xref: /linux/drivers/iio/adc/hi8435.c (revision 9a379e77033f02c4a071891afdf0f0a01eff8ccb)
1 /*
2  * Holt Integrated Circuits HI-8435 threshold detector driver
3  *
4  * Copyright (C) 2015 Zodiac Inflight Innovations
5  * Copyright (C) 2015 Cogent Embedded, Inc.
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  */
12 
13 #include <linux/delay.h>
14 #include <linux/iio/events.h>
15 #include <linux/iio/iio.h>
16 #include <linux/iio/sysfs.h>
17 #include <linux/iio/trigger.h>
18 #include <linux/iio/trigger_consumer.h>
19 #include <linux/iio/triggered_event.h>
20 #include <linux/interrupt.h>
21 #include <linux/module.h>
22 #include <linux/of.h>
23 #include <linux/of_device.h>
24 #include <linux/of_gpio.h>
25 #include <linux/spi/spi.h>
26 #include <linux/gpio/consumer.h>
27 
28 #define DRV_NAME "hi8435"
29 
30 /* Register offsets for HI-8435 */
31 #define HI8435_CTRL_REG		0x02
32 #define HI8435_PSEN_REG		0x04
33 #define HI8435_TMDATA_REG	0x1E
34 #define HI8435_GOCENHYS_REG	0x3A
35 #define HI8435_SOCENHYS_REG	0x3C
36 #define HI8435_SO7_0_REG	0x10
37 #define HI8435_SO15_8_REG	0x12
38 #define HI8435_SO23_16_REG	0x14
39 #define HI8435_SO31_24_REG	0x16
40 #define HI8435_SO31_0_REG	0x78
41 
42 #define HI8435_WRITE_OPCODE	0x00
43 #define HI8435_READ_OPCODE	0x80
44 
45 /* CTRL register bits */
46 #define HI8435_CTRL_TEST	0x01
47 #define HI8435_CTRL_SRST	0x02
48 
49 struct hi8435_priv {
50 	struct spi_device *spi;
51 	struct mutex lock;
52 
53 	unsigned long event_scan_mask; /* soft mask/unmask channels events */
54 	unsigned int event_prev_val;
55 
56 	unsigned threshold_lo[2]; /* GND-Open and Supply-Open thresholds */
57 	unsigned threshold_hi[2]; /* GND-Open and Supply-Open thresholds */
58 	u8 reg_buffer[3] ____cacheline_aligned;
59 };
60 
61 static int hi8435_readb(struct hi8435_priv *priv, u8 reg, u8 *val)
62 {
63 	reg |= HI8435_READ_OPCODE;
64 	return spi_write_then_read(priv->spi, &reg, 1, val, 1);
65 }
66 
67 static int hi8435_readw(struct hi8435_priv *priv, u8 reg, u16 *val)
68 {
69 	int ret;
70 	__be16 be_val;
71 
72 	reg |= HI8435_READ_OPCODE;
73 	ret = spi_write_then_read(priv->spi, &reg, 1, &be_val, 2);
74 	*val = be16_to_cpu(be_val);
75 
76 	return ret;
77 }
78 
79 static int hi8435_readl(struct hi8435_priv *priv, u8 reg, u32 *val)
80 {
81 	int ret;
82 	__be32 be_val;
83 
84 	reg |= HI8435_READ_OPCODE;
85 	ret = spi_write_then_read(priv->spi, &reg, 1, &be_val, 4);
86 	*val = be32_to_cpu(be_val);
87 
88 	return ret;
89 }
90 
91 static int hi8435_writeb(struct hi8435_priv *priv, u8 reg, u8 val)
92 {
93 	priv->reg_buffer[0] = reg | HI8435_WRITE_OPCODE;
94 	priv->reg_buffer[1] = val;
95 
96 	return spi_write(priv->spi, priv->reg_buffer, 2);
97 }
98 
99 static int hi8435_writew(struct hi8435_priv *priv, u8 reg, u16 val)
100 {
101 	priv->reg_buffer[0] = reg | HI8435_WRITE_OPCODE;
102 	priv->reg_buffer[1] = (val >> 8) & 0xff;
103 	priv->reg_buffer[2] = val & 0xff;
104 
105 	return spi_write(priv->spi, priv->reg_buffer, 3);
106 }
107 
108 static int hi8435_read_raw(struct iio_dev *idev,
109 			   const struct iio_chan_spec *chan,
110 			   int *val, int *val2, long mask)
111 {
112 	struct hi8435_priv *priv = iio_priv(idev);
113 	u32 tmp;
114 	int ret;
115 
116 	switch (mask) {
117 	case IIO_CHAN_INFO_RAW:
118 		ret = hi8435_readl(priv, HI8435_SO31_0_REG, &tmp);
119 		if (ret < 0)
120 			return ret;
121 		*val = !!(tmp & BIT(chan->channel));
122 		return IIO_VAL_INT;
123 	default:
124 		return -EINVAL;
125 	}
126 }
127 
128 static int hi8435_read_event_config(struct iio_dev *idev,
129 				    const struct iio_chan_spec *chan,
130 				    enum iio_event_type type,
131 				    enum iio_event_direction dir)
132 {
133 	struct hi8435_priv *priv = iio_priv(idev);
134 
135 	return !!(priv->event_scan_mask & BIT(chan->channel));
136 }
137 
138 static int hi8435_write_event_config(struct iio_dev *idev,
139 				     const struct iio_chan_spec *chan,
140 				     enum iio_event_type type,
141 				     enum iio_event_direction dir, int state)
142 {
143 	struct hi8435_priv *priv = iio_priv(idev);
144 	int ret;
145 	u32 tmp;
146 
147 	if (state) {
148 		ret = hi8435_readl(priv, HI8435_SO31_0_REG, &tmp);
149 		if (ret < 0)
150 			return ret;
151 		if (tmp & BIT(chan->channel))
152 			priv->event_prev_val |= BIT(chan->channel);
153 		else
154 			priv->event_prev_val &= ~BIT(chan->channel);
155 
156 		priv->event_scan_mask |= BIT(chan->channel);
157 	} else
158 		priv->event_scan_mask &= ~BIT(chan->channel);
159 
160 	return 0;
161 }
162 
163 static int hi8435_read_event_value(struct iio_dev *idev,
164 				   const struct iio_chan_spec *chan,
165 				   enum iio_event_type type,
166 				   enum iio_event_direction dir,
167 				   enum iio_event_info info,
168 				   int *val, int *val2)
169 {
170 	struct hi8435_priv *priv = iio_priv(idev);
171 	int ret;
172 	u8 mode, psen;
173 	u16 reg;
174 
175 	ret = hi8435_readb(priv, HI8435_PSEN_REG, &psen);
176 	if (ret < 0)
177 		return ret;
178 
179 	/* Supply-Open or GND-Open sensing mode */
180 	mode = !!(psen & BIT(chan->channel / 8));
181 
182 	ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG :
183 				 HI8435_GOCENHYS_REG, &reg);
184 	if (ret < 0)
185 		return ret;
186 
187 	if (dir == IIO_EV_DIR_FALLING)
188 		*val = ((reg & 0xff) - (reg >> 8)) / 2;
189 	else if (dir == IIO_EV_DIR_RISING)
190 		*val = ((reg & 0xff) + (reg >> 8)) / 2;
191 
192 	return IIO_VAL_INT;
193 }
194 
195 static int hi8435_write_event_value(struct iio_dev *idev,
196 				    const struct iio_chan_spec *chan,
197 				    enum iio_event_type type,
198 				    enum iio_event_direction dir,
199 				    enum iio_event_info info,
200 				    int val, int val2)
201 {
202 	struct hi8435_priv *priv = iio_priv(idev);
203 	int ret;
204 	u8 mode, psen;
205 	u16 reg;
206 
207 	ret = hi8435_readb(priv, HI8435_PSEN_REG, &psen);
208 	if (ret < 0)
209 		return ret;
210 
211 	/* Supply-Open or GND-Open sensing mode */
212 	mode = !!(psen & BIT(chan->channel / 8));
213 
214 	ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG :
215 				 HI8435_GOCENHYS_REG, &reg);
216 	if (ret < 0)
217 		return ret;
218 
219 	if (dir == IIO_EV_DIR_FALLING) {
220 		/* falling threshold range 2..21V, hysteresis minimum 2V */
221 		if (val < 2 || val > 21 || (val + 2) > priv->threshold_hi[mode])
222 			return -EINVAL;
223 
224 		if (val == priv->threshold_lo[mode])
225 			return 0;
226 
227 		priv->threshold_lo[mode] = val;
228 
229 		/* hysteresis must not be odd */
230 		if ((priv->threshold_hi[mode] - priv->threshold_lo[mode]) % 2)
231 			priv->threshold_hi[mode]--;
232 	} else if (dir == IIO_EV_DIR_RISING) {
233 		/* rising threshold range 3..22V, hysteresis minimum 2V */
234 		if (val < 3 || val > 22 || val < (priv->threshold_lo[mode] + 2))
235 			return -EINVAL;
236 
237 		if (val == priv->threshold_hi[mode])
238 			return 0;
239 
240 		priv->threshold_hi[mode] = val;
241 
242 		/* hysteresis must not be odd */
243 		if ((priv->threshold_hi[mode] - priv->threshold_lo[mode]) % 2)
244 			priv->threshold_lo[mode]++;
245 	}
246 
247 	/* program thresholds */
248 	mutex_lock(&priv->lock);
249 
250 	ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG :
251 				 HI8435_GOCENHYS_REG, &reg);
252 	if (ret < 0) {
253 		mutex_unlock(&priv->lock);
254 		return ret;
255 	}
256 
257 	/* hysteresis */
258 	reg = priv->threshold_hi[mode] - priv->threshold_lo[mode];
259 	reg <<= 8;
260 	/* threshold center */
261 	reg |= (priv->threshold_hi[mode] + priv->threshold_lo[mode]);
262 
263 	ret = hi8435_writew(priv, mode ? HI8435_SOCENHYS_REG :
264 				  HI8435_GOCENHYS_REG, reg);
265 
266 	mutex_unlock(&priv->lock);
267 
268 	return ret;
269 }
270 
271 static int hi8435_debugfs_reg_access(struct iio_dev *idev,
272 				     unsigned reg, unsigned writeval,
273 				     unsigned *readval)
274 {
275 	struct hi8435_priv *priv = iio_priv(idev);
276 	int ret;
277 	u8 val;
278 
279 	if (readval != NULL) {
280 		ret = hi8435_readb(priv, reg, &val);
281 		*readval = val;
282 	} else {
283 		val = (u8)writeval;
284 		ret = hi8435_writeb(priv, reg, val);
285 	}
286 
287 	return ret;
288 }
289 
290 static const struct iio_event_spec hi8435_events[] = {
291 	{
292 		.type = IIO_EV_TYPE_THRESH,
293 		.dir = IIO_EV_DIR_RISING,
294 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
295 	}, {
296 		.type = IIO_EV_TYPE_THRESH,
297 		.dir = IIO_EV_DIR_FALLING,
298 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
299 	}, {
300 		.type = IIO_EV_TYPE_THRESH,
301 		.dir = IIO_EV_DIR_EITHER,
302 		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
303 	},
304 };
305 
306 static int hi8435_get_sensing_mode(struct iio_dev *idev,
307 				   const struct iio_chan_spec *chan)
308 {
309 	struct hi8435_priv *priv = iio_priv(idev);
310 	int ret;
311 	u8 reg;
312 
313 	ret = hi8435_readb(priv, HI8435_PSEN_REG, &reg);
314 	if (ret < 0)
315 		return ret;
316 
317 	return !!(reg & BIT(chan->channel / 8));
318 }
319 
320 static int hi8435_set_sensing_mode(struct iio_dev *idev,
321 				   const struct iio_chan_spec *chan,
322 				   unsigned int mode)
323 {
324 	struct hi8435_priv *priv = iio_priv(idev);
325 	int ret;
326 	u8 reg;
327 
328 	mutex_lock(&priv->lock);
329 
330 	ret = hi8435_readb(priv, HI8435_PSEN_REG, &reg);
331 	if (ret < 0) {
332 		mutex_unlock(&priv->lock);
333 		return ret;
334 	}
335 
336 	reg &= ~BIT(chan->channel / 8);
337 	if (mode)
338 		reg |= BIT(chan->channel / 8);
339 
340 	ret = hi8435_writeb(priv, HI8435_PSEN_REG, reg);
341 
342 	mutex_unlock(&priv->lock);
343 
344 	return ret;
345 }
346 
347 static const char * const hi8435_sensing_modes[] = { "GND-Open",
348 						     "Supply-Open" };
349 
350 static const struct iio_enum hi8435_sensing_mode = {
351 	.items = hi8435_sensing_modes,
352 	.num_items = ARRAY_SIZE(hi8435_sensing_modes),
353 	.get = hi8435_get_sensing_mode,
354 	.set = hi8435_set_sensing_mode,
355 };
356 
357 static const struct iio_chan_spec_ext_info hi8435_ext_info[] = {
358 	IIO_ENUM("sensing_mode", IIO_SEPARATE, &hi8435_sensing_mode),
359 	IIO_ENUM_AVAILABLE("sensing_mode", &hi8435_sensing_mode),
360 	{},
361 };
362 
363 #define HI8435_VOLTAGE_CHANNEL(num)			\
364 {							\
365 	.type = IIO_VOLTAGE,				\
366 	.indexed = 1,					\
367 	.channel = num,					\
368 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),	\
369 	.event_spec = hi8435_events,			\
370 	.num_event_specs = ARRAY_SIZE(hi8435_events),	\
371 	.ext_info = hi8435_ext_info,			\
372 }
373 
374 static const struct iio_chan_spec hi8435_channels[] = {
375 	HI8435_VOLTAGE_CHANNEL(0),
376 	HI8435_VOLTAGE_CHANNEL(1),
377 	HI8435_VOLTAGE_CHANNEL(2),
378 	HI8435_VOLTAGE_CHANNEL(3),
379 	HI8435_VOLTAGE_CHANNEL(4),
380 	HI8435_VOLTAGE_CHANNEL(5),
381 	HI8435_VOLTAGE_CHANNEL(6),
382 	HI8435_VOLTAGE_CHANNEL(7),
383 	HI8435_VOLTAGE_CHANNEL(8),
384 	HI8435_VOLTAGE_CHANNEL(9),
385 	HI8435_VOLTAGE_CHANNEL(10),
386 	HI8435_VOLTAGE_CHANNEL(11),
387 	HI8435_VOLTAGE_CHANNEL(12),
388 	HI8435_VOLTAGE_CHANNEL(13),
389 	HI8435_VOLTAGE_CHANNEL(14),
390 	HI8435_VOLTAGE_CHANNEL(15),
391 	HI8435_VOLTAGE_CHANNEL(16),
392 	HI8435_VOLTAGE_CHANNEL(17),
393 	HI8435_VOLTAGE_CHANNEL(18),
394 	HI8435_VOLTAGE_CHANNEL(19),
395 	HI8435_VOLTAGE_CHANNEL(20),
396 	HI8435_VOLTAGE_CHANNEL(21),
397 	HI8435_VOLTAGE_CHANNEL(22),
398 	HI8435_VOLTAGE_CHANNEL(23),
399 	HI8435_VOLTAGE_CHANNEL(24),
400 	HI8435_VOLTAGE_CHANNEL(25),
401 	HI8435_VOLTAGE_CHANNEL(26),
402 	HI8435_VOLTAGE_CHANNEL(27),
403 	HI8435_VOLTAGE_CHANNEL(28),
404 	HI8435_VOLTAGE_CHANNEL(29),
405 	HI8435_VOLTAGE_CHANNEL(30),
406 	HI8435_VOLTAGE_CHANNEL(31),
407 	IIO_CHAN_SOFT_TIMESTAMP(32),
408 };
409 
410 static const struct iio_info hi8435_info = {
411 	.read_raw = hi8435_read_raw,
412 	.read_event_config = hi8435_read_event_config,
413 	.write_event_config = hi8435_write_event_config,
414 	.read_event_value = hi8435_read_event_value,
415 	.write_event_value = hi8435_write_event_value,
416 	.debugfs_reg_access = hi8435_debugfs_reg_access,
417 };
418 
419 static void hi8435_iio_push_event(struct iio_dev *idev, unsigned int val)
420 {
421 	struct hi8435_priv *priv = iio_priv(idev);
422 	enum iio_event_direction dir;
423 	unsigned int i;
424 	unsigned int status = priv->event_prev_val ^ val;
425 
426 	if (!status)
427 		return;
428 
429 	for_each_set_bit(i, &priv->event_scan_mask, 32) {
430 		if (status & BIT(i)) {
431 			dir = val & BIT(i) ? IIO_EV_DIR_RISING :
432 					     IIO_EV_DIR_FALLING;
433 			iio_push_event(idev,
434 				       IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i,
435 						    IIO_EV_TYPE_THRESH, dir),
436 				       iio_get_time_ns(idev));
437 		}
438 	}
439 
440 	priv->event_prev_val = val;
441 }
442 
443 static irqreturn_t hi8435_trigger_handler(int irq, void *private)
444 {
445 	struct iio_poll_func *pf = private;
446 	struct iio_dev *idev = pf->indio_dev;
447 	struct hi8435_priv *priv = iio_priv(idev);
448 	u32 val;
449 	int ret;
450 
451 	ret = hi8435_readl(priv, HI8435_SO31_0_REG, &val);
452 	if (ret < 0)
453 		goto err_read;
454 
455 	hi8435_iio_push_event(idev, val);
456 
457 err_read:
458 	iio_trigger_notify_done(idev->trig);
459 
460 	return IRQ_HANDLED;
461 }
462 
463 static int hi8435_probe(struct spi_device *spi)
464 {
465 	struct iio_dev *idev;
466 	struct hi8435_priv *priv;
467 	struct gpio_desc *reset_gpio;
468 	int ret;
469 
470 	idev = devm_iio_device_alloc(&spi->dev, sizeof(*priv));
471 	if (!idev)
472 		return -ENOMEM;
473 
474 	priv = iio_priv(idev);
475 	priv->spi = spi;
476 
477 	reset_gpio = devm_gpiod_get(&spi->dev, NULL, GPIOD_OUT_LOW);
478 	if (IS_ERR(reset_gpio)) {
479 		/* chip s/w reset if h/w reset failed */
480 		hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST);
481 		hi8435_writeb(priv, HI8435_CTRL_REG, 0);
482 	} else {
483 		udelay(5);
484 		gpiod_set_value(reset_gpio, 1);
485 	}
486 
487 	spi_set_drvdata(spi, idev);
488 	mutex_init(&priv->lock);
489 
490 	idev->dev.parent	= &spi->dev;
491 	idev->dev.of_node	= spi->dev.of_node;
492 	idev->name		= spi_get_device_id(spi)->name;
493 	idev->modes		= INDIO_DIRECT_MODE;
494 	idev->info		= &hi8435_info;
495 	idev->channels		= hi8435_channels;
496 	idev->num_channels	= ARRAY_SIZE(hi8435_channels);
497 
498 	/* unmask all events */
499 	priv->event_scan_mask = ~(0);
500 	/*
501 	 * There is a restriction in the chip - the hysteresis can not be odd.
502 	 * If the hysteresis is set to odd value then chip gets into lock state
503 	 * and not functional anymore.
504 	 * After chip reset the thresholds are in undefined state, so we need to
505 	 * initialize thresholds to some initial values and then prevent
506 	 * userspace setting odd hysteresis.
507 	 *
508 	 * Set threshold low voltage to 2V, threshold high voltage to 4V
509 	 * for both GND-Open and Supply-Open sensing modes.
510 	 */
511 	priv->threshold_lo[0] = priv->threshold_lo[1] = 2;
512 	priv->threshold_hi[0] = priv->threshold_hi[1] = 4;
513 	hi8435_writew(priv, HI8435_GOCENHYS_REG, 0x206);
514 	hi8435_writew(priv, HI8435_SOCENHYS_REG, 0x206);
515 
516 	ret = iio_triggered_event_setup(idev, NULL, hi8435_trigger_handler);
517 	if (ret)
518 		return ret;
519 
520 	ret = iio_device_register(idev);
521 	if (ret < 0) {
522 		dev_err(&spi->dev, "unable to register device\n");
523 		goto unregister_triggered_event;
524 	}
525 
526 	return 0;
527 
528 unregister_triggered_event:
529 	iio_triggered_event_cleanup(idev);
530 	return ret;
531 }
532 
533 static int hi8435_remove(struct spi_device *spi)
534 {
535 	struct iio_dev *idev = spi_get_drvdata(spi);
536 
537 	iio_device_unregister(idev);
538 	iio_triggered_event_cleanup(idev);
539 
540 	return 0;
541 }
542 
543 static const struct of_device_id hi8435_dt_ids[] = {
544 	{ .compatible = "holt,hi8435" },
545 	{},
546 };
547 MODULE_DEVICE_TABLE(of, hi8435_dt_ids);
548 
549 static const struct spi_device_id hi8435_id[] = {
550 	{ "hi8435", 0},
551 	{ }
552 };
553 MODULE_DEVICE_TABLE(spi, hi8435_id);
554 
555 static struct spi_driver hi8435_driver = {
556 	.driver	= {
557 		.name		= DRV_NAME,
558 		.of_match_table	= of_match_ptr(hi8435_dt_ids),
559 	},
560 	.probe		= hi8435_probe,
561 	.remove		= hi8435_remove,
562 	.id_table	= hi8435_id,
563 };
564 module_spi_driver(hi8435_driver);
565 
566 MODULE_LICENSE("GPL");
567 MODULE_AUTHOR("Vladimir Barinov");
568 MODULE_DESCRIPTION("HI-8435 threshold detector");
569