1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * MAX1117/MAX1118/MAX1119 8-bit, dual-channel ADCs driver |
4 | * |
5 | * Copyright (c) 2017 Akinobu Mita <akinobu.mita@gmail.com> |
6 | * |
7 | * Datasheet: https://datasheets.maximintegrated.com/en/ds/MAX1117-MAX1119.pdf |
8 | * |
9 | * SPI interface connections |
10 | * |
11 | * SPI MAXIM |
12 | * Master Direction MAX1117/8/9 |
13 | * ------ --------- ----------- |
14 | * nCS --> CNVST |
15 | * SCK --> SCLK |
16 | * MISO <-- DOUT |
17 | * ------ --------- ----------- |
18 | */ |
19 | |
20 | #include <linux/module.h> |
21 | #include <linux/mod_devicetable.h> |
22 | #include <linux/spi/spi.h> |
23 | #include <linux/iio/iio.h> |
24 | #include <linux/iio/buffer.h> |
25 | #include <linux/iio/triggered_buffer.h> |
26 | #include <linux/iio/trigger_consumer.h> |
27 | #include <linux/regulator/consumer.h> |
28 | |
29 | enum max1118_id { |
30 | max1117, |
31 | max1118, |
32 | max1119, |
33 | }; |
34 | |
35 | struct max1118 { |
36 | struct spi_device *spi; |
37 | struct mutex lock; |
38 | struct regulator *reg; |
39 | /* Ensure natural alignment of buffer elements */ |
40 | struct { |
41 | u8 channels[2]; |
42 | s64 ts __aligned(8); |
43 | } scan; |
44 | |
45 | u8 data __aligned(IIO_DMA_MINALIGN); |
46 | }; |
47 | |
48 | #define MAX1118_CHANNEL(ch) \ |
49 | { \ |
50 | .type = IIO_VOLTAGE, \ |
51 | .indexed = 1, \ |
52 | .channel = (ch), \ |
53 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
54 | .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ |
55 | .scan_index = ch, \ |
56 | .scan_type = { \ |
57 | .sign = 'u', \ |
58 | .realbits = 8, \ |
59 | .storagebits = 8, \ |
60 | }, \ |
61 | } |
62 | |
63 | static const struct iio_chan_spec max1118_channels[] = { |
64 | MAX1118_CHANNEL(0), |
65 | MAX1118_CHANNEL(1), |
66 | IIO_CHAN_SOFT_TIMESTAMP(2), |
67 | }; |
68 | |
69 | static int max1118_read(struct iio_dev *indio_dev, int channel) |
70 | { |
71 | struct max1118 *adc = iio_priv(indio_dev); |
72 | struct spi_transfer xfers[] = { |
73 | /* |
74 | * To select CH1 for conversion, CNVST pin must be brought high |
75 | * and low for a second time. |
76 | */ |
77 | { |
78 | .len = 0, |
79 | .delay = { /* > CNVST Low Time 100 ns */ |
80 | .value = 1, |
81 | .unit = SPI_DELAY_UNIT_USECS |
82 | }, |
83 | .cs_change = 1, |
84 | }, |
85 | /* |
86 | * The acquisition interval begins with the falling edge of |
87 | * CNVST. The total acquisition and conversion process takes |
88 | * <7.5us. |
89 | */ |
90 | { |
91 | .len = 0, |
92 | .delay = { |
93 | .value = 8, |
94 | .unit = SPI_DELAY_UNIT_USECS |
95 | }, |
96 | }, |
97 | { |
98 | .rx_buf = &adc->data, |
99 | .len = 1, |
100 | }, |
101 | }; |
102 | int ret; |
103 | |
104 | if (channel == 0) |
105 | ret = spi_sync_transfer(spi: adc->spi, xfers: xfers + 1, num_xfers: 2); |
106 | else |
107 | ret = spi_sync_transfer(spi: adc->spi, xfers, num_xfers: 3); |
108 | |
109 | if (ret) |
110 | return ret; |
111 | |
112 | return adc->data; |
113 | } |
114 | |
115 | static int max1118_get_vref_mV(struct iio_dev *indio_dev) |
116 | { |
117 | struct max1118 *adc = iio_priv(indio_dev); |
118 | const struct spi_device_id *id = spi_get_device_id(sdev: adc->spi); |
119 | int vref_uV; |
120 | |
121 | switch (id->driver_data) { |
122 | case max1117: |
123 | return 2048; |
124 | case max1119: |
125 | return 4096; |
126 | case max1118: |
127 | vref_uV = regulator_get_voltage(regulator: adc->reg); |
128 | if (vref_uV < 0) |
129 | return vref_uV; |
130 | return vref_uV / 1000; |
131 | } |
132 | |
133 | return -ENODEV; |
134 | } |
135 | |
136 | static int max1118_read_raw(struct iio_dev *indio_dev, |
137 | struct iio_chan_spec const *chan, |
138 | int *val, int *val2, long mask) |
139 | { |
140 | struct max1118 *adc = iio_priv(indio_dev); |
141 | |
142 | switch (mask) { |
143 | case IIO_CHAN_INFO_RAW: |
144 | mutex_lock(&adc->lock); |
145 | *val = max1118_read(indio_dev, channel: chan->channel); |
146 | mutex_unlock(lock: &adc->lock); |
147 | if (*val < 0) |
148 | return *val; |
149 | |
150 | return IIO_VAL_INT; |
151 | case IIO_CHAN_INFO_SCALE: |
152 | *val = max1118_get_vref_mV(indio_dev); |
153 | if (*val < 0) |
154 | return *val; |
155 | *val2 = 8; |
156 | |
157 | return IIO_VAL_FRACTIONAL_LOG2; |
158 | } |
159 | |
160 | return -EINVAL; |
161 | } |
162 | |
163 | static const struct iio_info max1118_info = { |
164 | .read_raw = max1118_read_raw, |
165 | }; |
166 | |
167 | static irqreturn_t max1118_trigger_handler(int irq, void *p) |
168 | { |
169 | struct iio_poll_func *pf = p; |
170 | struct iio_dev *indio_dev = pf->indio_dev; |
171 | struct max1118 *adc = iio_priv(indio_dev); |
172 | int scan_index; |
173 | int i = 0; |
174 | |
175 | mutex_lock(&adc->lock); |
176 | |
177 | for_each_set_bit(scan_index, indio_dev->active_scan_mask, |
178 | indio_dev->masklength) { |
179 | const struct iio_chan_spec *scan_chan = |
180 | &indio_dev->channels[scan_index]; |
181 | int ret = max1118_read(indio_dev, channel: scan_chan->channel); |
182 | |
183 | if (ret < 0) { |
184 | dev_warn(&adc->spi->dev, |
185 | "failed to get conversion data\n" ); |
186 | goto out; |
187 | } |
188 | |
189 | adc->scan.channels[i] = ret; |
190 | i++; |
191 | } |
192 | iio_push_to_buffers_with_timestamp(indio_dev, data: &adc->scan, |
193 | timestamp: iio_get_time_ns(indio_dev)); |
194 | out: |
195 | mutex_unlock(lock: &adc->lock); |
196 | |
197 | iio_trigger_notify_done(trig: indio_dev->trig); |
198 | |
199 | return IRQ_HANDLED; |
200 | } |
201 | |
202 | static void max1118_reg_disable(void *reg) |
203 | { |
204 | regulator_disable(regulator: reg); |
205 | } |
206 | |
207 | static int max1118_probe(struct spi_device *spi) |
208 | { |
209 | struct iio_dev *indio_dev; |
210 | struct max1118 *adc; |
211 | const struct spi_device_id *id = spi_get_device_id(sdev: spi); |
212 | int ret; |
213 | |
214 | indio_dev = devm_iio_device_alloc(parent: &spi->dev, sizeof_priv: sizeof(*adc)); |
215 | if (!indio_dev) |
216 | return -ENOMEM; |
217 | |
218 | adc = iio_priv(indio_dev); |
219 | adc->spi = spi; |
220 | mutex_init(&adc->lock); |
221 | |
222 | if (id->driver_data == max1118) { |
223 | adc->reg = devm_regulator_get(dev: &spi->dev, id: "vref" ); |
224 | if (IS_ERR(ptr: adc->reg)) |
225 | return dev_err_probe(dev: &spi->dev, err: PTR_ERR(ptr: adc->reg), |
226 | fmt: "failed to get vref regulator\n" ); |
227 | ret = regulator_enable(regulator: adc->reg); |
228 | if (ret) |
229 | return ret; |
230 | |
231 | ret = devm_add_action_or_reset(&spi->dev, max1118_reg_disable, |
232 | adc->reg); |
233 | if (ret) |
234 | return ret; |
235 | |
236 | } |
237 | |
238 | indio_dev->name = spi_get_device_id(sdev: spi)->name; |
239 | indio_dev->info = &max1118_info; |
240 | indio_dev->modes = INDIO_DIRECT_MODE; |
241 | indio_dev->channels = max1118_channels; |
242 | indio_dev->num_channels = ARRAY_SIZE(max1118_channels); |
243 | |
244 | /* |
245 | * To reinitiate a conversion on CH0, it is necessary to allow for a |
246 | * conversion to be complete and all of the data to be read out. Once |
247 | * a conversion has been completed, the MAX1117/MAX1118/MAX1119 will go |
248 | * into AutoShutdown mode until the next conversion is initiated. |
249 | */ |
250 | max1118_read(indio_dev, channel: 0); |
251 | |
252 | ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, NULL, |
253 | max1118_trigger_handler, NULL); |
254 | if (ret) |
255 | return ret; |
256 | |
257 | return devm_iio_device_register(&spi->dev, indio_dev); |
258 | } |
259 | |
260 | static const struct spi_device_id max1118_id[] = { |
261 | { "max1117" , max1117 }, |
262 | { "max1118" , max1118 }, |
263 | { "max1119" , max1119 }, |
264 | {} |
265 | }; |
266 | MODULE_DEVICE_TABLE(spi, max1118_id); |
267 | |
268 | static const struct of_device_id max1118_dt_ids[] = { |
269 | { .compatible = "maxim,max1117" }, |
270 | { .compatible = "maxim,max1118" }, |
271 | { .compatible = "maxim,max1119" }, |
272 | {}, |
273 | }; |
274 | MODULE_DEVICE_TABLE(of, max1118_dt_ids); |
275 | |
276 | static struct spi_driver max1118_spi_driver = { |
277 | .driver = { |
278 | .name = "max1118" , |
279 | .of_match_table = max1118_dt_ids, |
280 | }, |
281 | .probe = max1118_probe, |
282 | .id_table = max1118_id, |
283 | }; |
284 | module_spi_driver(max1118_spi_driver); |
285 | |
286 | MODULE_AUTHOR("Akinobu Mita <akinobu.mita@gmail.com>" ); |
287 | MODULE_DESCRIPTION("MAXIM MAX1117/MAX1118/MAX1119 ADCs driver" ); |
288 | MODULE_LICENSE("GPL v2" ); |
289 | |