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