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