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/unaligned.h>
19 #include <linux/iio/iio.h>
20 #include <linux/iio/trigger.h>
21 #include <linux/iio/buffer.h>
22 #include <linux/iio/trigger_consumer.h>
23 #include <linux/iio/triggered_buffer.h>
24 #include <linux/regulator/consumer.h>
25
26 #define TI_ADC_DRV_NAME "ti-adc161s626"
27
28 enum {
29 TI_ADC141S626,
30 TI_ADC161S626,
31 };
32
33 static const struct iio_chan_spec ti_adc141s626_channels[] = {
34 {
35 .type = IIO_VOLTAGE,
36 .channel = 0,
37 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
38 BIT(IIO_CHAN_INFO_SCALE) |
39 BIT(IIO_CHAN_INFO_OFFSET),
40 .scan_index = 0,
41 .scan_type = {
42 .sign = 's',
43 .realbits = 14,
44 .storagebits = 16,
45 },
46 },
47 IIO_CHAN_SOFT_TIMESTAMP(1),
48 };
49
50 static const struct iio_chan_spec ti_adc161s626_channels[] = {
51 {
52 .type = IIO_VOLTAGE,
53 .channel = 0,
54 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
55 BIT(IIO_CHAN_INFO_SCALE) |
56 BIT(IIO_CHAN_INFO_OFFSET),
57 .scan_index = 0,
58 .scan_type = {
59 .sign = 's',
60 .realbits = 16,
61 .storagebits = 16,
62 },
63 },
64 IIO_CHAN_SOFT_TIMESTAMP(1),
65 };
66
67 struct ti_adc_data {
68 struct iio_dev *indio_dev;
69 struct spi_device *spi;
70 struct regulator *ref;
71
72 u8 read_size;
73 u8 shift;
74 u8 buf[3] __aligned(IIO_DMA_MINALIGN);
75 };
76
ti_adc_read_measurement(struct ti_adc_data * data,struct iio_chan_spec const * chan,int * val)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 ret = spi_read(data->spi, data->buf, 2);
85 if (ret)
86 return ret;
87
88 *val = get_unaligned_be16(data->buf);
89 break;
90 case 3:
91 ret = spi_read(data->spi, data->buf, 3);
92 if (ret)
93 return ret;
94
95 *val = get_unaligned_be24(data->buf);
96 break;
97 default:
98 return -EINVAL;
99 }
100
101 *val = sign_extend32(*val >> data->shift, chan->scan_type.realbits - 1);
102
103 return 0;
104 }
105
ti_adc_trigger_handler(int irq,void * private)106 static irqreturn_t ti_adc_trigger_handler(int irq, void *private)
107 {
108 struct iio_poll_func *pf = private;
109 struct iio_dev *indio_dev = pf->indio_dev;
110 struct ti_adc_data *data = iio_priv(indio_dev);
111 struct {
112 s16 data;
113 aligned_s64 timestamp;
114 } scan = { };
115 int ret, val;
116
117 ret = ti_adc_read_measurement(data, &indio_dev->channels[0], &val);
118 if (ret)
119 goto exit_notify_done;
120
121 scan.data = val;
122 iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev));
123
124 exit_notify_done:
125 iio_trigger_notify_done(indio_dev->trig);
126
127 return IRQ_HANDLED;
128 }
129
ti_adc_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)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 if (!iio_device_claim_direct(indio_dev))
140 return -EBUSY;
141 ret = ti_adc_read_measurement(data, chan, val);
142 iio_device_release_direct(indio_dev);
143 if (ret)
144 return ret;
145 return IIO_VAL_INT;
146 case IIO_CHAN_INFO_SCALE:
147 ret = regulator_get_voltage(data->ref);
148 if (ret < 0)
149 return ret;
150
151 *val = ret / 1000;
152 *val2 = chan->scan_type.realbits;
153
154 return IIO_VAL_FRACTIONAL_LOG2;
155 case IIO_CHAN_INFO_OFFSET:
156 *val = 1 << (chan->scan_type.realbits - 1);
157 return IIO_VAL_INT;
158 }
159
160 return 0;
161 }
162
163 static const struct iio_info ti_adc_info = {
164 .read_raw = ti_adc_read_raw,
165 };
166
ti_adc_reg_disable(void * reg)167 static void ti_adc_reg_disable(void *reg)
168 {
169 regulator_disable(reg);
170 }
171
ti_adc_probe(struct spi_device * spi)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
186 data = iio_priv(indio_dev);
187 data->spi = spi;
188
189 switch (spi_get_device_id(spi)->driver_data) {
190 case TI_ADC141S626:
191 indio_dev->channels = ti_adc141s626_channels;
192 indio_dev->num_channels = ARRAY_SIZE(ti_adc141s626_channels);
193 data->shift = 0;
194 data->read_size = 2;
195 break;
196 case TI_ADC161S626:
197 indio_dev->channels = ti_adc161s626_channels;
198 indio_dev->num_channels = ARRAY_SIZE(ti_adc161s626_channels);
199 data->shift = 6;
200 data->read_size = 3;
201 break;
202 }
203
204 data->ref = devm_regulator_get(&spi->dev, "vdda");
205 if (IS_ERR(data->ref))
206 return PTR_ERR(data->ref);
207
208 ret = regulator_enable(data->ref);
209 if (ret < 0)
210 return ret;
211
212 ret = devm_add_action_or_reset(&spi->dev, ti_adc_reg_disable,
213 data->ref);
214 if (ret)
215 return ret;
216
217 ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL,
218 ti_adc_trigger_handler, NULL);
219 if (ret)
220 return ret;
221
222 return devm_iio_device_register(&spi->dev, indio_dev);
223 }
224
225 static const struct of_device_id ti_adc_dt_ids[] = {
226 { .compatible = "ti,adc141s626", },
227 { .compatible = "ti,adc161s626", },
228 { }
229 };
230 MODULE_DEVICE_TABLE(of, ti_adc_dt_ids);
231
232 static const struct spi_device_id ti_adc_id[] = {
233 { "adc141s626", TI_ADC141S626 },
234 { "adc161s626", TI_ADC161S626 },
235 { }
236 };
237 MODULE_DEVICE_TABLE(spi, ti_adc_id);
238
239 static struct spi_driver ti_adc_driver = {
240 .driver = {
241 .name = TI_ADC_DRV_NAME,
242 .of_match_table = ti_adc_dt_ids,
243 },
244 .probe = ti_adc_probe,
245 .id_table = ti_adc_id,
246 };
247 module_spi_driver(ti_adc_driver);
248
249 MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>");
250 MODULE_DESCRIPTION("Texas Instruments ADC1x1S 1-channel differential ADC");
251 MODULE_LICENSE("GPL");
252