hts221_buffer.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * STMicroelectronics hts221 sensor driver
  4. *
  5. * Copyright 2016 STMicroelectronics Inc.
  6. *
  7. * Lorenzo Bianconi <[email protected]>
  8. */
  9. #include <linux/kernel.h>
  10. #include <linux/module.h>
  11. #include <linux/device.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/irqreturn.h>
  14. #include <linux/property.h>
  15. #include <linux/regmap.h>
  16. #include <linux/bitfield.h>
  17. #include <linux/iio/iio.h>
  18. #include <linux/iio/trigger.h>
  19. #include <linux/iio/events.h>
  20. #include <linux/iio/trigger_consumer.h>
  21. #include <linux/iio/triggered_buffer.h>
  22. #include <linux/iio/buffer.h>
  23. #include <linux/platform_data/st_sensors_pdata.h>
  24. #include "hts221.h"
  25. #define HTS221_REG_DRDY_HL_ADDR 0x22
  26. #define HTS221_REG_DRDY_HL_MASK BIT(7)
  27. #define HTS221_REG_DRDY_PP_OD_ADDR 0x22
  28. #define HTS221_REG_DRDY_PP_OD_MASK BIT(6)
  29. #define HTS221_REG_DRDY_EN_ADDR 0x22
  30. #define HTS221_REG_DRDY_EN_MASK BIT(2)
  31. #define HTS221_REG_STATUS_ADDR 0x27
  32. #define HTS221_RH_DRDY_MASK BIT(1)
  33. #define HTS221_TEMP_DRDY_MASK BIT(0)
  34. static int hts221_trig_set_state(struct iio_trigger *trig, bool state)
  35. {
  36. struct iio_dev *iio_dev = iio_trigger_get_drvdata(trig);
  37. struct hts221_hw *hw = iio_priv(iio_dev);
  38. return regmap_update_bits(hw->regmap, HTS221_REG_DRDY_EN_ADDR,
  39. HTS221_REG_DRDY_EN_MASK,
  40. FIELD_PREP(HTS221_REG_DRDY_EN_MASK, state));
  41. }
  42. static const struct iio_trigger_ops hts221_trigger_ops = {
  43. .set_trigger_state = hts221_trig_set_state,
  44. };
  45. static irqreturn_t hts221_trigger_handler_thread(int irq, void *private)
  46. {
  47. struct hts221_hw *hw = private;
  48. int err, status;
  49. err = regmap_read(hw->regmap, HTS221_REG_STATUS_ADDR, &status);
  50. if (err < 0)
  51. return IRQ_HANDLED;
  52. /*
  53. * H_DA bit (humidity data available) is routed to DRDY line.
  54. * Humidity sample is computed after temperature one.
  55. * Here we can assume data channels are both available if H_DA bit
  56. * is set in status register
  57. */
  58. if (!(status & HTS221_RH_DRDY_MASK))
  59. return IRQ_NONE;
  60. iio_trigger_poll_chained(hw->trig);
  61. return IRQ_HANDLED;
  62. }
  63. int hts221_allocate_trigger(struct iio_dev *iio_dev)
  64. {
  65. struct hts221_hw *hw = iio_priv(iio_dev);
  66. struct st_sensors_platform_data *pdata = dev_get_platdata(hw->dev);
  67. bool irq_active_low = false, open_drain = false;
  68. unsigned long irq_type;
  69. int err;
  70. irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
  71. switch (irq_type) {
  72. case IRQF_TRIGGER_HIGH:
  73. case IRQF_TRIGGER_RISING:
  74. break;
  75. case IRQF_TRIGGER_LOW:
  76. case IRQF_TRIGGER_FALLING:
  77. irq_active_low = true;
  78. break;
  79. default:
  80. dev_info(hw->dev,
  81. "mode %lx unsupported, using IRQF_TRIGGER_RISING\n",
  82. irq_type);
  83. irq_type = IRQF_TRIGGER_RISING;
  84. break;
  85. }
  86. err = regmap_update_bits(hw->regmap, HTS221_REG_DRDY_HL_ADDR,
  87. HTS221_REG_DRDY_HL_MASK,
  88. FIELD_PREP(HTS221_REG_DRDY_HL_MASK,
  89. irq_active_low));
  90. if (err < 0)
  91. return err;
  92. if (device_property_read_bool(hw->dev, "drive-open-drain") ||
  93. (pdata && pdata->open_drain)) {
  94. irq_type |= IRQF_SHARED;
  95. open_drain = true;
  96. }
  97. err = regmap_update_bits(hw->regmap, HTS221_REG_DRDY_PP_OD_ADDR,
  98. HTS221_REG_DRDY_PP_OD_MASK,
  99. FIELD_PREP(HTS221_REG_DRDY_PP_OD_MASK,
  100. open_drain));
  101. if (err < 0)
  102. return err;
  103. err = devm_request_threaded_irq(hw->dev, hw->irq, NULL,
  104. hts221_trigger_handler_thread,
  105. irq_type | IRQF_ONESHOT,
  106. hw->name, hw);
  107. if (err) {
  108. dev_err(hw->dev, "failed to request trigger irq %d\n",
  109. hw->irq);
  110. return err;
  111. }
  112. hw->trig = devm_iio_trigger_alloc(hw->dev, "%s-trigger",
  113. iio_dev->name);
  114. if (!hw->trig)
  115. return -ENOMEM;
  116. iio_trigger_set_drvdata(hw->trig, iio_dev);
  117. hw->trig->ops = &hts221_trigger_ops;
  118. err = devm_iio_trigger_register(hw->dev, hw->trig);
  119. iio_dev->trig = iio_trigger_get(hw->trig);
  120. return err;
  121. }
  122. static int hts221_buffer_preenable(struct iio_dev *iio_dev)
  123. {
  124. return hts221_set_enable(iio_priv(iio_dev), true);
  125. }
  126. static int hts221_buffer_postdisable(struct iio_dev *iio_dev)
  127. {
  128. return hts221_set_enable(iio_priv(iio_dev), false);
  129. }
  130. static const struct iio_buffer_setup_ops hts221_buffer_ops = {
  131. .preenable = hts221_buffer_preenable,
  132. .postdisable = hts221_buffer_postdisable,
  133. };
  134. static irqreturn_t hts221_buffer_handler_thread(int irq, void *p)
  135. {
  136. struct iio_poll_func *pf = p;
  137. struct iio_dev *iio_dev = pf->indio_dev;
  138. struct hts221_hw *hw = iio_priv(iio_dev);
  139. struct iio_chan_spec const *ch;
  140. int err;
  141. /* humidity data */
  142. ch = &iio_dev->channels[HTS221_SENSOR_H];
  143. err = regmap_bulk_read(hw->regmap, ch->address,
  144. &hw->scan.channels[0],
  145. sizeof(hw->scan.channels[0]));
  146. if (err < 0)
  147. goto out;
  148. /* temperature data */
  149. ch = &iio_dev->channels[HTS221_SENSOR_T];
  150. err = regmap_bulk_read(hw->regmap, ch->address,
  151. &hw->scan.channels[1],
  152. sizeof(hw->scan.channels[1]));
  153. if (err < 0)
  154. goto out;
  155. iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan,
  156. iio_get_time_ns(iio_dev));
  157. out:
  158. iio_trigger_notify_done(hw->trig);
  159. return IRQ_HANDLED;
  160. }
  161. int hts221_allocate_buffers(struct iio_dev *iio_dev)
  162. {
  163. struct hts221_hw *hw = iio_priv(iio_dev);
  164. return devm_iio_triggered_buffer_setup(hw->dev, iio_dev,
  165. NULL, hts221_buffer_handler_thread,
  166. &hts221_buffer_ops);
  167. }
  168. MODULE_AUTHOR("Lorenzo Bianconi <[email protected]>");
  169. MODULE_DESCRIPTION("STMicroelectronics hts221 buffer driver");
  170. MODULE_LICENSE("GPL v2");