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