Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iio: accel: adxl380: add support for ADXL318 and ADXL319

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>

authored by

Jonathan Santos and committed by
Jonathan Cameron
0ecad196 8775ebd2

+107 -39
+95 -39
drivers/iio/accel/adxl380.c
··· 26 26 #include "adxl380.h" 27 27 28 28 #define ADXL380_ID_VAL 380 29 + #define ADXL318_ID_VAL 380 29 30 #define ADXL382_ID_VAL 382 31 + #define ADXL319_ID_VAL 382 30 32 31 33 #define ADXL380_DEVID_AD_REG 0x00 32 34 #define ADLX380_PART_ID_REG 0x02 ··· 180 178 181 179 static const int adxl380_range_scale_factor_tbl[] = { 1, 2, 4 }; 182 180 183 - const struct adxl380_chip_info adxl380_chip_info = { 184 - .name = "adxl380", 185 - .chip_id = ADXL380_ID_VAL, 186 - .scale_tbl = { 187 - [ADXL380_OP_MODE_4G_RANGE] = { 0, 1307226 }, 188 - [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 }, 189 - [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 }, 190 - }, 191 - .samp_freq_tbl = { 8000, 16000, 32000 }, 192 - /* 193 - * The datasheet defines an intercept of 470 LSB at 25 degC 194 - * and a sensitivity of 10.2 LSB/C. 195 - */ 196 - .temp_offset = 25 * 102 / 10 - 470, 197 - 198 - }; 199 - EXPORT_SYMBOL_NS_GPL(adxl380_chip_info, "IIO_ADXL380"); 200 - 201 - const struct adxl380_chip_info adxl382_chip_info = { 202 - .name = "adxl382", 203 - .chip_id = ADXL382_ID_VAL, 204 - .scale_tbl = { 205 - [ADXL382_OP_MODE_15G_RANGE] = { 0, 4903325 }, 206 - [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 }, 207 - [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 }, 208 - }, 209 - .samp_freq_tbl = { 16000, 32000, 64000 }, 210 - /* 211 - * The datasheet defines an intercept of 570 LSB at 25 degC 212 - * and a sensitivity of 10.2 LSB/C. 213 - */ 214 - .temp_offset = 25 * 102 / 10 - 570, 215 - }; 216 - EXPORT_SYMBOL_NS_GPL(adxl382_chip_info, "IIO_ADXL380"); 217 - 218 181 static const unsigned int adxl380_th_reg_high_addr[2] = { 219 182 [ADXL380_ACTIVITY] = ADXL380_THRESH_ACT_H_REG, 220 183 [ADXL380_INACTIVITY] = ADXL380_THRESH_INACT_H_REG, ··· 243 276 if (ret) 244 277 return ret; 245 278 246 - /* Activity/ Inactivity detection available only in VLP/ULP mode */ 247 - if (FIELD_GET(ADXL380_ACT_EN_MSK, act_inact_ctl) || 248 - FIELD_GET(ADXL380_INACT_EN_MSK, act_inact_ctl)) 279 + /* 280 + * Activity/Inactivity detection available only in VLP/ULP 281 + * mode and for devices that support low power modes. Otherwise 282 + * go straight to measure mode (same bits as ADXL380_OP_MODE_HP). 283 + */ 284 + if (st->chip_info->has_low_power && 285 + (FIELD_GET(ADXL380_ACT_EN_MSK, act_inact_ctl) || 286 + FIELD_GET(ADXL380_INACT_EN_MSK, act_inact_ctl))) 249 287 op_mode = ADXL380_OP_MODE_VLP; 250 288 else 251 289 op_mode = ADXL380_OP_MODE_HP; ··· 1590 1618 return 0; 1591 1619 } 1592 1620 1621 + static const struct iio_info adxl318_info = { 1622 + .read_raw = adxl380_read_raw, 1623 + .read_avail = &adxl380_read_avail, 1624 + .write_raw = adxl380_write_raw, 1625 + .write_raw_get_fmt = adxl380_write_raw_get_fmt, 1626 + .debugfs_reg_access = &adxl380_reg_access, 1627 + .hwfifo_set_watermark = adxl380_set_watermark, 1628 + }; 1629 + 1593 1630 static const struct iio_info adxl380_info = { 1594 1631 .read_raw = adxl380_read_raw, 1595 1632 .read_avail = &adxl380_read_avail, ··· 1612 1631 .debugfs_reg_access = &adxl380_reg_access, 1613 1632 .hwfifo_set_watermark = adxl380_set_watermark, 1614 1633 }; 1634 + 1635 + const struct adxl380_chip_info adxl318_chip_info = { 1636 + .name = "adxl318", 1637 + .chip_id = ADXL318_ID_VAL, 1638 + .scale_tbl = { 1639 + [ADXL380_OP_MODE_4G_RANGE] = { 0, 1307226 }, 1640 + [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 }, 1641 + [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 }, 1642 + }, 1643 + .samp_freq_tbl = { 8000, 16000, 32000 }, 1644 + /* 1645 + * The datasheet defines an intercept of 550 LSB at 25 degC 1646 + * and a sensitivity of 10.2 LSB/C. 1647 + */ 1648 + .temp_offset = 25 * 102 / 10 - 550, 1649 + .info = &adxl318_info, 1650 + }; 1651 + EXPORT_SYMBOL_NS_GPL(adxl318_chip_info, "IIO_ADXL380"); 1652 + 1653 + const struct adxl380_chip_info adxl319_chip_info = { 1654 + .name = "adxl319", 1655 + .chip_id = ADXL319_ID_VAL, 1656 + .scale_tbl = { 1657 + [ADXL382_OP_MODE_15G_RANGE] = { 0, 4903325 }, 1658 + [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 }, 1659 + [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 }, 1660 + }, 1661 + .samp_freq_tbl = { 16000, 32000, 64000 }, 1662 + /* 1663 + * The datasheet defines an intercept of 550 LSB at 25 degC 1664 + * and a sensitivity of 10.2 LSB/C. 1665 + */ 1666 + .temp_offset = 25 * 102 / 10 - 550, 1667 + .info = &adxl318_info, 1668 + }; 1669 + EXPORT_SYMBOL_NS_GPL(adxl319_chip_info, "IIO_ADXL380"); 1670 + 1671 + const struct adxl380_chip_info adxl380_chip_info = { 1672 + .name = "adxl380", 1673 + .chip_id = ADXL380_ID_VAL, 1674 + .scale_tbl = { 1675 + [ADXL380_OP_MODE_4G_RANGE] = { 0, 1307226 }, 1676 + [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 }, 1677 + [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 }, 1678 + }, 1679 + .samp_freq_tbl = { 8000, 16000, 32000 }, 1680 + /* 1681 + * The datasheet defines an intercept of 470 LSB at 25 degC 1682 + * and a sensitivity of 10.2 LSB/C. 1683 + */ 1684 + .temp_offset = 25 * 102 / 10 - 470, 1685 + .has_low_power = true, 1686 + .info = &adxl380_info, 1687 + 1688 + }; 1689 + EXPORT_SYMBOL_NS_GPL(adxl380_chip_info, "IIO_ADXL380"); 1690 + 1691 + const struct adxl380_chip_info adxl382_chip_info = { 1692 + .name = "adxl382", 1693 + .chip_id = ADXL382_ID_VAL, 1694 + .scale_tbl = { 1695 + [ADXL382_OP_MODE_15G_RANGE] = { 0, 4903325 }, 1696 + [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 }, 1697 + [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 }, 1698 + }, 1699 + .samp_freq_tbl = { 16000, 32000, 64000 }, 1700 + /* 1701 + * The datasheet defines an intercept of 570 LSB at 25 degC 1702 + * and a sensitivity of 10.2 LSB/C. 1703 + */ 1704 + .temp_offset = 25 * 102 / 10 - 570, 1705 + .has_low_power = true, 1706 + .info = &adxl380_info, 1707 + }; 1708 + EXPORT_SYMBOL_NS_GPL(adxl382_chip_info, "IIO_ADXL380"); 1615 1709 1616 1710 static const struct iio_event_spec adxl380_events[] = { 1617 1711 { ··· 1922 1866 indio_dev->channels = adxl380_channels; 1923 1867 indio_dev->num_channels = ARRAY_SIZE(adxl380_channels); 1924 1868 indio_dev->name = chip_info->name; 1925 - indio_dev->info = &adxl380_info; 1869 + indio_dev->info = chip_info->info; 1926 1870 indio_dev->modes = INDIO_DIRECT_MODE; 1927 1871 1928 1872 ret = devm_regulator_get_enable(dev, "vddio");
+4
drivers/iio/accel/adxl380.h
··· 12 12 const char *name; 13 13 const int scale_tbl[3][2]; 14 14 const int samp_freq_tbl[3]; 15 + const struct iio_info *info; 15 16 const int temp_offset; 16 17 const u16 chip_id; 18 + const bool has_low_power; 17 19 }; 18 20 21 + extern const struct adxl380_chip_info adxl318_chip_info; 22 + extern const struct adxl380_chip_info adxl319_chip_info; 19 23 extern const struct adxl380_chip_info adxl380_chip_info; 20 24 extern const struct adxl380_chip_info adxl382_chip_info; 21 25
+4
drivers/iio/accel/adxl380_i2c.c
··· 33 33 } 34 34 35 35 static const struct i2c_device_id adxl380_i2c_id[] = { 36 + { "adxl318", (kernel_ulong_t)&adxl318_chip_info }, 37 + { "adxl319", (kernel_ulong_t)&adxl319_chip_info }, 36 38 { "adxl380", (kernel_ulong_t)&adxl380_chip_info }, 37 39 { "adxl382", (kernel_ulong_t)&adxl382_chip_info }, 38 40 { } ··· 42 40 MODULE_DEVICE_TABLE(i2c, adxl380_i2c_id); 43 41 44 42 static const struct of_device_id adxl380_of_match[] = { 43 + { .compatible = "adi,adxl318", .data = &adxl318_chip_info }, 44 + { .compatible = "adi,adxl319", .data = &adxl319_chip_info }, 45 45 { .compatible = "adi,adxl380", .data = &adxl380_chip_info }, 46 46 { .compatible = "adi,adxl382", .data = &adxl382_chip_info }, 47 47 { }
+4
drivers/iio/accel/adxl380_spi.c
··· 35 35 } 36 36 37 37 static const struct spi_device_id adxl380_spi_id[] = { 38 + { "adxl318", (kernel_ulong_t)&adxl318_chip_info }, 39 + { "adxl319", (kernel_ulong_t)&adxl319_chip_info }, 38 40 { "adxl380", (kernel_ulong_t)&adxl380_chip_info }, 39 41 { "adxl382", (kernel_ulong_t)&adxl382_chip_info }, 40 42 { } ··· 44 42 MODULE_DEVICE_TABLE(spi, adxl380_spi_id); 45 43 46 44 static const struct of_device_id adxl380_of_match[] = { 45 + { .compatible = "adi,adxl318", .data = &adxl318_chip_info }, 46 + { .compatible = "adi,adxl319", .data = &adxl319_chip_info }, 47 47 { .compatible = "adi,adxl380", .data = &adxl380_chip_info }, 48 48 { .compatible = "adi,adxl382", .data = &adxl382_chip_info }, 49 49 { }