xref: /linux/drivers/iio/adc/ad7091r-base.c (revision cdd30ebb1b9f36159d66f088b61aee264e649d7a)
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 
ad7091r_set_channel(struct ad7091r_state * st,unsigned int channel)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(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(st->map, AD7091R_REG_RESULT, &dummy);
56 }
57 
ad7091r_read_one(struct iio_dev * iio_dev,unsigned int channel,unsigned int * read_val)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(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(st->map, AD7091R_REG_RESULT, &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 
ad7091r_read_raw(struct iio_dev * iio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long m)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(iio_dev);
86 	unsigned int read_val;
87 	int ret;
88 
89 	guard(mutex)(&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, chan->channel, &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(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 
ad7091r_read_event_config(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir)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(st->map,
133 				  AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
134 				  &val);
135 		if (ret)
136 			return ret;
137 		return val != AD7091R_HIGH_LIMIT;
138 	case IIO_EV_DIR_FALLING:
139 		ret = regmap_read(st->map,
140 				  AD7091R_REG_CH_LOW_LIMIT(chan->channel),
141 				  &val);
142 		if (ret)
143 			return ret;
144 		return val != AD7091R_LOW_LIMIT;
145 	default:
146 		return -EINVAL;
147 	}
148 }
149 
ad7091r_write_event_config(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,bool state)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,
154 				      bool state)
155 {
156 	struct ad7091r_state *st = iio_priv(indio_dev);
157 
158 	if (state) {
159 		return regmap_set_bits(st->map, AD7091R_REG_CONF,
160 				       AD7091R_REG_CONF_ALERT_EN);
161 	} else {
162 		/*
163 		 * Set thresholds either to 0 or to 2^12 - 1 as appropriate to
164 		 * prevent alerts and thus disable event generation.
165 		 */
166 		switch (dir) {
167 		case IIO_EV_DIR_RISING:
168 			return regmap_write(st->map,
169 					    AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
170 					    AD7091R_HIGH_LIMIT);
171 		case IIO_EV_DIR_FALLING:
172 			return regmap_write(st->map,
173 					    AD7091R_REG_CH_LOW_LIMIT(chan->channel),
174 					    AD7091R_LOW_LIMIT);
175 		default:
176 			return -EINVAL;
177 		}
178 	}
179 }
180 
ad7091r_read_event_value(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int * val,int * val2)181 static int ad7091r_read_event_value(struct iio_dev *indio_dev,
182 				    const struct iio_chan_spec *chan,
183 				    enum iio_event_type type,
184 				    enum iio_event_direction dir,
185 				    enum iio_event_info info, int *val, int *val2)
186 {
187 	struct ad7091r_state *st = iio_priv(indio_dev);
188 	int ret;
189 
190 	switch (info) {
191 	case IIO_EV_INFO_VALUE:
192 		switch (dir) {
193 		case IIO_EV_DIR_RISING:
194 			ret = regmap_read(st->map,
195 					  AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
196 					  val);
197 			if (ret)
198 				return ret;
199 			return IIO_VAL_INT;
200 		case IIO_EV_DIR_FALLING:
201 			ret = regmap_read(st->map,
202 					  AD7091R_REG_CH_LOW_LIMIT(chan->channel),
203 					  val);
204 			if (ret)
205 				return ret;
206 			return IIO_VAL_INT;
207 		default:
208 			return -EINVAL;
209 		}
210 	case IIO_EV_INFO_HYSTERESIS:
211 		ret = regmap_read(st->map,
212 				  AD7091R_REG_CH_HYSTERESIS(chan->channel),
213 				  val);
214 		if (ret)
215 			return ret;
216 		return IIO_VAL_INT;
217 	default:
218 		return -EINVAL;
219 	}
220 }
221 
ad7091r_write_event_value(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int val,int val2)222 static int ad7091r_write_event_value(struct iio_dev *indio_dev,
223 				     const struct iio_chan_spec *chan,
224 				     enum iio_event_type type,
225 				     enum iio_event_direction dir,
226 				     enum iio_event_info info, int val, int val2)
227 {
228 	struct ad7091r_state *st = iio_priv(indio_dev);
229 
230 	switch (info) {
231 	case IIO_EV_INFO_VALUE:
232 		switch (dir) {
233 		case IIO_EV_DIR_RISING:
234 			return regmap_write(st->map,
235 					    AD7091R_REG_CH_HIGH_LIMIT(chan->channel),
236 					    val);
237 		case IIO_EV_DIR_FALLING:
238 			return regmap_write(st->map,
239 					    AD7091R_REG_CH_LOW_LIMIT(chan->channel),
240 					    val);
241 		default:
242 			return -EINVAL;
243 		}
244 	case IIO_EV_INFO_HYSTERESIS:
245 		return regmap_write(st->map,
246 				    AD7091R_REG_CH_HYSTERESIS(chan->channel),
247 				    val);
248 	default:
249 		return -EINVAL;
250 	}
251 }
252 
253 static const struct iio_info ad7091r_info = {
254 	.read_raw = ad7091r_read_raw,
255 	.read_event_config = &ad7091r_read_event_config,
256 	.write_event_config = &ad7091r_write_event_config,
257 	.read_event_value = &ad7091r_read_event_value,
258 	.write_event_value = &ad7091r_write_event_value,
259 };
260 
ad7091r_event_handler(int irq,void * private)261 static irqreturn_t ad7091r_event_handler(int irq, void *private)
262 {
263 	struct iio_dev *iio_dev = private;
264 	struct ad7091r_state *st = iio_priv(iio_dev);
265 	unsigned int i, read_val;
266 	int ret;
267 	s64 timestamp = iio_get_time_ns(iio_dev);
268 
269 	ret = regmap_read(st->map, AD7091R_REG_ALERT, &read_val);
270 	if (ret)
271 		return IRQ_HANDLED;
272 
273 	for (i = 0; i < st->chip_info->num_channels; i++) {
274 		if (read_val & BIT(i * 2))
275 			iio_push_event(iio_dev,
276 					IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i,
277 						IIO_EV_TYPE_THRESH,
278 						IIO_EV_DIR_RISING), timestamp);
279 		if (read_val & BIT(i * 2 + 1))
280 			iio_push_event(iio_dev,
281 					IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i,
282 						IIO_EV_TYPE_THRESH,
283 						IIO_EV_DIR_FALLING), timestamp);
284 	}
285 
286 	return IRQ_HANDLED;
287 }
288 
ad7091r_remove(void * data)289 static void ad7091r_remove(void *data)
290 {
291 	struct ad7091r_state *st = data;
292 
293 	regulator_disable(st->vref);
294 }
295 
ad7091r_probe(struct device * dev,const struct ad7091r_init_info * init_info,int irq)296 int ad7091r_probe(struct device *dev, const struct ad7091r_init_info *init_info,
297 		  int irq)
298 {
299 	struct iio_dev *iio_dev;
300 	struct ad7091r_state *st;
301 	int ret;
302 
303 	iio_dev = devm_iio_device_alloc(dev, sizeof(*st));
304 	if (!iio_dev)
305 		return -ENOMEM;
306 
307 	st = iio_priv(iio_dev);
308 	st->dev = dev;
309 	init_info->init_adc_regmap(st, init_info->regmap_config);
310 	if (IS_ERR(st->map))
311 		return dev_err_probe(st->dev, PTR_ERR(st->map),
312 				     "Error initializing regmap\n");
313 
314 	iio_dev->info = &ad7091r_info;
315 	iio_dev->modes = INDIO_DIRECT_MODE;
316 
317 	if (init_info->setup) {
318 		ret = init_info->setup(st);
319 		if (ret < 0)
320 			return ret;
321 	}
322 
323 	if (irq) {
324 		st->chip_info = init_info->info_irq;
325 		ret = regmap_update_bits(st->map, AD7091R_REG_CONF,
326 					 AD7091R_REG_CONF_ALERT_EN, BIT(4));
327 		if (ret)
328 			return ret;
329 
330 		ret = devm_request_threaded_irq(dev, irq, NULL,
331 						ad7091r_event_handler,
332 						IRQF_TRIGGER_FALLING |
333 						IRQF_ONESHOT,
334 						st->chip_info->name, iio_dev);
335 		if (ret)
336 			return ret;
337 	} else {
338 		st->chip_info = init_info->info_no_irq;
339 	}
340 
341 	iio_dev->name = st->chip_info->name;
342 	iio_dev->num_channels = st->chip_info->num_channels;
343 	iio_dev->channels = st->chip_info->channels;
344 
345 	st->vref = devm_regulator_get_optional(dev, "vref");
346 	if (IS_ERR(st->vref)) {
347 		if (PTR_ERR(st->vref) == -EPROBE_DEFER)
348 			return -EPROBE_DEFER;
349 
350 		st->vref = NULL;
351 		/* Enable internal vref */
352 		ret = regmap_set_bits(st->map, AD7091R_REG_CONF,
353 				      AD7091R_REG_CONF_INT_VREF);
354 		if (ret)
355 			return dev_err_probe(st->dev, ret,
356 					     "Error on enable internal reference\n");
357 	} else {
358 		ret = regulator_enable(st->vref);
359 		if (ret)
360 			return ret;
361 		ret = devm_add_action_or_reset(dev, ad7091r_remove, st);
362 		if (ret)
363 			return ret;
364 	}
365 
366 	/* Use command mode by default to convert only desired channels*/
367 	ret = st->chip_info->set_mode(st, AD7091R_MODE_COMMAND);
368 	if (ret)
369 		return ret;
370 
371 	return devm_iio_device_register(dev, iio_dev);
372 }
373 EXPORT_SYMBOL_NS_GPL(ad7091r_probe, "IIO_AD7091R");
374 
ad7091r_writeable_reg(struct device * dev,unsigned int reg)375 bool ad7091r_writeable_reg(struct device *dev, unsigned int reg)
376 {
377 	switch (reg) {
378 	case AD7091R_REG_RESULT:
379 	case AD7091R_REG_ALERT:
380 		return false;
381 	default:
382 		return true;
383 	}
384 }
385 EXPORT_SYMBOL_NS_GPL(ad7091r_writeable_reg, "IIO_AD7091R");
386 
ad7091r_volatile_reg(struct device * dev,unsigned int reg)387 bool ad7091r_volatile_reg(struct device *dev, unsigned int reg)
388 {
389 	switch (reg) {
390 	case AD7091R_REG_RESULT:
391 	case AD7091R_REG_ALERT:
392 		return true;
393 	default:
394 		return false;
395 	}
396 }
397 EXPORT_SYMBOL_NS_GPL(ad7091r_volatile_reg, "IIO_AD7091R");
398 
399 MODULE_AUTHOR("Beniamin Bia <beniamin.bia@analog.com>");
400 MODULE_DESCRIPTION("Analog Devices AD7091Rx multi-channel converters");
401 MODULE_LICENSE("GPL v2");
402