1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * ltc2497-core.c - Common code for Analog Devices/Linear Technology 4 * LTC2496 and LTC2497 ADCs 5 * 6 * Copyright (C) 2017 Analog Devices Inc. 7 */ 8 9 #include <linux/delay.h> 10 #include <linux/iio/iio.h> 11 #include <linux/iio/driver.h> 12 #include <linux/module.h> 13 #include <linux/regulator/consumer.h> 14 15 #include "ltc2497.h" 16 17 #define LTC2497_SGL BIT(4) 18 #define LTC2497_DIFF 0 19 #define LTC2497_SIGN BIT(3) 20 21 static int ltc2497core_wait_conv(struct ltc2497core_driverdata *ddata) 22 { 23 s64 time_elapsed; 24 25 time_elapsed = ktime_ms_delta(ktime_get(), ddata->time_prev); 26 27 if (time_elapsed < LTC2497_CONVERSION_TIME_MS) { 28 /* delay if conversion time not passed 29 * since last read or write 30 */ 31 if (msleep_interruptible( 32 LTC2497_CONVERSION_TIME_MS - time_elapsed)) 33 return -ERESTARTSYS; 34 35 return 0; 36 } 37 38 if (time_elapsed - LTC2497_CONVERSION_TIME_MS <= 0) { 39 /* We're in automatic mode - 40 * so the last reading is still not outdated 41 */ 42 return 0; 43 } 44 45 return 1; 46 } 47 48 static int ltc2497core_read(struct ltc2497core_driverdata *ddata, u8 address, int *val) 49 { 50 int ret; 51 52 ret = ltc2497core_wait_conv(ddata); 53 if (ret < 0) 54 return ret; 55 56 if (ret || ddata->addr_prev != address) { 57 ret = ddata->result_and_measure(ddata, address, NULL); 58 if (ret < 0) 59 return ret; 60 ddata->addr_prev = address; 61 62 if (msleep_interruptible(LTC2497_CONVERSION_TIME_MS)) 63 return -ERESTARTSYS; 64 } 65 66 ret = ddata->result_and_measure(ddata, address, val); 67 if (ret < 0) 68 return ret; 69 70 ddata->time_prev = ktime_get(); 71 72 return ret; 73 } 74 75 static int ltc2497core_read_raw(struct iio_dev *indio_dev, 76 struct iio_chan_spec const *chan, 77 int *val, int *val2, long mask) 78 { 79 struct ltc2497core_driverdata *ddata = iio_priv(indio_dev); 80 int ret; 81 82 switch (mask) { 83 case IIO_CHAN_INFO_RAW: 84 mutex_lock(&indio_dev->mlock); 85 ret = ltc2497core_read(ddata, chan->address, val); 86 mutex_unlock(&indio_dev->mlock); 87 if (ret < 0) 88 return ret; 89 90 return IIO_VAL_INT; 91 92 case IIO_CHAN_INFO_SCALE: 93 ret = regulator_get_voltage(ddata->ref); 94 if (ret < 0) 95 return ret; 96 97 *val = ret / 1000; 98 *val2 = 17; 99 100 return IIO_VAL_FRACTIONAL_LOG2; 101 102 default: 103 return -EINVAL; 104 } 105 } 106 107 #define LTC2497_CHAN(_chan, _addr, _ds_name) { \ 108 .type = IIO_VOLTAGE, \ 109 .indexed = 1, \ 110 .channel = (_chan), \ 111 .address = (_addr | (_chan / 2) | ((_chan & 1) ? LTC2497_SIGN : 0)), \ 112 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 113 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 114 .datasheet_name = (_ds_name), \ 115 } 116 117 #define LTC2497_CHAN_DIFF(_chan, _addr) { \ 118 .type = IIO_VOLTAGE, \ 119 .indexed = 1, \ 120 .channel = (_chan) * 2 + ((_addr) & LTC2497_SIGN ? 1 : 0), \ 121 .channel2 = (_chan) * 2 + ((_addr) & LTC2497_SIGN ? 0 : 1),\ 122 .address = (_addr | _chan), \ 123 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 124 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 125 .differential = 1, \ 126 } 127 128 static const struct iio_chan_spec ltc2497core_channel[] = { 129 LTC2497_CHAN(0, LTC2497_SGL, "CH0"), 130 LTC2497_CHAN(1, LTC2497_SGL, "CH1"), 131 LTC2497_CHAN(2, LTC2497_SGL, "CH2"), 132 LTC2497_CHAN(3, LTC2497_SGL, "CH3"), 133 LTC2497_CHAN(4, LTC2497_SGL, "CH4"), 134 LTC2497_CHAN(5, LTC2497_SGL, "CH5"), 135 LTC2497_CHAN(6, LTC2497_SGL, "CH6"), 136 LTC2497_CHAN(7, LTC2497_SGL, "CH7"), 137 LTC2497_CHAN(8, LTC2497_SGL, "CH8"), 138 LTC2497_CHAN(9, LTC2497_SGL, "CH9"), 139 LTC2497_CHAN(10, LTC2497_SGL, "CH10"), 140 LTC2497_CHAN(11, LTC2497_SGL, "CH11"), 141 LTC2497_CHAN(12, LTC2497_SGL, "CH12"), 142 LTC2497_CHAN(13, LTC2497_SGL, "CH13"), 143 LTC2497_CHAN(14, LTC2497_SGL, "CH14"), 144 LTC2497_CHAN(15, LTC2497_SGL, "CH15"), 145 LTC2497_CHAN_DIFF(0, LTC2497_DIFF), 146 LTC2497_CHAN_DIFF(1, LTC2497_DIFF), 147 LTC2497_CHAN_DIFF(2, LTC2497_DIFF), 148 LTC2497_CHAN_DIFF(3, LTC2497_DIFF), 149 LTC2497_CHAN_DIFF(4, LTC2497_DIFF), 150 LTC2497_CHAN_DIFF(5, LTC2497_DIFF), 151 LTC2497_CHAN_DIFF(6, LTC2497_DIFF), 152 LTC2497_CHAN_DIFF(7, LTC2497_DIFF), 153 LTC2497_CHAN_DIFF(0, LTC2497_DIFF | LTC2497_SIGN), 154 LTC2497_CHAN_DIFF(1, LTC2497_DIFF | LTC2497_SIGN), 155 LTC2497_CHAN_DIFF(2, LTC2497_DIFF | LTC2497_SIGN), 156 LTC2497_CHAN_DIFF(3, LTC2497_DIFF | LTC2497_SIGN), 157 LTC2497_CHAN_DIFF(4, LTC2497_DIFF | LTC2497_SIGN), 158 LTC2497_CHAN_DIFF(5, LTC2497_DIFF | LTC2497_SIGN), 159 LTC2497_CHAN_DIFF(6, LTC2497_DIFF | LTC2497_SIGN), 160 LTC2497_CHAN_DIFF(7, LTC2497_DIFF | LTC2497_SIGN), 161 }; 162 163 static const struct iio_info ltc2497core_info = { 164 .read_raw = ltc2497core_read_raw, 165 }; 166 167 int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev) 168 { 169 struct ltc2497core_driverdata *ddata = iio_priv(indio_dev); 170 int ret; 171 172 indio_dev->dev.parent = dev; 173 indio_dev->name = dev_name(dev); 174 indio_dev->info = <c2497core_info; 175 indio_dev->modes = INDIO_DIRECT_MODE; 176 indio_dev->channels = ltc2497core_channel; 177 indio_dev->num_channels = ARRAY_SIZE(ltc2497core_channel); 178 179 ret = ddata->result_and_measure(ddata, LTC2497_CONFIG_DEFAULT, NULL); 180 if (ret < 0) 181 return ret; 182 183 ddata->ref = devm_regulator_get(dev, "vref"); 184 if (IS_ERR(ddata->ref)) { 185 if (PTR_ERR(ddata->ref) != -EPROBE_DEFER) 186 dev_err(dev, "Failed to get vref regulator: %pe\n", 187 ddata->ref); 188 189 return PTR_ERR(ddata->ref); 190 } 191 192 ret = regulator_enable(ddata->ref); 193 if (ret < 0) { 194 dev_err(dev, "Failed to enable vref regulator: %pe\n", 195 ERR_PTR(ret)); 196 return ret; 197 } 198 199 if (dev->platform_data) { 200 struct iio_map *plat_data; 201 202 plat_data = (struct iio_map *)dev->platform_data; 203 204 ret = iio_map_array_register(indio_dev, plat_data); 205 if (ret) { 206 dev_err(&indio_dev->dev, "iio map err: %d\n", ret); 207 goto err_regulator_disable; 208 } 209 } 210 211 ddata->addr_prev = LTC2497_CONFIG_DEFAULT; 212 ddata->time_prev = ktime_get(); 213 214 ret = iio_device_register(indio_dev); 215 if (ret < 0) 216 goto err_array_unregister; 217 218 return 0; 219 220 err_array_unregister: 221 iio_map_array_unregister(indio_dev); 222 223 err_regulator_disable: 224 regulator_disable(ddata->ref); 225 226 return ret; 227 } 228 EXPORT_SYMBOL_NS(ltc2497core_probe, LTC2497); 229 230 void ltc2497core_remove(struct iio_dev *indio_dev) 231 { 232 struct ltc2497core_driverdata *ddata = iio_priv(indio_dev); 233 234 iio_device_unregister(indio_dev); 235 236 iio_map_array_unregister(indio_dev); 237 238 regulator_disable(ddata->ref); 239 } 240 EXPORT_SYMBOL_NS(ltc2497core_remove, LTC2497); 241 242 MODULE_DESCRIPTION("common code for LTC2496/LTC2497 drivers"); 243 MODULE_LICENSE("GPL v2"); 244