1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * ti-adc161s626.c - Texas Instruments ADC161S626 1-channel differential ADC 4 * 5 * ADC Devices Supported: 6 * adc141s626 - 14-bit ADC 7 * adc161s626 - 16-bit ADC 8 * 9 * Copyright (C) 2016-2018 10 * Author: Matt Ranostay <matt.ranostay@konsulko.com> 11 */ 12 13 #include <linux/module.h> 14 #include <linux/mod_devicetable.h> 15 #include <linux/init.h> 16 #include <linux/err.h> 17 #include <linux/spi/spi.h> 18 #include <linux/iio/iio.h> 19 #include <linux/iio/trigger.h> 20 #include <linux/iio/buffer.h> 21 #include <linux/iio/trigger_consumer.h> 22 #include <linux/iio/triggered_buffer.h> 23 #include <linux/regulator/consumer.h> 24 25 #define TI_ADC_DRV_NAME "ti-adc161s626" 26 27 enum { 28 TI_ADC141S626, 29 TI_ADC161S626, 30 }; 31 32 static const struct iio_chan_spec ti_adc141s626_channels[] = { 33 { 34 .type = IIO_VOLTAGE, 35 .channel = 0, 36 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 37 BIT(IIO_CHAN_INFO_SCALE) | 38 BIT(IIO_CHAN_INFO_OFFSET), 39 .scan_index = 0, 40 .scan_type = { 41 .sign = 's', 42 .realbits = 14, 43 .storagebits = 16, 44 }, 45 }, 46 IIO_CHAN_SOFT_TIMESTAMP(1), 47 }; 48 49 static const struct iio_chan_spec ti_adc161s626_channels[] = { 50 { 51 .type = IIO_VOLTAGE, 52 .channel = 0, 53 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 54 BIT(IIO_CHAN_INFO_SCALE) | 55 BIT(IIO_CHAN_INFO_OFFSET), 56 .scan_index = 0, 57 .scan_type = { 58 .sign = 's', 59 .realbits = 16, 60 .storagebits = 16, 61 }, 62 }, 63 IIO_CHAN_SOFT_TIMESTAMP(1), 64 }; 65 66 struct ti_adc_data { 67 struct iio_dev *indio_dev; 68 struct spi_device *spi; 69 struct regulator *ref; 70 71 u8 read_size; 72 u8 shift; 73 74 u8 buffer[16] ____cacheline_aligned; 75 }; 76 77 static int ti_adc_read_measurement(struct ti_adc_data *data, 78 struct iio_chan_spec const *chan, int *val) 79 { 80 int ret; 81 82 switch (data->read_size) { 83 case 2: { 84 __be16 buf; 85 86 ret = spi_read(data->spi, (void *) &buf, 2); 87 if (ret) 88 return ret; 89 90 *val = be16_to_cpu(buf); 91 break; 92 } 93 case 3: { 94 __be32 buf; 95 96 ret = spi_read(data->spi, (void *) &buf, 3); 97 if (ret) 98 return ret; 99 100 *val = be32_to_cpu(buf) >> 8; 101 break; 102 } 103 default: 104 return -EINVAL; 105 } 106 107 *val = sign_extend32(*val >> data->shift, chan->scan_type.realbits - 1); 108 109 return 0; 110 } 111 112 static irqreturn_t ti_adc_trigger_handler(int irq, void *private) 113 { 114 struct iio_poll_func *pf = private; 115 struct iio_dev *indio_dev = pf->indio_dev; 116 struct ti_adc_data *data = iio_priv(indio_dev); 117 int ret; 118 119 ret = ti_adc_read_measurement(data, &indio_dev->channels[0], 120 (int *) &data->buffer); 121 if (!ret) 122 iio_push_to_buffers_with_timestamp(indio_dev, 123 data->buffer, 124 iio_get_time_ns(indio_dev)); 125 126 iio_trigger_notify_done(indio_dev->trig); 127 128 return IRQ_HANDLED; 129 } 130 131 static int ti_adc_read_raw(struct iio_dev *indio_dev, 132 struct iio_chan_spec const *chan, 133 int *val, int *val2, long mask) 134 { 135 struct ti_adc_data *data = iio_priv(indio_dev); 136 int ret; 137 138 switch (mask) { 139 case IIO_CHAN_INFO_RAW: 140 ret = iio_device_claim_direct_mode(indio_dev); 141 if (ret) 142 return ret; 143 144 ret = ti_adc_read_measurement(data, chan, val); 145 iio_device_release_direct_mode(indio_dev); 146 147 if (ret) 148 return ret; 149 150 return IIO_VAL_INT; 151 case IIO_CHAN_INFO_SCALE: 152 ret = regulator_get_voltage(data->ref); 153 if (ret < 0) 154 return ret; 155 156 *val = ret / 1000; 157 *val2 = chan->scan_type.realbits; 158 159 return IIO_VAL_FRACTIONAL_LOG2; 160 case IIO_CHAN_INFO_OFFSET: 161 *val = 1 << (chan->scan_type.realbits - 1); 162 return IIO_VAL_INT; 163 } 164 165 return 0; 166 } 167 168 static const struct iio_info ti_adc_info = { 169 .read_raw = ti_adc_read_raw, 170 }; 171 172 static int ti_adc_probe(struct spi_device *spi) 173 { 174 struct iio_dev *indio_dev; 175 struct ti_adc_data *data; 176 int ret; 177 178 indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data)); 179 if (!indio_dev) 180 return -ENOMEM; 181 182 indio_dev->info = &ti_adc_info; 183 indio_dev->name = TI_ADC_DRV_NAME; 184 indio_dev->modes = INDIO_DIRECT_MODE; 185 spi_set_drvdata(spi, indio_dev); 186 187 data = iio_priv(indio_dev); 188 data->spi = spi; 189 190 switch (spi_get_device_id(spi)->driver_data) { 191 case TI_ADC141S626: 192 indio_dev->channels = ti_adc141s626_channels; 193 indio_dev->num_channels = ARRAY_SIZE(ti_adc141s626_channels); 194 data->shift = 0; 195 data->read_size = 2; 196 break; 197 case TI_ADC161S626: 198 indio_dev->channels = ti_adc161s626_channels; 199 indio_dev->num_channels = ARRAY_SIZE(ti_adc161s626_channels); 200 data->shift = 6; 201 data->read_size = 3; 202 break; 203 } 204 205 data->ref = devm_regulator_get(&spi->dev, "vdda"); 206 if (!IS_ERR(data->ref)) { 207 ret = regulator_enable(data->ref); 208 if (ret < 0) 209 return ret; 210 } 211 212 ret = iio_triggered_buffer_setup(indio_dev, NULL, 213 ti_adc_trigger_handler, NULL); 214 if (ret) 215 goto error_regulator_disable; 216 217 ret = iio_device_register(indio_dev); 218 if (ret) 219 goto error_unreg_buffer; 220 221 return 0; 222 223 error_unreg_buffer: 224 iio_triggered_buffer_cleanup(indio_dev); 225 226 error_regulator_disable: 227 regulator_disable(data->ref); 228 229 return ret; 230 } 231 232 static int ti_adc_remove(struct spi_device *spi) 233 { 234 struct iio_dev *indio_dev = spi_get_drvdata(spi); 235 struct ti_adc_data *data = iio_priv(indio_dev); 236 237 iio_device_unregister(indio_dev); 238 iio_triggered_buffer_cleanup(indio_dev); 239 regulator_disable(data->ref); 240 241 return 0; 242 } 243 244 static const struct of_device_id ti_adc_dt_ids[] = { 245 { .compatible = "ti,adc141s626", }, 246 { .compatible = "ti,adc161s626", }, 247 {} 248 }; 249 MODULE_DEVICE_TABLE(of, ti_adc_dt_ids); 250 251 static const struct spi_device_id ti_adc_id[] = { 252 {"adc141s626", TI_ADC141S626}, 253 {"adc161s626", TI_ADC161S626}, 254 {}, 255 }; 256 MODULE_DEVICE_TABLE(spi, ti_adc_id); 257 258 static struct spi_driver ti_adc_driver = { 259 .driver = { 260 .name = TI_ADC_DRV_NAME, 261 .of_match_table = ti_adc_dt_ids, 262 }, 263 .probe = ti_adc_probe, 264 .remove = ti_adc_remove, 265 .id_table = ti_adc_id, 266 }; 267 module_spi_driver(ti_adc_driver); 268 269 MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); 270 MODULE_DESCRIPTION("Texas Instruments ADC1x1S 1-channel differential ADC"); 271 MODULE_LICENSE("GPL"); 272