hts221_buffer.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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/iio/iio.h>
  16. #include <linux/iio/trigger.h>
  17. #include <linux/iio/events.h>
  18. #include <linux/iio/trigger_consumer.h>
  19. #include <linux/iio/triggered_buffer.h>
  20. #include <linux/iio/buffer.h>
  21. #include <linux/platform_data/st_sensors_pdata.h>
  22. #include "hts221.h"
  23. #define HTS221_REG_DRDY_HL_ADDR 0x22
  24. #define HTS221_REG_DRDY_HL_MASK BIT(7)
  25. #define HTS221_REG_DRDY_PP_OD_ADDR 0x22
  26. #define HTS221_REG_DRDY_PP_OD_MASK BIT(6)
  27. #define HTS221_REG_DRDY_EN_ADDR 0x22
  28. #define HTS221_REG_DRDY_EN_MASK BIT(2)
  29. #define HTS221_REG_STATUS_ADDR 0x27
  30. #define HTS221_RH_DRDY_MASK BIT(1)
  31. #define HTS221_TEMP_DRDY_MASK BIT(0)
  32. static int hts221_trig_set_state(struct iio_trigger *trig, bool state)
  33. {
  34. struct iio_dev *iio_dev = iio_trigger_get_drvdata(trig);
  35. struct hts221_hw *hw = iio_priv(iio_dev);
  36. int err;
  37. err = hts221_write_with_mask(hw, HTS221_REG_DRDY_EN_ADDR,
  38. HTS221_REG_DRDY_EN_MASK, state);
  39. return err < 0 ? err : 0;
  40. }
  41. static const struct iio_trigger_ops hts221_trigger_ops = {
  42. .owner = THIS_MODULE,
  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. u8 status;
  49. int err;
  50. err = hw->tf->read(hw->dev, HTS221_REG_STATUS_ADDR, sizeof(status),
  51. &status);
  52. if (err < 0)
  53. return IRQ_HANDLED;
  54. /*
  55. * H_DA bit (humidity data available) is routed to DRDY line.
  56. * Humidity sample is computed after temperature one.
  57. * Here we can assume data channels are both available if H_DA bit
  58. * is set in status register
  59. */
  60. if (!(status & HTS221_RH_DRDY_MASK))
  61. return IRQ_NONE;
  62. iio_trigger_poll_chained(hw->trig);
  63. return IRQ_HANDLED;
  64. }
  65. int hts221_allocate_trigger(struct hts221_hw *hw)
  66. {
  67. struct iio_dev *iio_dev = iio_priv_to_dev(hw);
  68. bool irq_active_low = false, open_drain = false;
  69. struct device_node *np = hw->dev->of_node;
  70. struct st_sensors_platform_data *pdata;
  71. unsigned long irq_type;
  72. int err;
  73. irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq));
  74. switch (irq_type) {
  75. case IRQF_TRIGGER_HIGH:
  76. case IRQF_TRIGGER_RISING:
  77. break;
  78. case IRQF_TRIGGER_LOW:
  79. case IRQF_TRIGGER_FALLING:
  80. irq_active_low = true;
  81. break;
  82. default:
  83. dev_info(hw->dev,
  84. "mode %lx unsupported, using IRQF_TRIGGER_RISING\n",
  85. irq_type);
  86. irq_type = IRQF_TRIGGER_RISING;
  87. break;
  88. }
  89. err = hts221_write_with_mask(hw, HTS221_REG_DRDY_HL_ADDR,
  90. HTS221_REG_DRDY_HL_MASK, 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 = hts221_write_with_mask(hw, HTS221_REG_DRDY_PP_OD_ADDR,
  100. HTS221_REG_DRDY_PP_OD_MASK,
  101. open_drain);
  102. if (err < 0)
  103. return err;
  104. err = devm_request_threaded_irq(hw->dev, hw->irq, NULL,
  105. hts221_trigger_handler_thread,
  106. irq_type | IRQF_ONESHOT,
  107. hw->name, hw);
  108. if (err) {
  109. dev_err(hw->dev, "failed to request trigger irq %d\n",
  110. hw->irq);
  111. return err;
  112. }
  113. hw->trig = devm_iio_trigger_alloc(hw->dev, "%s-trigger",
  114. iio_dev->name);
  115. if (!hw->trig)
  116. return -ENOMEM;
  117. iio_trigger_set_drvdata(hw->trig, iio_dev);
  118. hw->trig->ops = &hts221_trigger_ops;
  119. hw->trig->dev.parent = hw->dev;
  120. iio_dev->trig = iio_trigger_get(hw->trig);
  121. return devm_iio_trigger_register(hw->dev, hw->trig);
  122. }
  123. static int hts221_buffer_preenable(struct iio_dev *iio_dev)
  124. {
  125. return hts221_set_enable(iio_priv(iio_dev), true);
  126. }
  127. static int hts221_buffer_postdisable(struct iio_dev *iio_dev)
  128. {
  129. return hts221_set_enable(iio_priv(iio_dev), false);
  130. }
  131. static const struct iio_buffer_setup_ops hts221_buffer_ops = {
  132. .preenable = hts221_buffer_preenable,
  133. .postenable = iio_triggered_buffer_postenable,
  134. .predisable = iio_triggered_buffer_predisable,
  135. .postdisable = hts221_buffer_postdisable,
  136. };
  137. static irqreturn_t hts221_buffer_handler_thread(int irq, void *p)
  138. {
  139. u8 buffer[ALIGN(2 * HTS221_DATA_SIZE, sizeof(s64)) + sizeof(s64)];
  140. struct iio_poll_func *pf = p;
  141. struct iio_dev *iio_dev = pf->indio_dev;
  142. struct hts221_hw *hw = iio_priv(iio_dev);
  143. struct iio_chan_spec const *ch;
  144. int err;
  145. /* humidity data */
  146. ch = &iio_dev->channels[HTS221_SENSOR_H];
  147. err = hw->tf->read(hw->dev, ch->address, HTS221_DATA_SIZE,
  148. buffer);
  149. if (err < 0)
  150. goto out;
  151. /* temperature data */
  152. ch = &iio_dev->channels[HTS221_SENSOR_T];
  153. err = hw->tf->read(hw->dev, ch->address, HTS221_DATA_SIZE,
  154. buffer + HTS221_DATA_SIZE);
  155. if (err < 0)
  156. goto out;
  157. iio_push_to_buffers_with_timestamp(iio_dev, buffer,
  158. iio_get_time_ns(iio_dev));
  159. out:
  160. iio_trigger_notify_done(hw->trig);
  161. return IRQ_HANDLED;
  162. }
  163. int hts221_allocate_buffers(struct hts221_hw *hw)
  164. {
  165. return devm_iio_triggered_buffer_setup(hw->dev, iio_priv_to_dev(hw),
  166. NULL, hts221_buffer_handler_thread,
  167. &hts221_buffer_ops);
  168. }
  169. MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
  170. MODULE_DESCRIPTION("STMicroelectronics hts221 buffer driver");
  171. MODULE_LICENSE("GPL v2");