iio: humidity: hts221: support open drain mode
authorLorenzo Bianconi <lorenzo.bianconi83@gmail.com>
Mon, 17 Jul 2017 17:39:03 +0000 (19:39 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Tue, 25 Jul 2017 19:00:47 +0000 (20:00 +0100)
Add open drain support in order to share requested IRQ line between
hts221 device and other peripherals

Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@st.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/humidity/hts221_buffer.c

index ad5222295b2ce9b0c70be47e467a38b39766b018..f29f01a22375bc1c581741696d193493651d10f7 100644 (file)
 #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_STATUS_ADDR         0x27
 #define HTS221_RH_DRDY_MASK            BIT(1)
 #define HTS221_TEMP_DRDY_MASK          BIT(0)
@@ -69,7 +73,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;
+       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;
 
@@ -95,6 +101,20 @@ int hts221_allocate_trigger(struct hts221_hw *hw)
                                     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,