• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
hi8435_readb(struct hi8435_priv * priv,u8 reg,u8 * val)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 
hi8435_readw(struct hi8435_priv * priv,u8 reg,u16 * val)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 
hi8435_readl(struct hi8435_priv * priv,u8 reg,u32 * val)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 
hi8435_writeb(struct hi8435_priv * priv,u8 reg,u8 val)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 
hi8435_writew(struct hi8435_priv * priv,u8 reg,u16 val)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 
hi8435_read_event_config(struct iio_dev * idev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir)108 static int hi8435_read_event_config(struct iio_dev *idev,
109 				    const struct iio_chan_spec *chan,
110 				    enum iio_event_type type,
111 				    enum iio_event_direction dir)
112 {
113 	struct hi8435_priv *priv = iio_priv(idev);
114 
115 	return !!(priv->event_scan_mask & BIT(chan->channel));
116 }
117 
hi8435_write_event_config(struct iio_dev * idev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,int state)118 static int hi8435_write_event_config(struct iio_dev *idev,
119 				     const struct iio_chan_spec *chan,
120 				     enum iio_event_type type,
121 				     enum iio_event_direction dir, int state)
122 {
123 	struct hi8435_priv *priv = iio_priv(idev);
124 	int ret;
125 	u32 tmp;
126 
127 	if (state) {
128 		ret = hi8435_readl(priv, HI8435_SO31_0_REG, &tmp);
129 		if (ret < 0)
130 			return ret;
131 		if (tmp & BIT(chan->channel))
132 			priv->event_prev_val |= BIT(chan->channel);
133 		else
134 			priv->event_prev_val &= ~BIT(chan->channel);
135 
136 		priv->event_scan_mask |= BIT(chan->channel);
137 	} else
138 		priv->event_scan_mask &= ~BIT(chan->channel);
139 
140 	return 0;
141 }
142 
hi8435_read_event_value(struct iio_dev * idev,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)143 static int hi8435_read_event_value(struct iio_dev *idev,
144 				   const struct iio_chan_spec *chan,
145 				   enum iio_event_type type,
146 				   enum iio_event_direction dir,
147 				   enum iio_event_info info,
148 				   int *val, int *val2)
149 {
150 	struct hi8435_priv *priv = iio_priv(idev);
151 	int ret;
152 	u8 mode, psen;
153 	u16 reg;
154 
155 	ret = hi8435_readb(priv, HI8435_PSEN_REG, &psen);
156 	if (ret < 0)
157 		return ret;
158 
159 	/* Supply-Open or GND-Open sensing mode */
160 	mode = !!(psen & BIT(chan->channel / 8));
161 
162 	ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG :
163 				 HI8435_GOCENHYS_REG, &reg);
164 	if (ret < 0)
165 		return ret;
166 
167 	if (dir == IIO_EV_DIR_FALLING)
168 		*val = ((reg & 0xff) - (reg >> 8)) / 2;
169 	else if (dir == IIO_EV_DIR_RISING)
170 		*val = ((reg & 0xff) + (reg >> 8)) / 2;
171 
172 	return IIO_VAL_INT;
173 }
174 
hi8435_write_event_value(struct iio_dev * idev,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)175 static int hi8435_write_event_value(struct iio_dev *idev,
176 				    const struct iio_chan_spec *chan,
177 				    enum iio_event_type type,
178 				    enum iio_event_direction dir,
179 				    enum iio_event_info info,
180 				    int val, int val2)
181 {
182 	struct hi8435_priv *priv = iio_priv(idev);
183 	int ret;
184 	u8 mode, psen;
185 	u16 reg;
186 
187 	ret = hi8435_readb(priv, HI8435_PSEN_REG, &psen);
188 	if (ret < 0)
189 		return ret;
190 
191 	/* Supply-Open or GND-Open sensing mode */
192 	mode = !!(psen & BIT(chan->channel / 8));
193 
194 	ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG :
195 				 HI8435_GOCENHYS_REG, &reg);
196 	if (ret < 0)
197 		return ret;
198 
199 	if (dir == IIO_EV_DIR_FALLING) {
200 		/* falling threshold range 2..21V, hysteresis minimum 2V */
201 		if (val < 2 || val > 21 || (val + 2) > priv->threshold_hi[mode])
202 			return -EINVAL;
203 
204 		if (val == priv->threshold_lo[mode])
205 			return 0;
206 
207 		priv->threshold_lo[mode] = val;
208 
209 		/* hysteresis must not be odd */
210 		if ((priv->threshold_hi[mode] - priv->threshold_lo[mode]) % 2)
211 			priv->threshold_hi[mode]--;
212 	} else if (dir == IIO_EV_DIR_RISING) {
213 		/* rising threshold range 3..22V, hysteresis minimum 2V */
214 		if (val < 3 || val > 22 || val < (priv->threshold_lo[mode] + 2))
215 			return -EINVAL;
216 
217 		if (val == priv->threshold_hi[mode])
218 			return 0;
219 
220 		priv->threshold_hi[mode] = val;
221 
222 		/* hysteresis must not be odd */
223 		if ((priv->threshold_hi[mode] - priv->threshold_lo[mode]) % 2)
224 			priv->threshold_lo[mode]++;
225 	}
226 
227 	/* program thresholds */
228 	mutex_lock(&priv->lock);
229 
230 	ret = hi8435_readw(priv, mode ? HI8435_SOCENHYS_REG :
231 				 HI8435_GOCENHYS_REG, &reg);
232 	if (ret < 0) {
233 		mutex_unlock(&priv->lock);
234 		return ret;
235 	}
236 
237 	/* hysteresis */
238 	reg = priv->threshold_hi[mode] - priv->threshold_lo[mode];
239 	reg <<= 8;
240 	/* threshold center */
241 	reg |= (priv->threshold_hi[mode] + priv->threshold_lo[mode]);
242 
243 	ret = hi8435_writew(priv, mode ? HI8435_SOCENHYS_REG :
244 				  HI8435_GOCENHYS_REG, reg);
245 
246 	mutex_unlock(&priv->lock);
247 
248 	return ret;
249 }
250 
hi8435_debugfs_reg_access(struct iio_dev * idev,unsigned reg,unsigned writeval,unsigned * readval)251 static int hi8435_debugfs_reg_access(struct iio_dev *idev,
252 				     unsigned reg, unsigned writeval,
253 				     unsigned *readval)
254 {
255 	struct hi8435_priv *priv = iio_priv(idev);
256 	int ret;
257 	u8 val;
258 
259 	if (readval != NULL) {
260 		ret = hi8435_readb(priv, reg, &val);
261 		*readval = val;
262 	} else {
263 		val = (u8)writeval;
264 		ret = hi8435_writeb(priv, reg, val);
265 	}
266 
267 	return ret;
268 }
269 
270 static const struct iio_event_spec hi8435_events[] = {
271 	{
272 		.type = IIO_EV_TYPE_THRESH,
273 		.dir = IIO_EV_DIR_RISING,
274 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
275 	}, {
276 		.type = IIO_EV_TYPE_THRESH,
277 		.dir = IIO_EV_DIR_FALLING,
278 		.mask_separate = BIT(IIO_EV_INFO_VALUE),
279 	}, {
280 		.type = IIO_EV_TYPE_THRESH,
281 		.dir = IIO_EV_DIR_EITHER,
282 		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
283 	},
284 };
285 
hi8435_get_sensing_mode(struct iio_dev * idev,const struct iio_chan_spec * chan)286 static int hi8435_get_sensing_mode(struct iio_dev *idev,
287 				   const struct iio_chan_spec *chan)
288 {
289 	struct hi8435_priv *priv = iio_priv(idev);
290 	int ret;
291 	u8 reg;
292 
293 	ret = hi8435_readb(priv, HI8435_PSEN_REG, &reg);
294 	if (ret < 0)
295 		return ret;
296 
297 	return !!(reg & BIT(chan->channel / 8));
298 }
299 
hi8435_set_sensing_mode(struct iio_dev * idev,const struct iio_chan_spec * chan,unsigned int mode)300 static int hi8435_set_sensing_mode(struct iio_dev *idev,
301 				   const struct iio_chan_spec *chan,
302 				   unsigned int mode)
303 {
304 	struct hi8435_priv *priv = iio_priv(idev);
305 	int ret;
306 	u8 reg;
307 
308 	mutex_lock(&priv->lock);
309 
310 	ret = hi8435_readb(priv, HI8435_PSEN_REG, &reg);
311 	if (ret < 0) {
312 		mutex_unlock(&priv->lock);
313 		return ret;
314 	}
315 
316 	reg &= ~BIT(chan->channel / 8);
317 	if (mode)
318 		reg |= BIT(chan->channel / 8);
319 
320 	ret = hi8435_writeb(priv, HI8435_PSEN_REG, reg);
321 
322 	mutex_unlock(&priv->lock);
323 
324 	return ret;
325 }
326 
327 static const char * const hi8435_sensing_modes[] = { "GND-Open",
328 						     "Supply-Open" };
329 
330 static const struct iio_enum hi8435_sensing_mode = {
331 	.items = hi8435_sensing_modes,
332 	.num_items = ARRAY_SIZE(hi8435_sensing_modes),
333 	.get = hi8435_get_sensing_mode,
334 	.set = hi8435_set_sensing_mode,
335 };
336 
337 static const struct iio_chan_spec_ext_info hi8435_ext_info[] = {
338 	IIO_ENUM("sensing_mode", IIO_SEPARATE, &hi8435_sensing_mode),
339 	{},
340 };
341 
342 #define HI8435_VOLTAGE_CHANNEL(num)			\
343 {							\
344 	.type = IIO_VOLTAGE,				\
345 	.indexed = 1,					\
346 	.channel = num,					\
347 	.event_spec = hi8435_events,			\
348 	.num_event_specs = ARRAY_SIZE(hi8435_events),	\
349 	.ext_info = hi8435_ext_info,			\
350 }
351 
352 static const struct iio_chan_spec hi8435_channels[] = {
353 	HI8435_VOLTAGE_CHANNEL(0),
354 	HI8435_VOLTAGE_CHANNEL(1),
355 	HI8435_VOLTAGE_CHANNEL(2),
356 	HI8435_VOLTAGE_CHANNEL(3),
357 	HI8435_VOLTAGE_CHANNEL(4),
358 	HI8435_VOLTAGE_CHANNEL(5),
359 	HI8435_VOLTAGE_CHANNEL(6),
360 	HI8435_VOLTAGE_CHANNEL(7),
361 	HI8435_VOLTAGE_CHANNEL(8),
362 	HI8435_VOLTAGE_CHANNEL(9),
363 	HI8435_VOLTAGE_CHANNEL(10),
364 	HI8435_VOLTAGE_CHANNEL(11),
365 	HI8435_VOLTAGE_CHANNEL(12),
366 	HI8435_VOLTAGE_CHANNEL(13),
367 	HI8435_VOLTAGE_CHANNEL(14),
368 	HI8435_VOLTAGE_CHANNEL(15),
369 	HI8435_VOLTAGE_CHANNEL(16),
370 	HI8435_VOLTAGE_CHANNEL(17),
371 	HI8435_VOLTAGE_CHANNEL(18),
372 	HI8435_VOLTAGE_CHANNEL(19),
373 	HI8435_VOLTAGE_CHANNEL(20),
374 	HI8435_VOLTAGE_CHANNEL(21),
375 	HI8435_VOLTAGE_CHANNEL(22),
376 	HI8435_VOLTAGE_CHANNEL(23),
377 	HI8435_VOLTAGE_CHANNEL(24),
378 	HI8435_VOLTAGE_CHANNEL(25),
379 	HI8435_VOLTAGE_CHANNEL(26),
380 	HI8435_VOLTAGE_CHANNEL(27),
381 	HI8435_VOLTAGE_CHANNEL(28),
382 	HI8435_VOLTAGE_CHANNEL(29),
383 	HI8435_VOLTAGE_CHANNEL(30),
384 	HI8435_VOLTAGE_CHANNEL(31),
385 	IIO_CHAN_SOFT_TIMESTAMP(32),
386 };
387 
388 static const struct iio_info hi8435_info = {
389 	.driver_module = THIS_MODULE,
390 	.read_event_config = &hi8435_read_event_config,
391 	.write_event_config = hi8435_write_event_config,
392 	.read_event_value = &hi8435_read_event_value,
393 	.write_event_value = &hi8435_write_event_value,
394 	.debugfs_reg_access = &hi8435_debugfs_reg_access,
395 };
396 
hi8435_iio_push_event(struct iio_dev * idev,unsigned int val)397 static void hi8435_iio_push_event(struct iio_dev *idev, unsigned int val)
398 {
399 	struct hi8435_priv *priv = iio_priv(idev);
400 	enum iio_event_direction dir;
401 	unsigned int i;
402 	unsigned int status = priv->event_prev_val ^ val;
403 
404 	if (!status)
405 		return;
406 
407 	for_each_set_bit(i, &priv->event_scan_mask, 32) {
408 		if (status & BIT(i)) {
409 			dir = val & BIT(i) ? IIO_EV_DIR_RISING :
410 					     IIO_EV_DIR_FALLING;
411 			iio_push_event(idev,
412 				       IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, i,
413 						    IIO_EV_TYPE_THRESH, dir),
414 				       iio_get_time_ns());
415 		}
416 	}
417 
418 	priv->event_prev_val = val;
419 }
420 
hi8435_trigger_handler(int irq,void * private)421 static irqreturn_t hi8435_trigger_handler(int irq, void *private)
422 {
423 	struct iio_poll_func *pf = private;
424 	struct iio_dev *idev = pf->indio_dev;
425 	struct hi8435_priv *priv = iio_priv(idev);
426 	u32 val;
427 	int ret;
428 
429 	ret = hi8435_readl(priv, HI8435_SO31_0_REG, &val);
430 	if (ret < 0)
431 		goto err_read;
432 
433 	hi8435_iio_push_event(idev, val);
434 
435 err_read:
436 	iio_trigger_notify_done(idev->trig);
437 
438 	return IRQ_HANDLED;
439 }
440 
hi8435_probe(struct spi_device * spi)441 static int hi8435_probe(struct spi_device *spi)
442 {
443 	struct iio_dev *idev;
444 	struct hi8435_priv *priv;
445 	struct gpio_desc *reset_gpio;
446 	int ret;
447 
448 	idev = devm_iio_device_alloc(&spi->dev, sizeof(*priv));
449 	if (!idev)
450 		return -ENOMEM;
451 
452 	priv = iio_priv(idev);
453 	priv->spi = spi;
454 
455 	reset_gpio = devm_gpiod_get(&spi->dev, NULL, GPIOD_OUT_LOW);
456 	if (!IS_ERR(reset_gpio)) {
457 		/* need >=100ns low pulse to reset chip */
458 		gpiod_set_raw_value_cansleep(reset_gpio, 0);
459 		udelay(1);
460 		gpiod_set_raw_value_cansleep(reset_gpio, 1);
461 	} else {
462 		/* s/w reset chip if h/w reset is not available */
463 		hi8435_writeb(priv, HI8435_CTRL_REG, HI8435_CTRL_SRST);
464 		hi8435_writeb(priv, HI8435_CTRL_REG, 0);
465 	}
466 
467 	spi_set_drvdata(spi, idev);
468 	mutex_init(&priv->lock);
469 
470 	idev->dev.parent	= &spi->dev;
471 	idev->name		= spi_get_device_id(spi)->name;
472 	idev->modes		= INDIO_DIRECT_MODE;
473 	idev->info		= &hi8435_info;
474 	idev->channels		= hi8435_channels;
475 	idev->num_channels	= ARRAY_SIZE(hi8435_channels);
476 
477 	/* unmask all events */
478 	priv->event_scan_mask = ~(0);
479 	/*
480 	 * There is a restriction in the chip - the hysteresis can not be odd.
481 	 * If the hysteresis is set to odd value then chip gets into lock state
482 	 * and not functional anymore.
483 	 * After chip reset the thresholds are in undefined state, so we need to
484 	 * initialize thresholds to some initial values and then prevent
485 	 * userspace setting odd hysteresis.
486 	 *
487 	 * Set threshold low voltage to 2V, threshold high voltage to 4V
488 	 * for both GND-Open and Supply-Open sensing modes.
489 	 */
490 	priv->threshold_lo[0] = priv->threshold_lo[1] = 2;
491 	priv->threshold_hi[0] = priv->threshold_hi[1] = 4;
492 	hi8435_writew(priv, HI8435_GOCENHYS_REG, 0x206);
493 	hi8435_writew(priv, HI8435_SOCENHYS_REG, 0x206);
494 
495 	ret = iio_triggered_event_setup(idev, NULL, hi8435_trigger_handler);
496 	if (ret)
497 		return ret;
498 
499 	ret = iio_device_register(idev);
500 	if (ret < 0) {
501 		dev_err(&spi->dev, "unable to register device\n");
502 		goto unregister_triggered_event;
503 	}
504 
505 	return 0;
506 
507 unregister_triggered_event:
508 	iio_triggered_event_cleanup(idev);
509 	return ret;
510 }
511 
hi8435_remove(struct spi_device * spi)512 static int hi8435_remove(struct spi_device *spi)
513 {
514 	struct iio_dev *idev = spi_get_drvdata(spi);
515 
516 	iio_device_unregister(idev);
517 	iio_triggered_event_cleanup(idev);
518 
519 	return 0;
520 }
521 
522 static const struct of_device_id hi8435_dt_ids[] = {
523 	{ .compatible = "holt,hi8435" },
524 	{},
525 };
526 MODULE_DEVICE_TABLE(of, hi8435_dt_ids);
527 
528 static const struct spi_device_id hi8435_id[] = {
529 	{ "hi8435", 0},
530 	{ }
531 };
532 MODULE_DEVICE_TABLE(spi, hi8435_id);
533 
534 static struct spi_driver hi8435_driver = {
535 	.driver	= {
536 		.name		= DRV_NAME,
537 		.of_match_table	= of_match_ptr(hi8435_dt_ids),
538 	},
539 	.probe		= hi8435_probe,
540 	.remove		= hi8435_remove,
541 	.id_table	= hi8435_id,
542 };
543 module_spi_driver(hi8435_driver);
544 
545 MODULE_LICENSE("GPL");
546 MODULE_AUTHOR("Vladimir Barinov");
547 MODULE_DESCRIPTION("HI-8435 threshold detector");
548