hts221_buffer.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * STMicroelectronics hts221 sensor driver
  3. *
  4. * Copyright 2016 STMicroelectronics Inc.
  5. *
  6. * Lorenzo Bianconi <lorenzo.bianconi@st.com>
  7. *
  8. * Licensed under the GPL-2.
  9. */
  10. #include <linux/kernel.h>
  11. #include <linux/module.h>
  12. #include <linux/device.h>
  13. #include <linux/interrupt.h>
  14. #include <linux/irqreturn.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 hts221_hw *hw)
  64. {
  65. struct iio_dev *iio_dev = iio_priv_to_dev(hw);
  66. bool irq_active_low = false, open_drain = false;
  67. struct device_node *np = hw->dev->of_node;
  68. struct st_sensors_platform_data *pdata;
  69. unsigned long irq_type;
  70. int err;
  71. irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
  72. switch (irq_type) {
  73. case IRQF_TRIGGER_HIGH:
  74. case IRQF_TRIGGER_RISING:
  75. break;
  76. case IRQF_TRIGGER_LOW:
  77. case IRQF_TRIGGER_FALLING:
  78. irq_active_low = true;
  79. break;
  80. default:
  81. dev_info(hw->dev,
  82. "mode %lx unsupported, using IRQF_TRIGGER_RISING\n",
  83. irq_type);
  84. irq_type = IRQF_TRIGGER_RISING;
  85. break;
  86. }
  87. err = regmap_update_bits(hw->regmap, HTS221_REG_DRDY_HL_ADDR,
  88. HTS221_REG_DRDY_HL_MASK,
  89. FIELD_PREP(HTS221_REG_DRDY_HL_MASK,
  90. irq_active_low));
  91. if (err < 0)
  92. return err;
  93. pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
  94. if ((np && of_property_read_bool(np, "drive-open-drain")) ||
  95. (pdata && pdata->open_drain)) {
  96. irq_type |= IRQF_SHARED;
  97. open_drain = true;
  98. }
  99. err = regmap_update_bits(hw->regmap, HTS221_REG_DRDY_PP_OD_ADDR,
  100. HTS221_REG_DRDY_PP_OD_MASK,
  101. FIELD_PREP(HTS221_REG_DRDY_PP_OD_MASK,
  102. open_drain));
  103. if (err < 0)
  104. return err;
  105. err = devm_request_threaded_irq(hw->dev, hw->irq, NULL,
  106. hts221_trigger_handler_thread,
  107. irq_type | IRQF_ONESHOT,
  108. hw->name, hw);
  109. if (err) {
  110. dev_err(hw->dev, "failed to request trigger irq %d\n",
  111. hw->irq);
  112. return err;
  113. }
  114. hw->trig = devm_iio_trigger_alloc(hw->dev, "%s-trigger",
  115. iio_dev->name);
  116. if (!hw->trig)
  117. return -ENOMEM;
  118. iio_trigger_set_drvdata(hw->trig, iio_dev);
  119. hw->trig->ops = &hts221_trigger_ops;
  120. hw->trig->dev.parent = hw->dev;
  121. iio_dev->trig = iio_trigger_get(hw->trig);
  122. return devm_iio_trigger_register(hw->dev, hw->trig);
  123. }
  124. static int hts221_buffer_preenable(struct iio_dev *iio_dev)
  125. {
  126. return hts221_set_enable(iio_priv(iio_dev), true);
  127. }
  128. static int hts221_buffer_postdisable(struct iio_dev *iio_dev)
  129. {
  130. return hts221_set_enable(iio_priv(iio_dev), false);
  131. }
  132. static const struct iio_buffer_setup_ops hts221_buffer_ops = {
  133. .preenable = hts221_buffer_preenable,
  134. .postenable = iio_triggered_buffer_postenable,
  135. .predisable = iio_triggered_buffer_predisable,
  136. .postdisable = hts221_buffer_postdisable,
  137. };
  138. static irqreturn_t hts221_buffer_handler_thread(int irq, void *p)
  139. {
  140. u8 buffer[ALIGN(2 * HTS221_DATA_SIZE, sizeof(s64)) + sizeof(s64)];
  141. struct iio_poll_func *pf = p;
  142. struct iio_dev *iio_dev = pf->indio_dev;
  143. struct hts221_hw *hw = iio_priv(iio_dev);
  144. struct iio_chan_spec const *ch;
  145. int err;
  146. /* humidity data */
  147. ch = &iio_dev->channels[HTS221_SENSOR_H];
  148. err = regmap_bulk_read(hw->regmap, ch->address,
  149. buffer, HTS221_DATA_SIZE);
  150. if (err < 0)
  151. goto out;
  152. /* temperature data */
  153. ch = &iio_dev->channels[HTS221_SENSOR_T];
  154. err = regmap_bulk_read(hw->regmap, ch->address,
  155. buffer + HTS221_DATA_SIZE, HTS221_DATA_SIZE);
  156. if (err < 0)
  157. goto out;
  158. iio_push_to_buffers_with_timestamp(iio_dev, buffer,
  159. iio_get_time_ns(iio_dev));
  160. out:
  161. iio_trigger_notify_done(hw->trig);
  162. return IRQ_HANDLED;
  163. }
  164. int hts221_allocate_buffers(struct hts221_hw *hw)
  165. {
  166. return devm_iio_triggered_buffer_setup(hw->dev, iio_priv_to_dev(hw),
  167. NULL, hts221_buffer_handler_thread,
  168. &hts221_buffer_ops);
  169. }
  170. MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
  171. MODULE_DESCRIPTION("STMicroelectronics hts221 buffer driver");
  172. MODULE_LICENSE("GPL v2");