hi8435.c 14 KB

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