[PATCH 1/3] iio: accel: adxl372: introduce chip_info structure
From: Antoniu Miclaus
Date: Mon Mar 02 2026 - 07:23:47 EST
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_available sysfs attribute is changed from a
static const string to a dynamic callback that reads from chip_info,
and 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@xxxxxxxxxx>
---
drivers/iio/accel/adxl372.c | 94 ++++++++++++++++++++++-----------
drivers/iio/accel/adxl372.h | 16 +++++-
drivers/iio/accel/adxl372_i2c.c | 12 +++--
drivers/iio/accel/adxl372_spi.c | 12 +++--
4 files changed, 93 insertions(+), 41 deletions(-)
diff --git a/drivers/iio/accel/adxl372.c b/drivers/iio/accel/adxl372.c
index 28a8793a53b6..d1f957adea64 100644
--- a/drivers/iio/accel/adxl372.c
+++ b/drivers/iio/accel/adxl372.c
@@ -222,6 +222,19 @@ static const int adxl372_bw_freq_tbl[5] = {
200, 400, 800, 1600, 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;
@@ -279,6 +292,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;
@@ -471,13 +485,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);
@@ -501,13 +516,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;
@@ -717,7 +733,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;
@@ -777,10 +793,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;
}
@@ -796,23 +812,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;
@@ -825,9 +835,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;
@@ -968,7 +978,7 @@ static ssize_t adxl372_show_filter_freq_avail(struct device *dev,
for (i = 0; i <= st->odr; i++)
len += scnprintf(buf + len, PAGE_SIZE - len,
- "%d ", adxl372_bw_freq_tbl[i]);
+ "%d ", st->chip_info->bw_freq_tbl[i]);
buf[len - 1] = '\n';
@@ -1142,12 +1152,31 @@ 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 ssize_t adxl372_show_samp_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->chip_info->num_freqs; i++)
+ len += scnprintf(buf + len, PAGE_SIZE - len,
+ "%d ", st->chip_info->samp_freq_tbl[i]);
+
+ buf[len - 1] = '\n';
+
+ return len;
+}
+
+static IIO_DEVICE_ATTR(sampling_frequency_available,
+ 0444, adxl372_show_samp_freq_avail, NULL, 0);
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_sampling_frequency_available.dev_attr.attr,
&iio_dev_attr_in_accel_filter_low_pass_3db_frequency_available.dev_attr.attr,
NULL,
};
@@ -1176,7 +1205,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;
@@ -1192,13 +1221,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;
diff --git a/drivers/iio/accel/adxl372.h b/drivers/iio/accel/adxl372.h
index 80a0aa9714fc..3ce06609446c 100644
--- a/drivers/iio/accel/adxl372.h
+++ b/drivers/iio/accel/adxl372.h
@@ -10,8 +10,22 @@
#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_ */
diff --git a/drivers/iio/accel/adxl372_i2c.c b/drivers/iio/accel/adxl372_i2c.c
index 186d4fe9a556..3f97126a87a1 100644
--- a/drivers/iio/accel/adxl372_i2c.c
+++ b/drivers/iio/accel/adxl372_i2c.c
@@ -20,11 +20,15 @@ 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);
+ if (!chip_info)
+ return -ENODEV;
+
regmap = devm_regmap_init_i2c(client, &adxl372_regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
@@ -38,17 +42,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);
diff --git a/drivers/iio/accel/adxl372_spi.c b/drivers/iio/accel/adxl372_spi.c
index 39941b519c3b..0e199feb405e 100644
--- a/drivers/iio/accel/adxl372_spi.c
+++ b/drivers/iio/accel/adxl372_spi.c
@@ -22,24 +22,28 @@ 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);
+ if (!chip_info)
+ return -ENODEV;
+
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);
--
2.43.0