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