[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250918190729.387117-1-akshayaj.lkd@gmail.com>
Date: Fri, 19 Sep 2025 00:37:21 +0530
From: Akshay Jindal <akshayaj.lkd@...il.com>
To: dan@...obertson.com,
jic23@...nel.org,
dlechner@...libre.com,
nuno.sa@...log.com,
andy@...nel.org
Cc: Akshay Jindal <akshayaj.lkd@...il.com>,
shuah@...nel.org,
linux-iio@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: [PATCH] iio: accel: bma400: Refactor generic interrupt configuration
Refactor the generic interrupt configuration logic to improve readability
and reduce repetitive code. Replace hard-coded register values with macros
and enums, making it clearer what configuration is written to hardware.
Introduce a const struct to map event direction to the corresponding
generic interrupt. This removes the need for switch statements in multiple
callbacks, including activity event setup, read_event_value, and
write_event_value, while still performing the selection at runtime.
This change has no functional impact but simplifies the code and makes it
easier to maintain and extend in future updates.
Signed-off-by: Akshay Jindal <akshayaj.lkd@...il.com>
---
drivers/iio/accel/bma400.h | 71 +++++++++++++++---
drivers/iio/accel/bma400_core.c | 128 ++++++++++++++++----------------
2 files changed, 125 insertions(+), 74 deletions(-)
diff --git a/drivers/iio/accel/bma400.h b/drivers/iio/accel/bma400.h
index 932358b45f17..ab7d1d139b66 100644
--- a/drivers/iio/accel/bma400.h
+++ b/drivers/iio/accel/bma400.h
@@ -68,7 +68,19 @@
#define BMA400_CMD_REG 0x7e
/* Interrupt registers */
-#define BMA400_INT_CONFIG0_REG 0x1f
+#define BMA400_INT_CONFIG0_REG 0x1f
+#define BMA400_INT_CONFIG0_ORTN_CHG_MASK BIT(1)
+#define BMA400_INT_CONFIG0_GEN1_MASK BIT(2)
+#define BMA400_INT_CONFIG0_GEN2_MASK BIT(3)
+#define BMA400_INT_CONFIG0_FIFO_FULL_MASK BIT(5)
+#define BMA400_INT_CONFIG0_FIFO_WTRMRK_MASK BIT(6)
+#define BMA400_INT_CONFIG0_DRDY_MASK BIT(7)
+
+enum generic_intr {
+ GEN1_INTR,
+ GEN2_INTR
+};
+
#define BMA400_INT_CONFIG1_REG 0x20
#define BMA400_INT1_MAP_REG 0x21
#define BMA400_INT_IO_CTRL_REG 0x24
@@ -96,15 +108,53 @@
#define BMA400_ACC_ODR_MIN_HZ 12
/* Generic interrupts register */
-#define BMA400_GEN1INT_CONFIG0 0x3f
-#define BMA400_GEN2INT_CONFIG0 0x4A
-#define BMA400_GEN_CONFIG1_OFF 0x01
-#define BMA400_GEN_CONFIG2_OFF 0x02
-#define BMA400_GEN_CONFIG3_OFF 0x03
-#define BMA400_GEN_CONFIG31_OFF 0x04
-#define BMA400_INT_GEN1_MSK BIT(2)
-#define BMA400_INT_GEN2_MSK BIT(3)
-#define BMA400_GEN_HYST_MSK GENMASK(1, 0)
+#define BMA400_GENINT_CONFIG_REG_BASE 0x3f
+#define BMA400_NUM_GENINT_CONFIG_REGS 11
+#define BMA400_GENINT_CONFIG_REG(gen_intr, config_idx) \
+ (BMA400_GENINT_CONFIG_REG_BASE + \
+ (gen_intr) * BMA400_NUM_GENINT_CONFIG_REGS + \
+ (config_idx))
+
+/* Generic Interrupt Config0 register */
+#define BMA400_GENINT_CONFIG0_HYST_MASK GENMASK(1, 0)
+#define BMA400_GENINT_CONFIG0_REF_UPD_MODE_MASK GENMASK(3, 2)
+#define BMA400_GENINT_CONFIG0_DATA_SRC_MASK BIT(4)
+#define BMA400_GENINT_CONFIG0_X_EN_MASK BIT(5)
+#define BMA400_GENINT_CONFIG0_Y_EN_MASK BIT(6)
+#define BMA400_GENINT_CONFIG0_Z_EN_MASK BIT(7)
+
+enum bma400_hysteresis_config {
+ NO_HYSTERESIS,
+ HYSTERESIS_24MG,
+ HYSTERESIS_48MG,
+ HYSTERESIS_96MG
+};
+
+enum bma400_accel_data_src {
+ ACCEL_FILT1,
+ ACCEL_FILT2
+};
+
+enum bma400_ref_updt_mode {
+ BMA400_REF_MANUAL_UPDT_MODE,
+ BMA400_REF_ONETIME_UPDT_MODE,
+ BMA400_REF_EVERYTIME_UPDT_MODE,
+ BMA400_REF_EVERYTIME_LP_UPDT_MODE
+};
+
+/* Generic Interrupt Config1 register */
+#define BMA400_GENINT_CONFIG1_AXES_COMB_MASK BIT(0)
+#define BMA400_GENINT_CONFIG1_DETCT_CRIT_MASK BIT(1)
+
+enum bma400_genintr_acceleval_axescomb {
+ BMA400_EVAL_X_OR_Y_OR_Z,
+ BMA400_EVAL_X_AND_Y_AND_Z,
+};
+
+enum bma400_detect_criterion {
+ BMA400_DETECT_INACTIVITY,
+ BMA400_DETECT_ACTIVITY,
+};
/* TAP config registers */
#define BMA400_TAP_CONFIG 0x57
@@ -119,6 +169,7 @@
#define BMA400_TAP_QUIETDT_MSK GENMASK(5, 4)
#define BMA400_TAP_TIM_LIST_LEN 4
+
/*
* BMA400_SCALE_MIN macro value represents m/s^2 for 1 LSB before
* converting to micro values for +-2g range.
diff --git a/drivers/iio/accel/bma400_core.c b/drivers/iio/accel/bma400_core.c
index 85e23badf733..d59c26b8a57f 100644
--- a/drivers/iio/accel/bma400_core.c
+++ b/drivers/iio/accel/bma400_core.c
@@ -121,6 +121,29 @@ struct bma400_data {
__be16 duration;
};
+struct bma400_genintr_info {
+ u8 genintr;
+ unsigned int intrmask;
+ enum iio_event_direction dir;
+ enum bma400_detect_criterion detect_mode;
+};
+
+/* Lookup struct for determining GEN1/GEN2 based on dir */
+static const struct bma400_genintr_info bma400_genintrs[] = {
+ [IIO_EV_DIR_RISING] = {
+ .genintr = GEN1_INTR, /* 0 for GEN1 */
+ .intrmask = BMA400_INT_CONFIG0_GEN1_MASK,
+ .dir = IIO_EV_DIR_RISING,
+ .detect_mode = BMA400_DETECT_ACTIVITY,
+ },
+ [IIO_EV_DIR_FALLING] = {
+ .genintr = GEN2_INTR, /* 1 for GEN2 */
+ .intrmask = BMA400_INT_CONFIG0_GEN2_MASK,
+ .dir = IIO_EV_DIR_FALLING,
+ .detect_mode = BMA400_DETECT_INACTIVITY,
+ }
+};
+
static bool bma400_is_writable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
@@ -1114,10 +1137,10 @@ static int bma400_read_event_config(struct iio_dev *indio_dev,
case IIO_ACCEL:
switch (dir) {
case IIO_EV_DIR_RISING:
- return FIELD_GET(BMA400_INT_GEN1_MSK,
+ return FIELD_GET(BMA400_INT_CONFIG0_GEN1_MASK,
data->generic_event_en);
case IIO_EV_DIR_FALLING:
- return FIELD_GET(BMA400_INT_GEN2_MSK,
+ return FIELD_GET(BMA400_INT_CONFIG0_GEN2_MASK,
data->generic_event_en);
case IIO_EV_DIR_SINGLETAP:
return FIELD_GET(BMA400_S_TAP_MSK,
@@ -1159,59 +1182,50 @@ static int bma400_activity_event_en(struct bma400_data *data,
enum iio_event_direction dir,
int state)
{
- int ret, reg, msk, value;
- int field_value = 0;
-
- switch (dir) {
- case IIO_EV_DIR_RISING:
- reg = BMA400_GEN1INT_CONFIG0;
- msk = BMA400_INT_GEN1_MSK;
- value = 2;
- set_mask_bits(&field_value, BMA400_INT_GEN1_MSK,
- FIELD_PREP(BMA400_INT_GEN1_MSK, state));
- break;
- case IIO_EV_DIR_FALLING:
- reg = BMA400_GEN2INT_CONFIG0;
- msk = BMA400_INT_GEN2_MSK;
- value = 0;
- set_mask_bits(&field_value, BMA400_INT_GEN2_MSK,
- FIELD_PREP(BMA400_INT_GEN2_MSK, state));
- break;
- default:
- return -EINVAL;
- }
+ int ret, regval;
+ u8 genintr = bma400_genintrs[dir].genintr;
+ u8 detect_criterion = bma400_genintrs[dir].detect_mode;
+ unsigned int intrmask = bma400_genintrs[dir].intrmask;
/* Enabling all axis for interrupt evaluation */
- ret = regmap_write(data->regmap, reg, 0xF8);
+ ret = regmap_write(data->regmap, BMA400_GENINT_CONFIG_REG(genintr, 0),
+ BMA400_GENINT_CONFIG0_X_EN_MASK |
+ BMA400_GENINT_CONFIG0_Y_EN_MASK |
+ BMA400_GENINT_CONFIG0_Z_EN_MASK|
+ BMA400_REF_EVERYTIME_UPDT_MODE);
if (ret)
return ret;
/* OR combination of all axis for interrupt evaluation */
- ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG1_OFF, value);
+ regval = FIELD_PREP(BMA400_GENINT_CONFIG1_AXES_COMB_MASK, BMA400_EVAL_X_OR_Y_OR_Z) |
+ FIELD_PREP(BMA400_GENINT_CONFIG1_DETCT_CRIT_MASK, detect_criterion);
+ ret = regmap_write(data->regmap, BMA400_GENINT_CONFIG_REG(genintr, 1), regval);
if (ret)
return ret;
/* Initial value to avoid interrupts while enabling*/
- ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG2_OFF, 0x0A);
+ ret = regmap_write(data->regmap, BMA400_GENINT_CONFIG_REG(genintr, 2), 0x0A);
if (ret)
return ret;
/* Initial duration value to avoid interrupts while enabling*/
- ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG31_OFF, 0x0F);
+ ret = regmap_write(data->regmap, BMA400_GENINT_CONFIG_REG(genintr, 4), 0x0F);
if (ret)
return ret;
- ret = regmap_update_bits(data->regmap, BMA400_INT1_MAP_REG, msk,
- field_value);
+ regval = FIELD_PREP(BMA400_INT_CONFIG0_GEN1_MASK, state);
+ if (genintr)
+ regval = FIELD_PREP(BMA400_INT_CONFIG0_GEN2_MASK, state);
+
+ ret = regmap_update_bits(data->regmap, BMA400_INT1_MAP_REG, intrmask, regval);
if (ret)
return ret;
- ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG0_REG, msk,
- field_value);
+ ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG0_REG, intrmask, regval);
if (ret)
return ret;
- set_mask_bits(&data->generic_event_en, msk, field_value);
+ set_mask_bits(&data->generic_event_en, intrmask, regval);
return 0;
}
@@ -1336,18 +1350,6 @@ static int bma400_write_event_config(struct iio_dev *indio_dev,
}
}
-static int get_gen_config_reg(enum iio_event_direction dir)
-{
- switch (dir) {
- case IIO_EV_DIR_FALLING:
- return BMA400_GEN2INT_CONFIG0;
- case IIO_EV_DIR_RISING:
- return BMA400_GEN1INT_CONFIG0;
- default:
- return -EINVAL;
- }
-}
-
static int bma400_read_event_value(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
@@ -1356,22 +1358,20 @@ static int bma400_read_event_value(struct iio_dev *indio_dev,
int *val, int *val2)
{
struct bma400_data *data = iio_priv(indio_dev);
- int ret, reg, reg_val, raw;
+ int ret, genintr, reg_val, raw;
if (chan->type != IIO_ACCEL)
return -EINVAL;
switch (type) {
case IIO_EV_TYPE_MAG:
- reg = get_gen_config_reg(dir);
- if (reg < 0)
- return -EINVAL;
+ genintr = bma400_genintrs[dir].genintr;
*val2 = 0;
switch (info) {
case IIO_EV_INFO_VALUE:
ret = regmap_read(data->regmap,
- reg + BMA400_GEN_CONFIG2_OFF,
+ BMA400_GENINT_CONFIG_REG(genintr, 2),
val);
if (ret)
return ret;
@@ -1379,7 +1379,7 @@ static int bma400_read_event_value(struct iio_dev *indio_dev,
case IIO_EV_INFO_PERIOD:
mutex_lock(&data->mutex);
ret = regmap_bulk_read(data->regmap,
- reg + BMA400_GEN_CONFIG3_OFF,
+ BMA400_GENINT_CONFIG_REG(genintr, 3),
&data->duration,
sizeof(data->duration));
if (ret) {
@@ -1390,10 +1390,12 @@ static int bma400_read_event_value(struct iio_dev *indio_dev,
mutex_unlock(&data->mutex);
return IIO_VAL_INT;
case IIO_EV_INFO_HYSTERESIS:
- ret = regmap_read(data->regmap, reg, val);
+ ret = regmap_read(data->regmap,
+ BMA400_GENINT_CONFIG_REG(genintr, 0),
+ val);
if (ret)
return ret;
- *val = FIELD_GET(BMA400_GEN_HYST_MSK, *val);
+ *val = FIELD_GET(BMA400_GENINT_CONFIG0_HYST_MASK, *val);
return IIO_VAL_INT;
default:
return -EINVAL;
@@ -1444,16 +1446,14 @@ static int bma400_write_event_value(struct iio_dev *indio_dev,
int val, int val2)
{
struct bma400_data *data = iio_priv(indio_dev);
- int reg, ret, raw;
+ int genintr, ret, raw;
if (chan->type != IIO_ACCEL)
return -EINVAL;
switch (type) {
case IIO_EV_TYPE_MAG:
- reg = get_gen_config_reg(dir);
- if (reg < 0)
- return -EINVAL;
+ genintr = bma400_genintrs[dir].genintr;
switch (info) {
case IIO_EV_INFO_VALUE:
@@ -1461,7 +1461,7 @@ static int bma400_write_event_value(struct iio_dev *indio_dev,
return -EINVAL;
return regmap_write(data->regmap,
- reg + BMA400_GEN_CONFIG2_OFF,
+ BMA400_GENINT_CONFIG_REG(genintr, 2),
val);
case IIO_EV_INFO_PERIOD:
if (val < 1 || val > 65535)
@@ -1470,7 +1470,7 @@ static int bma400_write_event_value(struct iio_dev *indio_dev,
mutex_lock(&data->mutex);
put_unaligned_be16(val, &data->duration);
ret = regmap_bulk_write(data->regmap,
- reg + BMA400_GEN_CONFIG3_OFF,
+ BMA400_GENINT_CONFIG_REG(genintr, 3),
&data->duration,
sizeof(data->duration));
mutex_unlock(&data->mutex);
@@ -1479,10 +1479,10 @@ static int bma400_write_event_value(struct iio_dev *indio_dev,
if (val < 0 || val > 3)
return -EINVAL;
- return regmap_update_bits(data->regmap, reg,
- BMA400_GEN_HYST_MSK,
- FIELD_PREP(BMA400_GEN_HYST_MSK,
- val));
+ return regmap_update_bits(data->regmap,
+ BMA400_GENINT_CONFIG_REG(genintr, 0),
+ BMA400_GENINT_CONFIG0_HYST_MASK,
+ FIELD_PREP(BMA400_GENINT_CONFIG0_HYST_MASK, val));
default:
return -EINVAL;
}
@@ -1650,10 +1650,10 @@ static irqreturn_t bma400_interrupt(int irq, void *private)
IIO_EV_DIR_DOUBLETAP),
timestamp);
- if (FIELD_GET(BMA400_INT_GEN1_MSK, le16_to_cpu(data->status)))
+ if (FIELD_GET(BMA400_INT_CONFIG0_GEN1_MASK, le16_to_cpu(data->status)))
ev_dir = IIO_EV_DIR_RISING;
- if (FIELD_GET(BMA400_INT_GEN2_MSK, le16_to_cpu(data->status)))
+ if (FIELD_GET(BMA400_INT_CONFIG0_GEN2_MASK, le16_to_cpu(data->status)))
ev_dir = IIO_EV_DIR_FALLING;
if (ev_dir != IIO_EV_DIR_NONE) {
--
2.43.0
Powered by blists - more mailing lists