hi8435.c 13 KB

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