]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
iio: accel: adxl372: introduce chip_info structure
authorAntoniu Miclaus <antoniu.miclaus@analog.com>
Sat, 21 Mar 2026 10:04:56 +0000 (12:04 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sat, 21 Mar 2026 11:19:02 +0000 (11:19 +0000)
Introduce a chip_info structure to parameterize device-specific
properties such as ODR/bandwidth frequency tables, activity/inactivity
timer scale factors, and the maximum ODR value. This refactors the
driver to use chip_info lookups instead of hardcoded values, preparing
the driver to support multiple device variants.

The sampling_frequency and filter_low_pass_3db_frequency available
attributes are switched from custom sysfs callbacks to read_avail()
based handling via info_mask_shared_by_type_available. This enforces
consistent formatting through the IIO framework and makes the values
accessible to in-kernel consumers.

The SPI/I2C probe functions are updated to pass a chip_info pointer
instead of a device name string.

No functional change intended.

Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/accel/adxl372.c
drivers/iio/accel/adxl372.h
drivers/iio/accel/adxl372_i2c.c
drivers/iio/accel/adxl372_spi.c

index 6763f8ed9f7f1c393db1e5b64b8da9e886ef7bb0..1592b25ecb2c891833d0a5d050aea5e11c1f190e 100644 (file)
@@ -181,6 +181,7 @@ enum adxl372_odr {
        ADXL372_ODR_1600HZ,
        ADXL372_ODR_3200HZ,
        ADXL372_ODR_6400HZ,
+       ADXL372_ODR_NUM
 };
 
 enum adxl372_bandwidth {
@@ -215,14 +216,35 @@ enum adxl372_fifo_mode {
        ADXL372_FIFO_OLD_SAVED
 };
 
-static const int adxl372_samp_freq_tbl[5] = {
-       400, 800, 1600, 3200, 6400,
+static const int adxl372_samp_freq_tbl[ADXL372_ODR_NUM] = {
+       [ADXL372_ODR_400HZ] = 400,
+       [ADXL372_ODR_800HZ] = 800,
+       [ADXL372_ODR_1600HZ] = 1600,
+       [ADXL372_ODR_3200HZ] = 3200,
+       [ADXL372_ODR_6400HZ] = 6400,
 };
 
-static const int adxl372_bw_freq_tbl[5] = {
-       200, 400, 800, 1600, 3200,
+static const int adxl372_bw_freq_tbl[ADXL372_ODR_NUM] = {
+       [ADXL372_BW_200HZ] = 200,
+       [ADXL372_BW_400HZ] = 400,
+       [ADXL372_BW_800HZ] = 800,
+       [ADXL372_BW_1600HZ] = 1600,
+       [ADXL372_BW_3200HZ] = 3200,
 };
 
+const struct adxl372_chip_info adxl372_chip_info = {
+       .name = "adxl372",
+       .samp_freq_tbl = adxl372_samp_freq_tbl,
+       .bw_freq_tbl = adxl372_bw_freq_tbl,
+       .num_freqs = ARRAY_SIZE(adxl372_samp_freq_tbl),
+       .act_time_scale_us = 3300,
+       .act_time_scale_low_us = 6600,
+       .inact_time_scale_ms = 13,
+       .inact_time_scale_low_ms = 26,
+       .max_odr = ADXL372_ODR_6400HZ,
+};
+EXPORT_SYMBOL_NS_GPL(adxl372_chip_info, "IIO_ADXL372");
+
 struct adxl372_axis_lookup {
        unsigned int bits;
        enum adxl372_fifo_format fifo_format;
@@ -258,8 +280,12 @@ static const struct iio_event_spec adxl372_events[] = {
        .modified = 1,                                                  \
        .channel2 = IIO_MOD_##axis,                                     \
        .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),                   \
-       .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |          \
-                                   BIT(IIO_CHAN_INFO_SAMP_FREQ) |      \
+       .info_mask_shared_by_type =                                     \
+               BIT(IIO_CHAN_INFO_SCALE) |                              \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ) |                          \
+               BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),       \
+       .info_mask_shared_by_type_available =                           \
+               BIT(IIO_CHAN_INFO_SAMP_FREQ) |                          \
                BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY),       \
        .scan_index = index,                                            \
        .scan_type = {                                                  \
@@ -280,6 +306,7 @@ static const struct iio_chan_spec adxl372_channels[] = {
 };
 
 struct adxl372_state {
+       const struct adxl372_chip_info  *chip_info;
        int                             irq;
        struct device                   *dev;
        struct regmap                   *regmap;
@@ -468,13 +495,14 @@ static int adxl372_set_activity_time_ms(struct adxl372_state *st,
        int ret;
 
        /*
-        * 3.3 ms per code is the scale factor of the TIME_ACT register for
-        * ODR = 6400 Hz. It is 6.6 ms per code for ODR = 3200 Hz and below.
+        * The scale factor of the TIME_ACT register depends on the ODR.
+        * A higher scale factor is used at the maximum ODR and a lower
+        * one at all other rates.
         */
-       if (st->odr == ADXL372_ODR_6400HZ)
-               scale_factor = 3300;
+       if (st->odr == st->chip_info->max_odr)
+               scale_factor = st->chip_info->act_time_scale_us;
        else
-               scale_factor = 6600;
+               scale_factor = st->chip_info->act_time_scale_low_us;
 
        reg_val = DIV_ROUND_CLOSEST(act_time_ms * 1000, scale_factor);
 
@@ -498,13 +526,14 @@ static int adxl372_set_inactivity_time_ms(struct adxl372_state *st,
        int ret;
 
        /*
-        * 13 ms per code is the scale factor of the TIME_INACT register for
-        * ODR = 6400 Hz. It is 26 ms per code for ODR = 3200 Hz and below.
+        * The scale factor of the TIME_INACT register depends on the ODR.
+        * A higher scale factor is used at the maximum ODR and a lower
+        * one at all other rates.
         */
-       if (st->odr == ADXL372_ODR_6400HZ)
-               scale_factor = 13;
+       if (st->odr == st->chip_info->max_odr)
+               scale_factor = st->chip_info->inact_time_scale_ms;
        else
-               scale_factor = 26;
+               scale_factor = st->chip_info->inact_time_scale_low_ms;
 
        res = DIV_ROUND_CLOSEST(inact_time_ms, scale_factor);
        reg_val_h = (res >> 8) & 0xFF;
@@ -714,7 +743,7 @@ static int adxl372_setup(struct adxl372_state *st)
        if (ret < 0)
                return ret;
 
-       ret = adxl372_set_odr(st, ADXL372_ODR_6400HZ);
+       ret = adxl372_set_odr(st, st->chip_info->max_odr);
        if (ret < 0)
                return ret;
 
@@ -774,10 +803,10 @@ static int adxl372_read_raw(struct iio_dev *indio_dev,
                *val2 = ADXL372_USCALE;
                return IIO_VAL_INT_PLUS_MICRO;
        case IIO_CHAN_INFO_SAMP_FREQ:
-               *val = adxl372_samp_freq_tbl[st->odr];
+               *val = st->chip_info->samp_freq_tbl[st->odr];
                return IIO_VAL_INT;
        case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
-               *val = adxl372_bw_freq_tbl[st->bw];
+               *val = st->chip_info->bw_freq_tbl[st->bw];
                return IIO_VAL_INT;
        }
 
@@ -793,23 +822,17 @@ static int adxl372_write_raw(struct iio_dev *indio_dev,
 
        switch (info) {
        case IIO_CHAN_INFO_SAMP_FREQ:
-               odr_index = adxl372_find_closest_match(adxl372_samp_freq_tbl,
-                                       ARRAY_SIZE(adxl372_samp_freq_tbl),
-                                       val);
+               odr_index = adxl372_find_closest_match(st->chip_info->samp_freq_tbl,
+                                                      st->chip_info->num_freqs,
+                                                      val);
                ret = adxl372_set_odr(st, odr_index);
                if (ret < 0)
                        return ret;
-               /*
-                * The timer period depends on the ODR selected.
-                * At 3200 Hz and below, it is 6.6 ms; at 6400 Hz, it is 3.3 ms
-                */
+               /* Recalculate activity time as the timer period depends on ODR */
                ret = adxl372_set_activity_time_ms(st, st->act_time_ms);
                if (ret < 0)
                        return ret;
-               /*
-                * The timer period depends on the ODR selected.
-                * At 3200 Hz and below, it is 26 ms; at 6400 Hz, it is 13 ms
-                */
+               /* Recalculate inactivity time as the timer period depends on ODR */
                ret = adxl372_set_inactivity_time_ms(st, st->inact_time_ms);
                if (ret < 0)
                        return ret;
@@ -822,9 +845,9 @@ static int adxl372_write_raw(struct iio_dev *indio_dev,
 
                return ret;
        case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
-               bw_index = adxl372_find_closest_match(adxl372_bw_freq_tbl,
-                                       ARRAY_SIZE(adxl372_bw_freq_tbl),
-                                       val);
+               bw_index = adxl372_find_closest_match(st->chip_info->bw_freq_tbl,
+                                                     st->chip_info->num_freqs,
+                                                     val);
                return adxl372_set_bandwidth(st, bw_index);
        default:
                return -EINVAL;
@@ -954,24 +977,6 @@ static int adxl372_write_event_config(struct iio_dev *indio_dev, const struct ii
        return adxl372_set_interrupts(st, st->int1_bitmask, 0);
 }
 
-static ssize_t adxl372_show_filter_freq_avail(struct device *dev,
-                                             struct device_attribute *attr,
-                                             char *buf)
-{
-       struct iio_dev *indio_dev = dev_to_iio_dev(dev);
-       struct adxl372_state *st = iio_priv(indio_dev);
-       int i;
-       size_t len = 0;
-
-       for (i = 0; i <= st->odr; i++)
-               len += scnprintf(buf + len, PAGE_SIZE - len,
-                                "%d ", adxl372_bw_freq_tbl[i]);
-
-       buf[len - 1] = '\n';
-
-       return len;
-}
-
 static ssize_t adxl372_get_fifo_enabled(struct device *dev,
                                          struct device_attribute *attr,
                                          char *buf)
@@ -1139,25 +1144,38 @@ static const struct iio_trigger_ops adxl372_peak_data_trigger_ops = {
        .set_trigger_state = adxl372_peak_dready_trig_set_state,
 };
 
-static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("400 800 1600 3200 6400");
-static IIO_DEVICE_ATTR(in_accel_filter_low_pass_3db_frequency_available,
-                      0444, adxl372_show_filter_freq_avail, NULL, 0);
-
-static struct attribute *adxl372_attributes[] = {
-       &iio_const_attr_sampling_frequency_available.dev_attr.attr,
-       &iio_dev_attr_in_accel_filter_low_pass_3db_frequency_available.dev_attr.attr,
-       NULL,
-};
+static int adxl372_read_avail(struct iio_dev *indio_dev,
+                             struct iio_chan_spec const *chan,
+                             const int **vals, int *type, int *length,
+                             long mask)
+{
+       struct adxl372_state *st = iio_priv(indio_dev);
 
-static const struct attribute_group adxl372_attrs_group = {
-       .attrs = adxl372_attributes,
-};
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               *vals = st->chip_info->samp_freq_tbl;
+               *type = IIO_VAL_INT;
+               *length = st->chip_info->num_freqs;
+               return IIO_AVAIL_LIST;
+       case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY:
+               *vals = st->chip_info->bw_freq_tbl;
+               *type = IIO_VAL_INT;
+               /*
+                * Bandwidth cannot exceed half the sampling frequency
+                * (Nyquist), so limit available values based on current ODR.
+                */
+               *length = st->odr + 1;
+               return IIO_AVAIL_LIST;
+       default:
+               return -EINVAL;
+       }
+}
 
 static const struct iio_info adxl372_info = {
        .validate_trigger = &adxl372_validate_trigger,
-       .attrs = &adxl372_attrs_group,
        .read_raw = adxl372_read_raw,
        .write_raw = adxl372_write_raw,
+       .read_avail = adxl372_read_avail,
        .read_event_config = adxl372_read_event_config,
        .write_event_config = adxl372_write_event_config,
        .read_event_value = adxl372_read_event_value,
@@ -1173,7 +1191,7 @@ bool adxl372_readable_noinc_reg(struct device *dev, unsigned int reg)
 EXPORT_SYMBOL_NS_GPL(adxl372_readable_noinc_reg, "IIO_ADXL372");
 
 int adxl372_probe(struct device *dev, struct regmap *regmap,
-                 int irq, const char *name)
+                 int irq, const struct adxl372_chip_info *chip_info)
 {
        struct iio_dev *indio_dev;
        struct adxl372_state *st;
@@ -1189,13 +1207,14 @@ int adxl372_probe(struct device *dev, struct regmap *regmap,
        st->dev = dev;
        st->regmap = regmap;
        st->irq = irq;
+       st->chip_info = chip_info;
 
        mutex_init(&st->threshold_m);
 
        indio_dev->channels = adxl372_channels;
        indio_dev->num_channels = ARRAY_SIZE(adxl372_channels);
        indio_dev->available_scan_masks = adxl372_channel_masks;
-       indio_dev->name = name;
+       indio_dev->name = chip_info->name;
        indio_dev->info = &adxl372_info;
        indio_dev->modes = INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE;
 
index 80a0aa9714fc0691f071e3a46ccbe96baffdc97f..3ce06609446cfdd6550ba652907c34bad99050db 100644 (file)
 
 #define ADXL372_REVID  0x03
 
+struct adxl372_chip_info {
+       const char *name;
+       const int *samp_freq_tbl;
+       const int *bw_freq_tbl;
+       unsigned int num_freqs;
+       unsigned int act_time_scale_us;
+       unsigned int act_time_scale_low_us;
+       unsigned int inact_time_scale_ms;
+       unsigned int inact_time_scale_low_ms;
+       unsigned int max_odr;
+};
+
+extern const struct adxl372_chip_info adxl372_chip_info;
+
 int adxl372_probe(struct device *dev, struct regmap *regmap,
-                 int irq, const char *name);
+                 int irq, const struct adxl372_chip_info *chip_info);
 bool adxl372_readable_noinc_reg(struct device *dev, unsigned int reg);
 
 #endif /* _ADXL372_H_ */
index 186d4fe9a556a0713bfa3c22c06ca1a4ea427678..5d135b1150c8c0ec4f021794353f7aeed4db2721 100644 (file)
@@ -20,11 +20,13 @@ static const struct regmap_config adxl372_regmap_config = {
 
 static int adxl372_i2c_probe(struct i2c_client *client)
 {
-       const struct i2c_device_id *id = i2c_client_get_device_id(client);
+       const struct adxl372_chip_info *chip_info;
        struct regmap *regmap;
        unsigned int regval;
        int ret;
 
+       chip_info = i2c_get_match_data(client);
+
        regmap = devm_regmap_init_i2c(client, &adxl372_regmap_config);
        if (IS_ERR(regmap))
                return PTR_ERR(regmap);
@@ -38,17 +40,17 @@ static int adxl372_i2c_probe(struct i2c_client *client)
                dev_warn(&client->dev,
                "I2C might not work properly with other devices on the bus");
 
-       return adxl372_probe(&client->dev, regmap, client->irq, id->name);
+       return adxl372_probe(&client->dev, regmap, client->irq, chip_info);
 }
 
 static const struct i2c_device_id adxl372_i2c_id[] = {
-       { "adxl372" },
+       { "adxl372", (kernel_ulong_t)&adxl372_chip_info },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, adxl372_i2c_id);
 
 static const struct of_device_id adxl372_of_match[] = {
-       { .compatible = "adi,adxl372" },
+       { .compatible = "adi,adxl372", .data = &adxl372_chip_info },
        { }
 };
 MODULE_DEVICE_TABLE(of, adxl372_of_match);
index 39941b519c3bba7b46b1ebd3a3a9d0fb04ced891..e96a355bfe6752e62e5a200fb52db5cb7b13aeb4 100644 (file)
@@ -22,24 +22,26 @@ static const struct regmap_config adxl372_spi_regmap_config = {
 
 static int adxl372_spi_probe(struct spi_device *spi)
 {
-       const struct spi_device_id *id = spi_get_device_id(spi);
+       const struct adxl372_chip_info *chip_info;
        struct regmap *regmap;
 
+       chip_info = spi_get_device_match_data(spi);
+
        regmap = devm_regmap_init_spi(spi, &adxl372_spi_regmap_config);
        if (IS_ERR(regmap))
                return PTR_ERR(regmap);
 
-       return adxl372_probe(&spi->dev, regmap, spi->irq, id->name);
+       return adxl372_probe(&spi->dev, regmap, spi->irq, chip_info);
 }
 
 static const struct spi_device_id adxl372_spi_id[] = {
-       { "adxl372", 0 },
+       { "adxl372", (kernel_ulong_t)&adxl372_chip_info },
        { }
 };
 MODULE_DEVICE_TABLE(spi, adxl372_spi_id);
 
 static const struct of_device_id adxl372_of_match[] = {
-       { .compatible = "adi,adxl372" },
+       { .compatible = "adi,adxl372", .data = &adxl372_chip_info },
        { }
 };
 MODULE_DEVICE_TABLE(of, adxl372_of_match);