1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * AD7091RX Analog to Digital converter driver |
4 | * |
5 | * Copyright 2014-2019 Analog Devices Inc. |
6 | */ |
7 | |
8 | #include <linux/bitops.h> |
9 | #include <linux/bitfield.h> |
10 | #include <linux/iio/events.h> |
11 | #include <linux/iio/iio.h> |
12 | #include <linux/interrupt.h> |
13 | #include <linux/module.h> |
14 | #include <linux/regmap.h> |
15 | #include <linux/regulator/consumer.h> |
16 | |
17 | #include "ad7091r-base.h" |
18 | |
19 | const struct iio_event_spec ad7091r_events[] = { |
20 | { |
21 | .type = IIO_EV_TYPE_THRESH, |
22 | .dir = IIO_EV_DIR_RISING, |
23 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | |
24 | BIT(IIO_EV_INFO_ENABLE), |
25 | }, |
26 | { |
27 | .type = IIO_EV_TYPE_THRESH, |
28 | .dir = IIO_EV_DIR_FALLING, |
29 | .mask_separate = BIT(IIO_EV_INFO_VALUE) | |
30 | BIT(IIO_EV_INFO_ENABLE), |
31 | }, |
32 | { |
33 | .type = IIO_EV_TYPE_THRESH, |
34 | .dir = IIO_EV_DIR_EITHER, |
35 | .mask_separate = BIT(IIO_EV_INFO_HYSTERESIS), |
36 | }, |
37 | }; |
38 | EXPORT_SYMBOL_NS_GPL(ad7091r_events, IIO_AD7091R); |
39 | |
40 | static int ad7091r_set_channel(struct ad7091r_state *st, unsigned int channel) |
41 | { |
42 | unsigned int dummy; |
43 | int ret; |
44 | |
45 | /* AD7091R_REG_CHANNEL specified which channels to be converted */ |
46 | ret = regmap_write(map: st->map, AD7091R_REG_CHANNEL, |
47 | BIT(channel) | (BIT(channel) << 8)); |
48 | if (ret) |
49 | return ret; |
50 | |
51 | /* |
52 | * There is a latency of one conversion before the channel conversion |
53 | * sequence is updated |
54 | */ |
55 | return regmap_read(map: st->map, AD7091R_REG_RESULT, val: &dummy); |
56 | } |
57 | |
58 | static int ad7091r_read_one(struct iio_dev *iio_dev, |
59 | unsigned int channel, unsigned int *read_val) |
60 | { |
61 | struct ad7091r_state *st = iio_priv(indio_dev: iio_dev); |
62 | unsigned int val; |
63 | int ret; |
64 | |
65 | ret = ad7091r_set_channel(st, channel); |
66 | if (ret) |
67 | return ret; |
68 | |
69 | ret = regmap_read(map: st->map, AD7091R_REG_RESULT, val: &val); |
70 | if (ret) |
71 | return ret; |
72 | |
73 | if (st->chip_info->reg_result_chan_id(val) != channel) |
74 | return -EIO; |
75 | |
76 | *read_val = AD7091R_REG_RESULT_CONV_RESULT(val); |
77 | |
78 | return 0; |
79 | } |
80 | |
81 | static int ad7091r_read_raw(struct iio_dev *iio_dev, |
82 | struct iio_chan_spec const *chan, |
83 | int *val, int *val2, long m) |
84 | { |
85 | struct ad7091r_state *st = iio_priv(indio_dev: iio_dev); |
86 | unsigned int read_val; |
87 | int ret; |
88 | |
89 | guard(mutex)(T: &st->lock); |
90 | |
91 | switch (m) { |
92 | case IIO_CHAN_INFO_RAW: |
93 | if (st->mode != AD7091R_MODE_COMMAND) |
94 | return -EBUSY; |
95 | |
96 | ret = ad7091r_read_one(iio_dev, channel: chan->channel, read_val: &read_val); |
97 | if (ret) |
98 | return ret; |
99 | |
100 | *val = read_val; |
101 | return IIO_VAL_INT; |
102 | |
103 | case IIO_CHAN_INFO_SCALE: |
104 | if (st->vref) { |
105 | ret = regulator_get_voltage(regulator: st->vref); |
106 | if (ret < 0) |
107 | return ret; |
108 | |
109 | *val = ret / 1000; |
110 | } else { |
111 | *val = st->chip_info->vref_mV; |
112 | } |
113 | |
114 | *val2 = chan->scan_type.realbits; |
115 | return IIO_VAL_FRACTIONAL_LOG2; |
116 | |
117 | default: |
118 | return -EINVAL; |
119 | } |
120 | } |
121 | |
122 | static int ad7091r_read_event_config(struct iio_dev *indio_dev, |
123 | const struct iio_chan_spec *chan, |
124 | enum iio_event_type type, |
125 | enum iio_event_direction dir) |
126 | { |
127 | struct ad7091r_state *st = iio_priv(indio_dev); |
128 | int val, ret; |
129 | |
130 | switch (dir) { |
131 | case IIO_EV_DIR_RISING: |
132 | ret = regmap_read(map: st->map, |
133 | AD7091R_REG_CH_HIGH_LIMIT(chan->channel), |
134 | val: &val); |
135 | if (ret) |
136 | return ret; |
137 | return val != AD7091R_HIGH_LIMIT; |
138 | case IIO_EV_DIR_FALLING: |
139 | ret = regmap_read(map: st->map, |
140 | AD7091R_REG_CH_LOW_LIMIT(chan->channel), |
141 | val: &val); |
142 | if (ret) |
143 | return ret; |
144 | return val != AD7091R_LOW_LIMIT; |
145 | default: |
146 | return -EINVAL; |
147 | } |
148 | } |
149 | |
150 | static int ad7091r_write_event_config(struct iio_dev *indio_dev, |
151 | const struct iio_chan_spec *chan, |
152 | enum iio_event_type type, |
153 | enum iio_event_direction dir, int state) |
154 | { |
155 | struct ad7091r_state *st = iio_priv(indio_dev); |
156 | |
157 | if (state) { |
158 | return regmap_set_bits(map: st->map, AD7091R_REG_CONF, |
159 | AD7091R_REG_CONF_ALERT_EN); |
160 | } else { |
161 | /* |
162 | * Set thresholds either to 0 or to 2^12 - 1 as appropriate to |
163 | * prevent alerts and thus disable event generation. |
164 | */ |
165 | switch (dir) { |
166 | case IIO_EV_DIR_RISING: |
167 | return regmap_write(map: st->map, |
168 | AD7091R_REG_CH_HIGH_LIMIT(chan->channel), |
169 | AD7091R_HIGH_LIMIT); |
170 | case IIO_EV_DIR_FALLING: |
171 | return regmap_write(map: st->map, |
172 | AD7091R_REG_CH_LOW_LIMIT(chan->channel), |
173 | AD7091R_LOW_LIMIT); |
174 | default: |
175 | return -EINVAL; |
176 | } |
177 | } |
178 | } |
179 | |
180 | static int ad7091r_read_event_value(struct iio_dev *indio_dev, |
181 | const struct iio_chan_spec *chan, |
182 | enum iio_event_type type, |
183 | enum iio_event_direction dir, |
184 | enum iio_event_info info, int *val, int *val2) |
185 | { |
186 | struct ad7091r_state *st = iio_priv(indio_dev); |
187 | int ret; |
188 | |
189 | switch (info) { |
190 | case IIO_EV_INFO_VALUE: |
191 | switch (dir) { |
192 | case IIO_EV_DIR_RISING: |
193 | ret = regmap_read(map: st->map, |
194 | AD7091R_REG_CH_HIGH_LIMIT(chan->channel), |
195 | val); |
196 | if (ret) |
197 | return ret; |
198 | return IIO_VAL_INT; |
199 | case IIO_EV_DIR_FALLING: |
200 | ret = regmap_read(map: st->map, |
201 | AD7091R_REG_CH_LOW_LIMIT(chan->channel), |
202 | val); |
203 | if (ret) |
204 | return ret; |
205 | return IIO_VAL_INT; |
206 | default: |
207 | return -EINVAL; |
208 | } |
209 | case IIO_EV_INFO_HYSTERESIS: |
210 | ret = regmap_read(map: st->map, |
211 | AD7091R_REG_CH_HYSTERESIS(chan->channel), |
212 | val); |
213 | if (ret) |
214 | return ret; |
215 | return IIO_VAL_INT; |
216 | default: |
217 | return -EINVAL; |
218 | } |
219 | } |
220 | |
221 | static int ad7091r_write_event_value(struct iio_dev *indio_dev, |
222 | const struct iio_chan_spec *chan, |
223 | enum iio_event_type type, |
224 | enum iio_event_direction dir, |
225 | enum iio_event_info info, int val, int val2) |
226 | { |
227 | struct ad7091r_state *st = iio_priv(indio_dev); |
228 | |
229 | switch (info) { |
230 | case IIO_EV_INFO_VALUE: |
231 | switch (dir) { |
232 | case IIO_EV_DIR_RISING: |
233 | return regmap_write(map: st->map, |
234 | AD7091R_REG_CH_HIGH_LIMIT(chan->channel), |
235 | val); |
236 | case IIO_EV_DIR_FALLING: |
237 | return regmap_write(map: st->map, |
238 | AD7091R_REG_CH_LOW_LIMIT(chan->channel), |
239 | val); |
240 | default: |
241 | return -EINVAL; |
242 | } |
243 | case IIO_EV_INFO_HYSTERESIS: |
244 | return regmap_write(map: st->map, |
245 | AD7091R_REG_CH_HYSTERESIS(chan->channel), |
246 | val); |
247 | default: |
248 | return -EINVAL; |
249 | } |
250 | } |
251 | |
252 | static const struct iio_info ad7091r_info = { |
253 | .read_raw = ad7091r_read_raw, |
254 | .read_event_config = &ad7091r_read_event_config, |
255 | .write_event_config = &ad7091r_write_event_config, |
256 | .read_event_value = &ad7091r_read_event_value, |
257 | .write_event_value = &ad7091r_write_event_value, |
258 | }; |
259 | |
260 | static irqreturn_t ad7091r_event_handler(int irq, void *private) |
261 | { |
262 | struct iio_dev *iio_dev = private; |
263 | struct ad7091r_state *st = iio_priv(indio_dev: iio_dev); |
264 | unsigned int i, read_val; |
265 | int ret; |
266 | s64 timestamp = iio_get_time_ns(indio_dev: iio_dev); |
267 | |
268 | ret = regmap_read(map: st->map, AD7091R_REG_ALERT, val: &read_val); |
269 | if (ret) |
270 | return IRQ_HANDLED; |
271 | |
272 | for (i = 0; i < st->chip_info->num_channels; i++) { |
273 | if (read_val & BIT(i * 2)) |
274 | iio_push_event(indio_dev: iio_dev, |
275 | IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i, |
276 | IIO_EV_TYPE_THRESH, |
277 | IIO_EV_DIR_RISING), timestamp); |
278 | if (read_val & BIT(i * 2 + 1)) |
279 | iio_push_event(indio_dev: iio_dev, |
280 | IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i, |
281 | IIO_EV_TYPE_THRESH, |
282 | IIO_EV_DIR_FALLING), timestamp); |
283 | } |
284 | |
285 | return IRQ_HANDLED; |
286 | } |
287 | |
288 | static void ad7091r_remove(void *data) |
289 | { |
290 | struct ad7091r_state *st = data; |
291 | |
292 | regulator_disable(regulator: st->vref); |
293 | } |
294 | |
295 | int ad7091r_probe(struct device *dev, const struct ad7091r_init_info *init_info, |
296 | int irq) |
297 | { |
298 | struct iio_dev *iio_dev; |
299 | struct ad7091r_state *st; |
300 | int ret; |
301 | |
302 | iio_dev = devm_iio_device_alloc(parent: dev, sizeof_priv: sizeof(*st)); |
303 | if (!iio_dev) |
304 | return -ENOMEM; |
305 | |
306 | st = iio_priv(indio_dev: iio_dev); |
307 | st->dev = dev; |
308 | init_info->init_adc_regmap(st, init_info->regmap_config); |
309 | if (IS_ERR(ptr: st->map)) |
310 | return dev_err_probe(dev: st->dev, err: PTR_ERR(ptr: st->map), |
311 | fmt: "Error initializing regmap\n" ); |
312 | |
313 | iio_dev->info = &ad7091r_info; |
314 | iio_dev->modes = INDIO_DIRECT_MODE; |
315 | |
316 | if (init_info->setup) { |
317 | ret = init_info->setup(st); |
318 | if (ret < 0) |
319 | return ret; |
320 | } |
321 | |
322 | if (irq) { |
323 | st->chip_info = init_info->info_irq; |
324 | ret = regmap_update_bits(map: st->map, AD7091R_REG_CONF, |
325 | AD7091R_REG_CONF_ALERT_EN, BIT(4)); |
326 | if (ret) |
327 | return ret; |
328 | |
329 | ret = devm_request_threaded_irq(dev, irq, NULL, |
330 | thread_fn: ad7091r_event_handler, |
331 | IRQF_TRIGGER_FALLING | |
332 | IRQF_ONESHOT, |
333 | devname: st->chip_info->name, dev_id: iio_dev); |
334 | if (ret) |
335 | return ret; |
336 | } else { |
337 | st->chip_info = init_info->info_no_irq; |
338 | } |
339 | |
340 | iio_dev->name = st->chip_info->name; |
341 | iio_dev->num_channels = st->chip_info->num_channels; |
342 | iio_dev->channels = st->chip_info->channels; |
343 | |
344 | st->vref = devm_regulator_get_optional(dev, id: "vref" ); |
345 | if (IS_ERR(ptr: st->vref)) { |
346 | if (PTR_ERR(ptr: st->vref) == -EPROBE_DEFER) |
347 | return -EPROBE_DEFER; |
348 | |
349 | st->vref = NULL; |
350 | /* Enable internal vref */ |
351 | ret = regmap_set_bits(map: st->map, AD7091R_REG_CONF, |
352 | AD7091R_REG_CONF_INT_VREF); |
353 | if (ret) |
354 | return dev_err_probe(dev: st->dev, err: ret, |
355 | fmt: "Error on enable internal reference\n" ); |
356 | } else { |
357 | ret = regulator_enable(regulator: st->vref); |
358 | if (ret) |
359 | return ret; |
360 | ret = devm_add_action_or_reset(dev, ad7091r_remove, st); |
361 | if (ret) |
362 | return ret; |
363 | } |
364 | |
365 | /* Use command mode by default to convert only desired channels*/ |
366 | ret = st->chip_info->set_mode(st, AD7091R_MODE_COMMAND); |
367 | if (ret) |
368 | return ret; |
369 | |
370 | return devm_iio_device_register(dev, iio_dev); |
371 | } |
372 | EXPORT_SYMBOL_NS_GPL(ad7091r_probe, IIO_AD7091R); |
373 | |
374 | bool ad7091r_writeable_reg(struct device *dev, unsigned int reg) |
375 | { |
376 | switch (reg) { |
377 | case AD7091R_REG_RESULT: |
378 | case AD7091R_REG_ALERT: |
379 | return false; |
380 | default: |
381 | return true; |
382 | } |
383 | } |
384 | EXPORT_SYMBOL_NS_GPL(ad7091r_writeable_reg, IIO_AD7091R); |
385 | |
386 | bool ad7091r_volatile_reg(struct device *dev, unsigned int reg) |
387 | { |
388 | switch (reg) { |
389 | case AD7091R_REG_RESULT: |
390 | case AD7091R_REG_ALERT: |
391 | return true; |
392 | default: |
393 | return false; |
394 | } |
395 | } |
396 | EXPORT_SYMBOL_NS_GPL(ad7091r_volatile_reg, IIO_AD7091R); |
397 | |
398 | MODULE_AUTHOR("Beniamin Bia <beniamin.bia@analog.com>" ); |
399 | MODULE_DESCRIPTION("Analog Devices AD7091Rx multi-channel converters" ); |
400 | MODULE_LICENSE("GPL v2" ); |
401 | |