hi8435.c 13 KB

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