diff options
Diffstat (limited to 'drivers/iio/humidity/hts221_buffer.c')
-rw-r--r-- | drivers/iio/humidity/hts221_buffer.c | 43 |
1 files changed, 40 insertions, 3 deletions
diff --git a/drivers/iio/humidity/hts221_buffer.c b/drivers/iio/humidity/hts221_buffer.c index 7d19a3da7ab7..9690dfe9a844 100644 --- a/drivers/iio/humidity/hts221_buffer.c +++ b/drivers/iio/humidity/hts221_buffer.c @@ -20,8 +20,16 @@ #include <linux/iio/triggered_buffer.h> #include <linux/iio/buffer.h> +#include <linux/platform_data/st_sensors_pdata.h> + #include "hts221.h" +#define HTS221_REG_DRDY_HL_ADDR 0x22 +#define HTS221_REG_DRDY_HL_MASK BIT(7) +#define HTS221_REG_DRDY_PP_OD_ADDR 0x22 +#define HTS221_REG_DRDY_PP_OD_MASK BIT(6) +#define HTS221_REG_DRDY_EN_ADDR 0x22 +#define HTS221_REG_DRDY_EN_MASK BIT(2) #define HTS221_REG_STATUS_ADDR 0x27 #define HTS221_RH_DRDY_MASK BIT(1) #define HTS221_TEMP_DRDY_MASK BIT(0) @@ -30,8 +38,12 @@ static int hts221_trig_set_state(struct iio_trigger *trig, bool state) { struct iio_dev *iio_dev = iio_trigger_get_drvdata(trig); struct hts221_hw *hw = iio_priv(iio_dev); + int err; + + err = hts221_write_with_mask(hw, HTS221_REG_DRDY_EN_ADDR, + HTS221_REG_DRDY_EN_MASK, state); - return hts221_config_drdy(hw, state); + return err < 0 ? err : 0; } static const struct iio_trigger_ops hts221_trigger_ops = { @@ -67,6 +79,9 @@ static irqreturn_t hts221_trigger_handler_thread(int irq, void *private) int hts221_allocate_trigger(struct hts221_hw *hw) { struct iio_dev *iio_dev = iio_priv_to_dev(hw); + bool irq_active_low = false, open_drain = false; + struct device_node *np = hw->dev->of_node; + struct st_sensors_platform_data *pdata; unsigned long irq_type; int err; @@ -76,6 +91,10 @@ int hts221_allocate_trigger(struct hts221_hw *hw) case IRQF_TRIGGER_HIGH: case IRQF_TRIGGER_RISING: break; + case IRQF_TRIGGER_LOW: + case IRQF_TRIGGER_FALLING: + irq_active_low = true; + break; default: dev_info(hw->dev, "mode %lx unsupported, using IRQF_TRIGGER_RISING\n", @@ -84,6 +103,24 @@ int hts221_allocate_trigger(struct hts221_hw *hw) break; } + err = hts221_write_with_mask(hw, HTS221_REG_DRDY_HL_ADDR, + HTS221_REG_DRDY_HL_MASK, irq_active_low); + if (err < 0) + return err; + + pdata = (struct st_sensors_platform_data *)hw->dev->platform_data; + if ((np && of_property_read_bool(np, "drive-open-drain")) || + (pdata && pdata->open_drain)) { + irq_type |= IRQF_SHARED; + open_drain = true; + } + + err = hts221_write_with_mask(hw, HTS221_REG_DRDY_PP_OD_ADDR, + HTS221_REG_DRDY_PP_OD_MASK, + open_drain); + if (err < 0) + return err; + err = devm_request_threaded_irq(hw->dev, hw->irq, NULL, hts221_trigger_handler_thread, irq_type | IRQF_ONESHOT, @@ -109,12 +146,12 @@ int hts221_allocate_trigger(struct hts221_hw *hw) static int hts221_buffer_preenable(struct iio_dev *iio_dev) { - return hts221_power_on(iio_priv(iio_dev)); + return hts221_set_enable(iio_priv(iio_dev), true); } static int hts221_buffer_postdisable(struct iio_dev *iio_dev) { - return hts221_power_off(iio_priv(iio_dev)); + return hts221_set_enable(iio_priv(iio_dev), false); } static const struct iio_buffer_setup_ops hts221_buffer_ops = { |