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