summaryrefslogtreecommitdiffstats
path: root/drivers/iio
diff options
context:
space:
mode:
authorStephen Boyd <swboyd@chromium.org>2020-10-06 18:17:33 -0700
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2020-10-10 17:38:37 +0100
commit1b6872015f0b96e6800c1a321b45d581aba9381b (patch)
treebe059b2539392ce14359b306a14477859f614ea3 /drivers/iio
parent08f0411c48f27703f0db2bd287890fdedf5bef5e (diff)
iio: sx9310: Support setting debounce values
The rising and falling directions can be debounced in the hardware as "close" and "far" debounce settings. Add support for these as rising and falling debounce settings. Signed-off-by: Stephen Boyd <swboyd@chromium.org> Cc: Daniel Campello <campello@chromium.org> Cc: Lars-Peter Clausen <lars@metafoo.de> Cc: Peter Meerwald-Stadler <pmeerw@pmeerw.net> Cc: Douglas Anderson <dianders@chromium.org> Cc: Gwendal Grignou <gwendal@chromium.org> Cc: Evan Green <evgreen@chromium.org> Link: https://lore.kernel.org/r/20201007011735.1346994-5-swboyd@chromium.org Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'drivers/iio')
-rw-r--r--drivers/iio/proximity/sx9310.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/drivers/iio/proximity/sx9310.c b/drivers/iio/proximity/sx9310.c
index 940c415ece6b..1809940563b1 100644
--- a/drivers/iio/proximity/sx9310.c
+++ b/drivers/iio/proximity/sx9310.c
@@ -77,6 +77,8 @@
#define SX9310_REG_PROX_CTRL10 0x1a
#define SX9310_REG_PROX_CTRL10_HYST_MASK GENMASK(5, 4)
#define SX9310_REG_PROX_CTRL10_HYST_6PCT (0x01 << 4)
+#define SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK GENMASK(3, 2)
+#define SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK GENMASK(1, 0)
#define SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_2 0x01
#define SX9310_REG_PROX_CTRL11 0x1b
#define SX9310_REG_PROX_CTRL12 0x1c
@@ -149,6 +151,16 @@ struct sx9310_data {
static const struct iio_event_spec sx9310_events[] = {
{
.type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_RISING,
+ .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD),
+ },
+ {
+ .type = IIO_EV_TYPE_THRESH,
+ .dir = IIO_EV_DIR_FALLING,
+ .mask_shared_by_all = BIT(IIO_EV_INFO_PERIOD),
+ },
+ {
+ .type = IIO_EV_TYPE_THRESH,
.dir = IIO_EV_DIR_EITHER,
.mask_separate = BIT(IIO_EV_INFO_ENABLE) |
BIT(IIO_EV_INFO_HYSTERESIS) |
@@ -601,6 +613,42 @@ static int sx9310_read_hysteresis(struct sx9310_data *data,
return IIO_VAL_INT;
}
+static int sx9310_read_far_debounce(struct sx9310_data *data, int *val)
+{
+ unsigned int regval;
+ int ret;
+
+ ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL10, &regval);
+ if (ret)
+ return ret;
+
+ regval = FIELD_GET(SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK, regval);
+ if (regval)
+ *val = 1 << regval;
+ else
+ *val = 0;
+
+ return IIO_VAL_INT;
+}
+
+static int sx9310_read_close_debounce(struct sx9310_data *data, int *val)
+{
+ unsigned int regval;
+ int ret;
+
+ ret = regmap_read(data->regmap, SX9310_REG_PROX_CTRL10, &regval);
+ if (ret)
+ return ret;
+
+ regval = FIELD_GET(SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK, regval);
+ if (regval)
+ *val = 1 << regval;
+ else
+ *val = 0;
+
+ return IIO_VAL_INT;
+}
+
static int sx9310_read_event_val(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
@@ -615,6 +663,15 @@ static int sx9310_read_event_val(struct iio_dev *indio_dev,
switch (info) {
case IIO_EV_INFO_VALUE:
return sx9310_read_thresh(data, chan, val);
+ case IIO_EV_INFO_PERIOD:
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ return sx9310_read_far_debounce(data, val);
+ case IIO_EV_DIR_FALLING:
+ return sx9310_read_close_debounce(data, val);
+ default:
+ return -EINVAL;
+ }
case IIO_EV_INFO_HYSTERESIS:
return sx9310_read_hysteresis(data, chan, val);
default:
@@ -682,6 +739,40 @@ static int sx9310_write_hysteresis(struct sx9310_data *data,
return ret;
}
+static int sx9310_write_far_debounce(struct sx9310_data *data, int val)
+{
+ int ret;
+ unsigned int regval;
+
+ val = ilog2(val);
+ regval = FIELD_PREP(SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK, val);
+
+ mutex_lock(&data->mutex);
+ ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL10,
+ SX9310_REG_PROX_CTRL10_FAR_DEBOUNCE_MASK,
+ regval);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
+static int sx9310_write_close_debounce(struct sx9310_data *data, int val)
+{
+ int ret;
+ unsigned int regval;
+
+ val = ilog2(val);
+ regval = FIELD_PREP(SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK, val);
+
+ mutex_lock(&data->mutex);
+ ret = regmap_update_bits(data->regmap, SX9310_REG_PROX_CTRL10,
+ SX9310_REG_PROX_CTRL10_CLOSE_DEBOUNCE_MASK,
+ regval);
+ mutex_unlock(&data->mutex);
+
+ return ret;
+}
+
static int sx9310_write_event_val(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
@@ -696,6 +787,15 @@ static int sx9310_write_event_val(struct iio_dev *indio_dev,
switch (info) {
case IIO_EV_INFO_VALUE:
return sx9310_write_thresh(data, chan, val);
+ case IIO_EV_INFO_PERIOD:
+ switch (dir) {
+ case IIO_EV_DIR_RISING:
+ return sx9310_write_far_debounce(data, val);
+ case IIO_EV_DIR_FALLING:
+ return sx9310_write_close_debounce(data, val);
+ default:
+ return -EINVAL;
+ }
case IIO_EV_INFO_HYSTERESIS:
return sx9310_write_hysteresis(data, chan, val);
default: