]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
iio: accel: adxl380: add support for ADXL318 and ADXL319
authorJonathan Santos <Jonathan.Santos@analog.com>
Fri, 14 Nov 2025 22:14:02 +0000 (19:14 -0300)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Sat, 15 Nov 2025 17:11:35 +0000 (17:11 +0000)
The ADXL318 and ADXL319 are low noise density, low power, 3-axis
accelerometers based on ADXL380 and ADXL382, respectively. The main
difference between the new parts and the existing ones are the absence
of interrupts and events like tap detection, activity/inactivity, and
free-fall detection.

Other differences in the new parts are fewer power modes, basically
allowing only idle and measurement modes, and the removal of the 12-bit
SAR ADC path for the 3-axis signals (known as lower signal chain),
being excluisive for the temperature sensor in the ADXL318/319.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Jonathan Santos <Jonathan.Santos@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/accel/adxl380.c
drivers/iio/accel/adxl380.h
drivers/iio/accel/adxl380_i2c.c
drivers/iio/accel/adxl380_spi.c

index 0cf3c68158293c17ebb14bbfbbce64c4c35c09d0..6d5f1a0d51e97636799f5d5bae8908007dbdad42 100644 (file)
@@ -26,7 +26,9 @@
 #include "adxl380.h"
 
 #define ADXL380_ID_VAL                         380
+#define ADXL318_ID_VAL                         380
 #define ADXL382_ID_VAL                         382
+#define ADXL319_ID_VAL                         382
 
 #define ADXL380_DEVID_AD_REG                   0x00
 #define ADLX380_PART_ID_REG                    0x02
@@ -178,41 +180,6 @@ enum adxl380_tap_time_type {
 
 static const int adxl380_range_scale_factor_tbl[] = { 1, 2, 4 };
 
-const struct adxl380_chip_info adxl380_chip_info = {
-       .name = "adxl380",
-       .chip_id = ADXL380_ID_VAL,
-       .scale_tbl = {
-               [ADXL380_OP_MODE_4G_RANGE] = { 0, 1307226 },
-               [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 },
-               [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 },
-       },
-       .samp_freq_tbl = { 8000, 16000, 32000 },
-       /*
-        * The datasheet defines an intercept of 470 LSB at 25 degC
-        * and a sensitivity of 10.2 LSB/C.
-        */
-       .temp_offset =  25 * 102 / 10 - 470,
-
-};
-EXPORT_SYMBOL_NS_GPL(adxl380_chip_info, "IIO_ADXL380");
-
-const struct adxl380_chip_info adxl382_chip_info = {
-       .name = "adxl382",
-       .chip_id = ADXL382_ID_VAL,
-       .scale_tbl = {
-               [ADXL382_OP_MODE_15G_RANGE] = { 0, 4903325 },
-               [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 },
-               [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 },
-       },
-       .samp_freq_tbl = { 16000, 32000, 64000 },
-       /*
-        * The datasheet defines an intercept of 570 LSB at 25 degC
-        * and a sensitivity of 10.2 LSB/C.
-        */
-       .temp_offset =  25 * 102 / 10 - 570,
-};
-EXPORT_SYMBOL_NS_GPL(adxl382_chip_info, "IIO_ADXL380");
-
 static const unsigned int adxl380_th_reg_high_addr[2] = {
        [ADXL380_ACTIVITY] = ADXL380_THRESH_ACT_H_REG,
        [ADXL380_INACTIVITY] = ADXL380_THRESH_INACT_H_REG,
@@ -276,9 +243,14 @@ static int adxl380_set_measure_en(struct adxl380_state *st, bool en)
                if (ret)
                        return ret;
 
-               /* Activity/ Inactivity detection available only in VLP/ULP mode */
-               if (FIELD_GET(ADXL380_ACT_EN_MSK, act_inact_ctl) ||
-                   FIELD_GET(ADXL380_INACT_EN_MSK, act_inact_ctl))
+               /*
+                * Activity/Inactivity detection available only in VLP/ULP
+                * mode and for devices that support low power modes. Otherwise
+                * go straight to measure mode (same bits as ADXL380_OP_MODE_HP).
+                */
+               if (st->chip_info->has_low_power &&
+                   (FIELD_GET(ADXL380_ACT_EN_MSK, act_inact_ctl) ||
+                    FIELD_GET(ADXL380_INACT_EN_MSK, act_inact_ctl)))
                        op_mode = ADXL380_OP_MODE_VLP;
                else
                        op_mode = ADXL380_OP_MODE_HP;
@@ -1618,6 +1590,15 @@ static int adxl380_set_watermark(struct iio_dev *indio_dev, unsigned int val)
        return 0;
 }
 
+static const struct iio_info adxl318_info = {
+       .read_raw = adxl380_read_raw,
+       .read_avail = &adxl380_read_avail,
+       .write_raw = adxl380_write_raw,
+       .write_raw_get_fmt = adxl380_write_raw_get_fmt,
+       .debugfs_reg_access = &adxl380_reg_access,
+       .hwfifo_set_watermark = adxl380_set_watermark,
+};
+
 static const struct iio_info adxl380_info = {
        .read_raw = adxl380_read_raw,
        .read_avail = &adxl380_read_avail,
@@ -1632,6 +1613,81 @@ static const struct iio_info adxl380_info = {
        .hwfifo_set_watermark = adxl380_set_watermark,
 };
 
+const struct adxl380_chip_info adxl318_chip_info = {
+       .name = "adxl318",
+       .chip_id = ADXL318_ID_VAL,
+       .scale_tbl = {
+               [ADXL380_OP_MODE_4G_RANGE] = { 0, 1307226 },
+               [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 },
+               [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 },
+       },
+       .samp_freq_tbl = { 8000, 16000, 32000 },
+       /*
+        * The datasheet defines an intercept of 550 LSB at 25 degC
+        * and a sensitivity of 10.2 LSB/C.
+        */
+       .temp_offset =  25 * 102 / 10 - 550,
+       .info = &adxl318_info,
+};
+EXPORT_SYMBOL_NS_GPL(adxl318_chip_info, "IIO_ADXL380");
+
+const struct adxl380_chip_info adxl319_chip_info = {
+       .name = "adxl319",
+       .chip_id = ADXL319_ID_VAL,
+       .scale_tbl = {
+               [ADXL382_OP_MODE_15G_RANGE] = { 0, 4903325 },
+               [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 },
+               [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 },
+       },
+       .samp_freq_tbl = { 16000, 32000, 64000 },
+       /*
+        * The datasheet defines an intercept of 550 LSB at 25 degC
+        * and a sensitivity of 10.2 LSB/C.
+        */
+       .temp_offset =  25 * 102 / 10 - 550,
+       .info = &adxl318_info,
+};
+EXPORT_SYMBOL_NS_GPL(adxl319_chip_info, "IIO_ADXL380");
+
+const struct adxl380_chip_info adxl380_chip_info = {
+       .name = "adxl380",
+       .chip_id = ADXL380_ID_VAL,
+       .scale_tbl = {
+               [ADXL380_OP_MODE_4G_RANGE] = { 0, 1307226 },
+               [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 },
+               [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 },
+       },
+       .samp_freq_tbl = { 8000, 16000, 32000 },
+       /*
+        * The datasheet defines an intercept of 470 LSB at 25 degC
+        * and a sensitivity of 10.2 LSB/C.
+        */
+       .temp_offset =  25 * 102 / 10 - 470,
+       .has_low_power = true,
+       .info = &adxl380_info,
+
+};
+EXPORT_SYMBOL_NS_GPL(adxl380_chip_info, "IIO_ADXL380");
+
+const struct adxl380_chip_info adxl382_chip_info = {
+       .name = "adxl382",
+       .chip_id = ADXL382_ID_VAL,
+       .scale_tbl = {
+               [ADXL382_OP_MODE_15G_RANGE] = { 0, 4903325 },
+               [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 },
+               [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 },
+       },
+       .samp_freq_tbl = { 16000, 32000, 64000 },
+       /*
+        * The datasheet defines an intercept of 570 LSB at 25 degC
+        * and a sensitivity of 10.2 LSB/C.
+        */
+       .temp_offset =  25 * 102 / 10 - 570,
+       .has_low_power = true,
+       .info = &adxl380_info,
+};
+EXPORT_SYMBOL_NS_GPL(adxl382_chip_info, "IIO_ADXL380");
+
 static const struct iio_event_spec adxl380_events[] = {
        {
                .type = IIO_EV_TYPE_THRESH,
@@ -1866,7 +1922,7 @@ int adxl380_probe(struct device *dev, struct regmap *regmap,
        indio_dev->channels = adxl380_channels;
        indio_dev->num_channels = ARRAY_SIZE(adxl380_channels);
        indio_dev->name = chip_info->name;
-       indio_dev->info = &adxl380_info;
+       indio_dev->info = chip_info->info;
        indio_dev->modes = INDIO_DIRECT_MODE;
 
        ret = devm_regulator_get_enable(dev, "vddio");
index a683625d897a4a463e9bb8a88b4725ee7ca349f1..e67c5aab8efcf390ae0441b6f7a9a772aef3fb88 100644 (file)
@@ -12,10 +12,14 @@ struct adxl380_chip_info {
        const char *name;
        const int scale_tbl[3][2];
        const int samp_freq_tbl[3];
+       const struct iio_info *info;
        const int temp_offset;
        const u16 chip_id;
+       const bool has_low_power;
 };
 
+extern const struct adxl380_chip_info adxl318_chip_info;
+extern const struct adxl380_chip_info adxl319_chip_info;
 extern const struct adxl380_chip_info adxl380_chip_info;
 extern const struct adxl380_chip_info adxl382_chip_info;
 
index b4f86f97236148b0df8666d48010054eef727071..bd8782d08c7d91f4932869628326e4ce857ef75e 100644 (file)
@@ -33,6 +33,8 @@ static int adxl380_i2c_probe(struct i2c_client *client)
 }
 
 static const struct i2c_device_id adxl380_i2c_id[] = {
+       { "adxl318", (kernel_ulong_t)&adxl318_chip_info },
+       { "adxl319", (kernel_ulong_t)&adxl319_chip_info },
        { "adxl380", (kernel_ulong_t)&adxl380_chip_info },
        { "adxl382", (kernel_ulong_t)&adxl382_chip_info },
        { }
@@ -40,6 +42,8 @@ static const struct i2c_device_id adxl380_i2c_id[] = {
 MODULE_DEVICE_TABLE(i2c, adxl380_i2c_id);
 
 static const struct of_device_id adxl380_of_match[] = {
+       { .compatible = "adi,adxl318", .data = &adxl318_chip_info },
+       { .compatible = "adi,adxl319", .data = &adxl319_chip_info },
        { .compatible = "adi,adxl380", .data = &adxl380_chip_info },
        { .compatible = "adi,adxl382", .data = &adxl382_chip_info },
        { }
index 6edd0d211ffad91c377baa02457aee5a1a5919ab..4ead949b24f18f27243e5ecd080024b70efc30af 100644 (file)
@@ -35,6 +35,8 @@ static int adxl380_spi_probe(struct spi_device *spi)
 }
 
 static const struct spi_device_id adxl380_spi_id[] = {
+       { "adxl318", (kernel_ulong_t)&adxl318_chip_info },
+       { "adxl319", (kernel_ulong_t)&adxl319_chip_info },
        { "adxl380", (kernel_ulong_t)&adxl380_chip_info },
        { "adxl382", (kernel_ulong_t)&adxl382_chip_info },
        { }
@@ -42,6 +44,8 @@ static const struct spi_device_id adxl380_spi_id[] = {
 MODULE_DEVICE_TABLE(spi, adxl380_spi_id);
 
 static const struct of_device_id adxl380_of_match[] = {
+       { .compatible = "adi,adxl318", .data = &adxl318_chip_info },
+       { .compatible = "adi,adxl319", .data = &adxl319_chip_info },
        { .compatible = "adi,adxl380", .data = &adxl380_chip_info },
        { .compatible = "adi,adxl382", .data = &adxl382_chip_info },
        { }