1fda8d26eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2290a6ce1SLorenzo Bianconi /* 3290a6ce1SLorenzo Bianconi * STMicroelectronics st_lsm6dsx sensor driver 4290a6ce1SLorenzo Bianconi * 5290a6ce1SLorenzo Bianconi * The ST LSM6DSx IMU MEMS series consists of 3D digital accelerometer 6290a6ce1SLorenzo Bianconi * and 3D digital gyroscope system-in-package with a digital I2C/SPI serial 7290a6ce1SLorenzo Bianconi * interface standard output. 8290a6ce1SLorenzo Bianconi * LSM6DSx IMU MEMS series has a dynamic user-selectable full-scale 9290a6ce1SLorenzo Bianconi * acceleration range of +-2/+-4/+-8/+-16 g and an angular rate range of 10290a6ce1SLorenzo Bianconi * +-125/+-245/+-500/+-1000/+-2000 dps 11290a6ce1SLorenzo Bianconi * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer 12290a6ce1SLorenzo Bianconi * allowing dynamic batching of sensor data. 1352f4b1f1SMartin Kepplinger * LSM9DSx series is similar but includes an additional magnetometer, handled 1452f4b1f1SMartin Kepplinger * by a different driver. 15290a6ce1SLorenzo Bianconi * 16290a6ce1SLorenzo Bianconi * Supported sensors: 17290a6ce1SLorenzo Bianconi * - LSM6DS3: 18290a6ce1SLorenzo Bianconi * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416 19290a6ce1SLorenzo Bianconi * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 20290a6ce1SLorenzo Bianconi * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 21290a6ce1SLorenzo Bianconi * - FIFO size: 8KB 22290a6ce1SLorenzo Bianconi * 23dbcd2088SLorenzo Bianconi * - LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC/LSM6DS3TR-C: 24290a6ce1SLorenzo Bianconi * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416 25290a6ce1SLorenzo Bianconi * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 26290a6ce1SLorenzo Bianconi * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 27290a6ce1SLorenzo Bianconi * - FIFO size: 4KB 28290a6ce1SLorenzo Bianconi * 29db947a79SLorenzo Bianconi * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX: 30801a6e0aSLorenzo Bianconi * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416 31801a6e0aSLorenzo Bianconi * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 32801a6e0aSLorenzo Bianconi * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 33801a6e0aSLorenzo Bianconi * - FIFO size: 3KB 34801a6e0aSLorenzo Bianconi * 35fa060a3dSLorenzo Bianconi * - LSM9DS1/LSM6DS0: 3652f4b1f1SMartin Kepplinger * - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952 3752f4b1f1SMartin Kepplinger * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 3852f4b1f1SMartin Kepplinger * - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952 3952f4b1f1SMartin Kepplinger * - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000 4052f4b1f1SMartin Kepplinger * - FIFO size: 32 4152f4b1f1SMartin Kepplinger * 42290a6ce1SLorenzo Bianconi * Copyright 2016 STMicroelectronics Inc. 43290a6ce1SLorenzo Bianconi * 44290a6ce1SLorenzo Bianconi * Lorenzo Bianconi <lorenzo.bianconi@st.com> 45290a6ce1SLorenzo Bianconi * Denis Ciocca <denis.ciocca@st.com> 46290a6ce1SLorenzo Bianconi */ 47290a6ce1SLorenzo Bianconi 48290a6ce1SLorenzo Bianconi #include <linux/kernel.h> 49290a6ce1SLorenzo Bianconi #include <linux/module.h> 50290a6ce1SLorenzo Bianconi #include <linux/delay.h> 511aabad1fSSean Nyekjaer #include <linux/iio/events.h> 52290a6ce1SLorenzo Bianconi #include <linux/iio/iio.h> 53290a6ce1SLorenzo Bianconi #include <linux/iio/sysfs.h> 546ee6a368SSean Nyekjaer #include <linux/interrupt.h> 556ee6a368SSean Nyekjaer #include <linux/irq.h> 56d3f77058SLorenzo Bianconi #include <linux/pm.h> 5703d4c566SAndy Shevchenko #include <linux/property.h> 5851a8b707SLorenzo Bianconi #include <linux/regmap.h> 5951a8b707SLorenzo Bianconi #include <linux/bitfield.h> 60290a6ce1SLorenzo Bianconi 61dba32904SLorenzo Bianconi #include <linux/platform_data/st_sensors_pdata.h> 62dba32904SLorenzo Bianconi 63290a6ce1SLorenzo Bianconi #include "st_lsm6dsx.h" 64290a6ce1SLorenzo Bianconi 65290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f 66290a6ce1SLorenzo Bianconi 67cb3b6b8eSMario Tesi #define ST_LSM6DSX_TS_SENSITIVITY 25000UL /* 25us */ 68cb3b6b8eSMario Tesi 69f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { 70b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0), 71b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1), 72b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2), 73f48bc49bSLorenzo Bianconi IIO_CHAN_SOFT_TIMESTAMP(3), 74f48bc49bSLorenzo Bianconi }; 75f48bc49bSLorenzo Bianconi 76f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = { 77f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0), 78f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1), 79f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2), 80f48bc49bSLorenzo Bianconi IIO_CHAN_SOFT_TIMESTAMP(3), 81f48bc49bSLorenzo Bianconi }; 82f48bc49bSLorenzo Bianconi 8352f4b1f1SMartin Kepplinger static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = { 8452f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0), 8552f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1), 8652f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2), 8752f4b1f1SMartin Kepplinger IIO_CHAN_SOFT_TIMESTAMP(3), 8852f4b1f1SMartin Kepplinger }; 8952f4b1f1SMartin Kepplinger 90290a6ce1SLorenzo Bianconi static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { 91290a6ce1SLorenzo Bianconi { 9252f4b1f1SMartin Kepplinger .wai = 0x68, 9366b662a1SLorenzo Bianconi .reset = { 9466b662a1SLorenzo Bianconi .addr = 0x22, 9566b662a1SLorenzo Bianconi .mask = BIT(0), 9666b662a1SLorenzo Bianconi }, 9766b662a1SLorenzo Bianconi .boot = { 9866b662a1SLorenzo Bianconi .addr = 0x22, 9966b662a1SLorenzo Bianconi .mask = BIT(7), 10066b662a1SLorenzo Bianconi }, 10166b662a1SLorenzo Bianconi .bdu = { 10266b662a1SLorenzo Bianconi .addr = 0x22, 10366b662a1SLorenzo Bianconi .mask = BIT(6), 10466b662a1SLorenzo Bianconi }, 10552f4b1f1SMartin Kepplinger .max_fifo_size = 32, 10652f4b1f1SMartin Kepplinger .id = { 10752f4b1f1SMartin Kepplinger { 10852f4b1f1SMartin Kepplinger .hw_id = ST_LSM9DS1_ID, 10952f4b1f1SMartin Kepplinger .name = ST_LSM9DS1_DEV_NAME, 110fa060a3dSLorenzo Bianconi }, { 111fa060a3dSLorenzo Bianconi .hw_id = ST_LSM6DS0_ID, 112fa060a3dSLorenzo Bianconi .name = ST_LSM6DS0_DEV_NAME, 11352f4b1f1SMartin Kepplinger }, 11452f4b1f1SMartin Kepplinger }, 11552f4b1f1SMartin Kepplinger .channels = { 11652f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 11752f4b1f1SMartin Kepplinger .chan = st_lsm6dsx_acc_channels, 11852f4b1f1SMartin Kepplinger .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 11952f4b1f1SMartin Kepplinger }, 12052f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 12152f4b1f1SMartin Kepplinger .chan = st_lsm6ds0_gyro_channels, 12252f4b1f1SMartin Kepplinger .len = ARRAY_SIZE(st_lsm6ds0_gyro_channels), 12352f4b1f1SMartin Kepplinger }, 12452f4b1f1SMartin Kepplinger }, 12552f4b1f1SMartin Kepplinger .odr_table = { 12652f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 12752f4b1f1SMartin Kepplinger .reg = { 12852f4b1f1SMartin Kepplinger .addr = 0x20, 12952f4b1f1SMartin Kepplinger .mask = GENMASK(7, 5), 13052f4b1f1SMartin Kepplinger }, 131f8710f03SLorenzo Bianconi .odr_avl[0] = { 10000, 0x01 }, 132f8710f03SLorenzo Bianconi .odr_avl[1] = { 50000, 0x02 }, 133f8710f03SLorenzo Bianconi .odr_avl[2] = { 119000, 0x03 }, 134f8710f03SLorenzo Bianconi .odr_avl[3] = { 238000, 0x04 }, 135f8710f03SLorenzo Bianconi .odr_avl[4] = { 476000, 0x05 }, 136f8710f03SLorenzo Bianconi .odr_avl[5] = { 952000, 0x06 }, 13759af4e20SLorenzo Bianconi .odr_len = 6, 13852f4b1f1SMartin Kepplinger }, 13952f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 14052f4b1f1SMartin Kepplinger .reg = { 14152f4b1f1SMartin Kepplinger .addr = 0x10, 14252f4b1f1SMartin Kepplinger .mask = GENMASK(7, 5), 14352f4b1f1SMartin Kepplinger }, 144f8710f03SLorenzo Bianconi .odr_avl[0] = { 14900, 0x01 }, 145f8710f03SLorenzo Bianconi .odr_avl[1] = { 59500, 0x02 }, 146f8710f03SLorenzo Bianconi .odr_avl[2] = { 119000, 0x03 }, 147f8710f03SLorenzo Bianconi .odr_avl[3] = { 238000, 0x04 }, 148f8710f03SLorenzo Bianconi .odr_avl[4] = { 476000, 0x05 }, 149f8710f03SLorenzo Bianconi .odr_avl[5] = { 952000, 0x06 }, 15059af4e20SLorenzo Bianconi .odr_len = 6, 15152f4b1f1SMartin Kepplinger }, 15252f4b1f1SMartin Kepplinger }, 15352f4b1f1SMartin Kepplinger .fs_table = { 15452f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 15552f4b1f1SMartin Kepplinger .reg = { 15652f4b1f1SMartin Kepplinger .addr = 0x20, 15752f4b1f1SMartin Kepplinger .mask = GENMASK(4, 3), 15852f4b1f1SMartin Kepplinger }, 1596fa02948SLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 1606fa02948SLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 1616fa02948SLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 1626fa02948SLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 }, 16385ae3aeeSLorenzo Bianconi .fs_len = 4, 16452f4b1f1SMartin Kepplinger }, 16552f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 16652f4b1f1SMartin Kepplinger .reg = { 16752f4b1f1SMartin Kepplinger .addr = 0x10, 16852f4b1f1SMartin Kepplinger .mask = GENMASK(4, 3), 16952f4b1f1SMartin Kepplinger }, 1701b375101SLorenzo Bianconi 1711b375101SLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 1721b375101SLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 1731b375101SLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 17485ae3aeeSLorenzo Bianconi .fs_len = 3, 17552f4b1f1SMartin Kepplinger }, 17652f4b1f1SMartin Kepplinger }, 1777e906103SLorenzo Bianconi .irq_config = { 1787e906103SLorenzo Bianconi .irq1 = { 1797e906103SLorenzo Bianconi .addr = 0x0c, 1807e906103SLorenzo Bianconi .mask = BIT(3), 1817e906103SLorenzo Bianconi }, 1827e906103SLorenzo Bianconi .irq2 = { 1837e906103SLorenzo Bianconi .addr = 0x0d, 1847e906103SLorenzo Bianconi .mask = BIT(3), 1857e906103SLorenzo Bianconi }, 18631fe8d4eSLorenzo Bianconi .hla = { 18731fe8d4eSLorenzo Bianconi .addr = 0x22, 18831fe8d4eSLorenzo Bianconi .mask = BIT(5), 18931fe8d4eSLorenzo Bianconi }, 19031fe8d4eSLorenzo Bianconi .od = { 19131fe8d4eSLorenzo Bianconi .addr = 0x22, 19231fe8d4eSLorenzo Bianconi .mask = BIT(4), 19331fe8d4eSLorenzo Bianconi }, 1947e906103SLorenzo Bianconi }, 19552f4b1f1SMartin Kepplinger }, 19652f4b1f1SMartin Kepplinger { 197d068e4a0SLorenzo Bianconi .wai = 0x69, 19866b662a1SLorenzo Bianconi .reset = { 19966b662a1SLorenzo Bianconi .addr = 0x12, 20066b662a1SLorenzo Bianconi .mask = BIT(0), 20166b662a1SLorenzo Bianconi }, 20266b662a1SLorenzo Bianconi .boot = { 20366b662a1SLorenzo Bianconi .addr = 0x12, 20466b662a1SLorenzo Bianconi .mask = BIT(7), 20566b662a1SLorenzo Bianconi }, 20666b662a1SLorenzo Bianconi .bdu = { 20766b662a1SLorenzo Bianconi .addr = 0x12, 20866b662a1SLorenzo Bianconi .mask = BIT(6), 20966b662a1SLorenzo Bianconi }, 2108f2a88a2SLorenzo Bianconi .max_fifo_size = 1365, 211d068e4a0SLorenzo Bianconi .id = { 21281956a93SLorenzo Bianconi { 21381956a93SLorenzo Bianconi .hw_id = ST_LSM6DS3_ID, 21481956a93SLorenzo Bianconi .name = ST_LSM6DS3_DEV_NAME, 21581956a93SLorenzo Bianconi }, 216d068e4a0SLorenzo Bianconi }, 217f48bc49bSLorenzo Bianconi .channels = { 218f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 219f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 220f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 221f48bc49bSLorenzo Bianconi }, 222f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 223f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 224f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 225f48bc49bSLorenzo Bianconi }, 226f48bc49bSLorenzo Bianconi }, 22740dd7343SLorenzo Bianconi .odr_table = { 22840dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 22940dd7343SLorenzo Bianconi .reg = { 23040dd7343SLorenzo Bianconi .addr = 0x10, 23140dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 23240dd7343SLorenzo Bianconi }, 233f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 234f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 235f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 236f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 237f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 238f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 23959af4e20SLorenzo Bianconi .odr_len = 6, 24040dd7343SLorenzo Bianconi }, 24140dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 24240dd7343SLorenzo Bianconi .reg = { 24340dd7343SLorenzo Bianconi .addr = 0x11, 24440dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 24540dd7343SLorenzo Bianconi }, 246f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 247f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 248f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 249f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 250f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 251f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 25259af4e20SLorenzo Bianconi .odr_len = 6, 25340dd7343SLorenzo Bianconi }, 25440dd7343SLorenzo Bianconi }, 255640aca3fSLorenzo Bianconi .fs_table = { 256640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 257640aca3fSLorenzo Bianconi .reg = { 258640aca3fSLorenzo Bianconi .addr = 0x10, 259640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 260640aca3fSLorenzo Bianconi }, 261640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 262640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 263640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 264640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 26585ae3aeeSLorenzo Bianconi .fs_len = 4, 266640aca3fSLorenzo Bianconi }, 267640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 268640aca3fSLorenzo Bianconi .reg = { 269640aca3fSLorenzo Bianconi .addr = 0x11, 270640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 271640aca3fSLorenzo Bianconi }, 272640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 273640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 274640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 275640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 27685ae3aeeSLorenzo Bianconi .fs_len = 4, 277640aca3fSLorenzo Bianconi }, 278640aca3fSLorenzo Bianconi }, 2797e906103SLorenzo Bianconi .irq_config = { 2807e906103SLorenzo Bianconi .irq1 = { 2817e906103SLorenzo Bianconi .addr = 0x0d, 2827e906103SLorenzo Bianconi .mask = BIT(3), 2837e906103SLorenzo Bianconi }, 2847e906103SLorenzo Bianconi .irq2 = { 2857e906103SLorenzo Bianconi .addr = 0x0e, 2867e906103SLorenzo Bianconi .mask = BIT(3), 2877e906103SLorenzo Bianconi }, 2887e906103SLorenzo Bianconi .lir = { 2897e906103SLorenzo Bianconi .addr = 0x58, 2907e906103SLorenzo Bianconi .mask = BIT(0), 2917e906103SLorenzo Bianconi }, 2927e906103SLorenzo Bianconi .irq1_func = { 2937e906103SLorenzo Bianconi .addr = 0x5e, 2947e906103SLorenzo Bianconi .mask = BIT(5), 2957e906103SLorenzo Bianconi }, 2967e906103SLorenzo Bianconi .irq2_func = { 2977e906103SLorenzo Bianconi .addr = 0x5f, 2987e906103SLorenzo Bianconi .mask = BIT(5), 2997e906103SLorenzo Bianconi }, 30031fe8d4eSLorenzo Bianconi .hla = { 30131fe8d4eSLorenzo Bianconi .addr = 0x12, 30231fe8d4eSLorenzo Bianconi .mask = BIT(5), 30331fe8d4eSLorenzo Bianconi }, 30431fe8d4eSLorenzo Bianconi .od = { 30531fe8d4eSLorenzo Bianconi .addr = 0x12, 30631fe8d4eSLorenzo Bianconi .mask = BIT(4), 30731fe8d4eSLorenzo Bianconi }, 3087e906103SLorenzo Bianconi }, 3097ca3ac9eSLorenzo Bianconi .decimator = { 3107ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 3117ca3ac9eSLorenzo Bianconi .addr = 0x08, 3127ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 3137ca3ac9eSLorenzo Bianconi }, 3147ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 3157ca3ac9eSLorenzo Bianconi .addr = 0x08, 3167ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 3177ca3ac9eSLorenzo Bianconi }, 3187ca3ac9eSLorenzo Bianconi }, 31992617c15SLorenzo Bianconi .fifo_ops = { 3203b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 32150ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 32292617c15SLorenzo Bianconi .fifo_th = { 32392617c15SLorenzo Bianconi .addr = 0x06, 32492617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 32592617c15SLorenzo Bianconi }, 32692617c15SLorenzo Bianconi .fifo_diff = { 32792617c15SLorenzo Bianconi .addr = 0x3a, 32892617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 32992617c15SLorenzo Bianconi }, 33092617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 33192617c15SLorenzo Bianconi }, 33221345107SLorenzo Bianconi .ts_settings = { 33321345107SLorenzo Bianconi .timer_en = { 33421345107SLorenzo Bianconi .addr = 0x58, 33521345107SLorenzo Bianconi .mask = BIT(7), 33621345107SLorenzo Bianconi }, 33721345107SLorenzo Bianconi .hr_timer = { 33821345107SLorenzo Bianconi .addr = 0x5c, 33921345107SLorenzo Bianconi .mask = BIT(4), 34021345107SLorenzo Bianconi }, 34121345107SLorenzo Bianconi .fifo_en = { 34221345107SLorenzo Bianconi .addr = 0x07, 34321345107SLorenzo Bianconi .mask = BIT(7), 34421345107SLorenzo Bianconi }, 34521345107SLorenzo Bianconi .decimator = { 34621345107SLorenzo Bianconi .addr = 0x09, 34721345107SLorenzo Bianconi .mask = GENMASK(5, 3), 34821345107SLorenzo Bianconi }, 34921345107SLorenzo Bianconi }, 350b5969abfSSean Nyekjaer .event_settings = { 351b5969abfSSean Nyekjaer .wakeup_reg = { 352b5969abfSSean Nyekjaer .addr = 0x5B, 353b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 354b5969abfSSean Nyekjaer }, 3551aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 3561aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 3571aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 3581aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 3591aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 360b5969abfSSean Nyekjaer }, 361290a6ce1SLorenzo Bianconi }, 362290a6ce1SLorenzo Bianconi { 363df47710aSLorenzo Bianconi .wai = 0x69, 36466b662a1SLorenzo Bianconi .reset = { 36566b662a1SLorenzo Bianconi .addr = 0x12, 36666b662a1SLorenzo Bianconi .mask = BIT(0), 36766b662a1SLorenzo Bianconi }, 36866b662a1SLorenzo Bianconi .boot = { 36966b662a1SLorenzo Bianconi .addr = 0x12, 37066b662a1SLorenzo Bianconi .mask = BIT(7), 37166b662a1SLorenzo Bianconi }, 37266b662a1SLorenzo Bianconi .bdu = { 37366b662a1SLorenzo Bianconi .addr = 0x12, 37466b662a1SLorenzo Bianconi .mask = BIT(6), 37566b662a1SLorenzo Bianconi }, 3768f2a88a2SLorenzo Bianconi .max_fifo_size = 682, 377df47710aSLorenzo Bianconi .id = { 37881956a93SLorenzo Bianconi { 37981956a93SLorenzo Bianconi .hw_id = ST_LSM6DS3H_ID, 38081956a93SLorenzo Bianconi .name = ST_LSM6DS3H_DEV_NAME, 38181956a93SLorenzo Bianconi }, 382df47710aSLorenzo Bianconi }, 383f48bc49bSLorenzo Bianconi .channels = { 384f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 385f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 386f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 387f48bc49bSLorenzo Bianconi }, 388f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 389f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 390f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 391f48bc49bSLorenzo Bianconi }, 392f48bc49bSLorenzo Bianconi }, 39340dd7343SLorenzo Bianconi .odr_table = { 39440dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 39540dd7343SLorenzo Bianconi .reg = { 39640dd7343SLorenzo Bianconi .addr = 0x10, 39740dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 39840dd7343SLorenzo Bianconi }, 399f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 400f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 401f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 402f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 403f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 404f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 40559af4e20SLorenzo Bianconi .odr_len = 6, 40640dd7343SLorenzo Bianconi }, 40740dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 40840dd7343SLorenzo Bianconi .reg = { 40940dd7343SLorenzo Bianconi .addr = 0x11, 41040dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 41140dd7343SLorenzo Bianconi }, 412f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 413f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 414f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 415f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 416f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 417f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 41859af4e20SLorenzo Bianconi .odr_len = 6, 41940dd7343SLorenzo Bianconi }, 42040dd7343SLorenzo Bianconi }, 421640aca3fSLorenzo Bianconi .fs_table = { 422640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 423640aca3fSLorenzo Bianconi .reg = { 424640aca3fSLorenzo Bianconi .addr = 0x10, 425640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 426640aca3fSLorenzo Bianconi }, 427640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 428640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 429640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 430640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 43185ae3aeeSLorenzo Bianconi .fs_len = 4, 432640aca3fSLorenzo Bianconi }, 433640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 434640aca3fSLorenzo Bianconi .reg = { 435640aca3fSLorenzo Bianconi .addr = 0x11, 436640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 437640aca3fSLorenzo Bianconi }, 438640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 439640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 440640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 441640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 44285ae3aeeSLorenzo Bianconi .fs_len = 4, 443640aca3fSLorenzo Bianconi }, 444640aca3fSLorenzo Bianconi }, 4457e906103SLorenzo Bianconi .irq_config = { 4467e906103SLorenzo Bianconi .irq1 = { 4477e906103SLorenzo Bianconi .addr = 0x0d, 4487e906103SLorenzo Bianconi .mask = BIT(3), 4497e906103SLorenzo Bianconi }, 4507e906103SLorenzo Bianconi .irq2 = { 4517e906103SLorenzo Bianconi .addr = 0x0e, 4527e906103SLorenzo Bianconi .mask = BIT(3), 4537e906103SLorenzo Bianconi }, 4547e906103SLorenzo Bianconi .lir = { 4557e906103SLorenzo Bianconi .addr = 0x58, 4567e906103SLorenzo Bianconi .mask = BIT(0), 4577e906103SLorenzo Bianconi }, 4587e906103SLorenzo Bianconi .irq1_func = { 4597e906103SLorenzo Bianconi .addr = 0x5e, 4607e906103SLorenzo Bianconi .mask = BIT(5), 4617e906103SLorenzo Bianconi }, 4627e906103SLorenzo Bianconi .irq2_func = { 4637e906103SLorenzo Bianconi .addr = 0x5f, 4647e906103SLorenzo Bianconi .mask = BIT(5), 4657e906103SLorenzo Bianconi }, 46631fe8d4eSLorenzo Bianconi .hla = { 46731fe8d4eSLorenzo Bianconi .addr = 0x12, 46831fe8d4eSLorenzo Bianconi .mask = BIT(5), 46931fe8d4eSLorenzo Bianconi }, 47031fe8d4eSLorenzo Bianconi .od = { 47131fe8d4eSLorenzo Bianconi .addr = 0x12, 47231fe8d4eSLorenzo Bianconi .mask = BIT(4), 47331fe8d4eSLorenzo Bianconi }, 4747e906103SLorenzo Bianconi }, 4757ca3ac9eSLorenzo Bianconi .decimator = { 4767ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 4777ca3ac9eSLorenzo Bianconi .addr = 0x08, 4787ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 4797ca3ac9eSLorenzo Bianconi }, 4807ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 4817ca3ac9eSLorenzo Bianconi .addr = 0x08, 4827ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 4837ca3ac9eSLorenzo Bianconi }, 4847ca3ac9eSLorenzo Bianconi }, 48592617c15SLorenzo Bianconi .fifo_ops = { 4863b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 48750ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 48892617c15SLorenzo Bianconi .fifo_th = { 48992617c15SLorenzo Bianconi .addr = 0x06, 49092617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 49192617c15SLorenzo Bianconi }, 49292617c15SLorenzo Bianconi .fifo_diff = { 49392617c15SLorenzo Bianconi .addr = 0x3a, 49492617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 49592617c15SLorenzo Bianconi }, 49692617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 49792617c15SLorenzo Bianconi }, 49821345107SLorenzo Bianconi .ts_settings = { 49921345107SLorenzo Bianconi .timer_en = { 50021345107SLorenzo Bianconi .addr = 0x58, 50121345107SLorenzo Bianconi .mask = BIT(7), 50221345107SLorenzo Bianconi }, 50321345107SLorenzo Bianconi .hr_timer = { 50421345107SLorenzo Bianconi .addr = 0x5c, 50521345107SLorenzo Bianconi .mask = BIT(4), 50621345107SLorenzo Bianconi }, 50721345107SLorenzo Bianconi .fifo_en = { 50821345107SLorenzo Bianconi .addr = 0x07, 50921345107SLorenzo Bianconi .mask = BIT(7), 51021345107SLorenzo Bianconi }, 51121345107SLorenzo Bianconi .decimator = { 51221345107SLorenzo Bianconi .addr = 0x09, 51321345107SLorenzo Bianconi .mask = GENMASK(5, 3), 51421345107SLorenzo Bianconi }, 51521345107SLorenzo Bianconi }, 516b5969abfSSean Nyekjaer .event_settings = { 517b5969abfSSean Nyekjaer .wakeup_reg = { 518b5969abfSSean Nyekjaer .addr = 0x5B, 519b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 520b5969abfSSean Nyekjaer }, 5211aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 5221aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 5231aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 5241aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 5251aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 526b5969abfSSean Nyekjaer }, 527df47710aSLorenzo Bianconi }, 528df47710aSLorenzo Bianconi { 529d068e4a0SLorenzo Bianconi .wai = 0x6a, 53066b662a1SLorenzo Bianconi .reset = { 53166b662a1SLorenzo Bianconi .addr = 0x12, 53266b662a1SLorenzo Bianconi .mask = BIT(0), 53366b662a1SLorenzo Bianconi }, 53466b662a1SLorenzo Bianconi .boot = { 53566b662a1SLorenzo Bianconi .addr = 0x12, 53666b662a1SLorenzo Bianconi .mask = BIT(7), 53766b662a1SLorenzo Bianconi }, 53866b662a1SLorenzo Bianconi .bdu = { 53966b662a1SLorenzo Bianconi .addr = 0x12, 54066b662a1SLorenzo Bianconi .mask = BIT(6), 54166b662a1SLorenzo Bianconi }, 5428f2a88a2SLorenzo Bianconi .max_fifo_size = 682, 543d068e4a0SLorenzo Bianconi .id = { 54481956a93SLorenzo Bianconi { 54581956a93SLorenzo Bianconi .hw_id = ST_LSM6DSL_ID, 54681956a93SLorenzo Bianconi .name = ST_LSM6DSL_DEV_NAME, 54781956a93SLorenzo Bianconi }, { 54881956a93SLorenzo Bianconi .hw_id = ST_LSM6DSM_ID, 54981956a93SLorenzo Bianconi .name = ST_LSM6DSM_DEV_NAME, 55081956a93SLorenzo Bianconi }, { 55181956a93SLorenzo Bianconi .hw_id = ST_ISM330DLC_ID, 55281956a93SLorenzo Bianconi .name = ST_ISM330DLC_DEV_NAME, 553dbcd2088SLorenzo Bianconi }, { 554dbcd2088SLorenzo Bianconi .hw_id = ST_LSM6DS3TRC_ID, 555dbcd2088SLorenzo Bianconi .name = ST_LSM6DS3TRC_DEV_NAME, 55681956a93SLorenzo Bianconi }, 557d068e4a0SLorenzo Bianconi }, 558f48bc49bSLorenzo Bianconi .channels = { 559f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 560f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 561f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 562f48bc49bSLorenzo Bianconi }, 563f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 564f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 565f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 566f48bc49bSLorenzo Bianconi }, 567f48bc49bSLorenzo Bianconi }, 56840dd7343SLorenzo Bianconi .odr_table = { 56940dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 57040dd7343SLorenzo Bianconi .reg = { 57140dd7343SLorenzo Bianconi .addr = 0x10, 57240dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 57340dd7343SLorenzo Bianconi }, 574f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 575f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 576f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 577f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 578f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 579f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 58059af4e20SLorenzo Bianconi .odr_len = 6, 58140dd7343SLorenzo Bianconi }, 58240dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 58340dd7343SLorenzo Bianconi .reg = { 58440dd7343SLorenzo Bianconi .addr = 0x11, 58540dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 58640dd7343SLorenzo Bianconi }, 587f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 588f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 589f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 590f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 591f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 592f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 59359af4e20SLorenzo Bianconi .odr_len = 6, 59440dd7343SLorenzo Bianconi }, 59540dd7343SLorenzo Bianconi }, 596640aca3fSLorenzo Bianconi .fs_table = { 597640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 598640aca3fSLorenzo Bianconi .reg = { 599640aca3fSLorenzo Bianconi .addr = 0x10, 600640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 601640aca3fSLorenzo Bianconi }, 602640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 603640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 604640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 605640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 60685ae3aeeSLorenzo Bianconi .fs_len = 4, 607640aca3fSLorenzo Bianconi }, 608640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 609640aca3fSLorenzo Bianconi .reg = { 610640aca3fSLorenzo Bianconi .addr = 0x11, 611640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 612640aca3fSLorenzo Bianconi }, 613640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 614640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 615640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 616640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 61785ae3aeeSLorenzo Bianconi .fs_len = 4, 618640aca3fSLorenzo Bianconi }, 619640aca3fSLorenzo Bianconi }, 6207e906103SLorenzo Bianconi .irq_config = { 6217e906103SLorenzo Bianconi .irq1 = { 6227e906103SLorenzo Bianconi .addr = 0x0d, 6237e906103SLorenzo Bianconi .mask = BIT(3), 6247e906103SLorenzo Bianconi }, 6257e906103SLorenzo Bianconi .irq2 = { 6267e906103SLorenzo Bianconi .addr = 0x0e, 6277e906103SLorenzo Bianconi .mask = BIT(3), 6287e906103SLorenzo Bianconi }, 6297e906103SLorenzo Bianconi .lir = { 6307e906103SLorenzo Bianconi .addr = 0x58, 6317e906103SLorenzo Bianconi .mask = BIT(0), 6327e906103SLorenzo Bianconi }, 6337e906103SLorenzo Bianconi .irq1_func = { 6347e906103SLorenzo Bianconi .addr = 0x5e, 6357e906103SLorenzo Bianconi .mask = BIT(5), 6367e906103SLorenzo Bianconi }, 6377e906103SLorenzo Bianconi .irq2_func = { 6387e906103SLorenzo Bianconi .addr = 0x5f, 6397e906103SLorenzo Bianconi .mask = BIT(5), 6407e906103SLorenzo Bianconi }, 64131fe8d4eSLorenzo Bianconi .hla = { 64231fe8d4eSLorenzo Bianconi .addr = 0x12, 64331fe8d4eSLorenzo Bianconi .mask = BIT(5), 64431fe8d4eSLorenzo Bianconi }, 64531fe8d4eSLorenzo Bianconi .od = { 64631fe8d4eSLorenzo Bianconi .addr = 0x12, 64731fe8d4eSLorenzo Bianconi .mask = BIT(4), 64831fe8d4eSLorenzo Bianconi }, 6497e906103SLorenzo Bianconi }, 6507ca3ac9eSLorenzo Bianconi .decimator = { 6517ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 6527ca3ac9eSLorenzo Bianconi .addr = 0x08, 6537ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 6547ca3ac9eSLorenzo Bianconi }, 6557ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 6567ca3ac9eSLorenzo Bianconi .addr = 0x08, 6577ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 6587ca3ac9eSLorenzo Bianconi }, 6597ca3ac9eSLorenzo Bianconi }, 66092617c15SLorenzo Bianconi .fifo_ops = { 6613b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 66250ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 66392617c15SLorenzo Bianconi .fifo_th = { 66492617c15SLorenzo Bianconi .addr = 0x06, 665be75eb86SLorenzo Bianconi .mask = GENMASK(10, 0), 66692617c15SLorenzo Bianconi }, 66792617c15SLorenzo Bianconi .fifo_diff = { 66892617c15SLorenzo Bianconi .addr = 0x3a, 669be75eb86SLorenzo Bianconi .mask = GENMASK(10, 0), 67092617c15SLorenzo Bianconi }, 67192617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 67292617c15SLorenzo Bianconi }, 67321345107SLorenzo Bianconi .ts_settings = { 67421345107SLorenzo Bianconi .timer_en = { 67521345107SLorenzo Bianconi .addr = 0x19, 67621345107SLorenzo Bianconi .mask = BIT(5), 67721345107SLorenzo Bianconi }, 67821345107SLorenzo Bianconi .hr_timer = { 67921345107SLorenzo Bianconi .addr = 0x5c, 68021345107SLorenzo Bianconi .mask = BIT(4), 68121345107SLorenzo Bianconi }, 68221345107SLorenzo Bianconi .fifo_en = { 68321345107SLorenzo Bianconi .addr = 0x07, 68421345107SLorenzo Bianconi .mask = BIT(7), 68521345107SLorenzo Bianconi }, 68621345107SLorenzo Bianconi .decimator = { 68721345107SLorenzo Bianconi .addr = 0x09, 68821345107SLorenzo Bianconi .mask = GENMASK(5, 3), 68921345107SLorenzo Bianconi }, 69021345107SLorenzo Bianconi }, 691b5969abfSSean Nyekjaer .event_settings = { 692b5969abfSSean Nyekjaer .enable_reg = { 693b5969abfSSean Nyekjaer .addr = 0x58, 694b5969abfSSean Nyekjaer .mask = BIT(7), 695b5969abfSSean Nyekjaer }, 696b5969abfSSean Nyekjaer .wakeup_reg = { 697b5969abfSSean Nyekjaer .addr = 0x5B, 698b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 699b5969abfSSean Nyekjaer }, 7001aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 7011aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 7021aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 7031aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 7041aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 705b5969abfSSean Nyekjaer }, 706290a6ce1SLorenzo Bianconi }, 707801a6e0aSLorenzo Bianconi { 708801a6e0aSLorenzo Bianconi .wai = 0x6c, 70966b662a1SLorenzo Bianconi .reset = { 71066b662a1SLorenzo Bianconi .addr = 0x12, 71166b662a1SLorenzo Bianconi .mask = BIT(0), 71266b662a1SLorenzo Bianconi }, 71366b662a1SLorenzo Bianconi .boot = { 71466b662a1SLorenzo Bianconi .addr = 0x12, 71566b662a1SLorenzo Bianconi .mask = BIT(7), 71666b662a1SLorenzo Bianconi }, 71766b662a1SLorenzo Bianconi .bdu = { 71866b662a1SLorenzo Bianconi .addr = 0x12, 71966b662a1SLorenzo Bianconi .mask = BIT(6), 72066b662a1SLorenzo Bianconi }, 721801a6e0aSLorenzo Bianconi .max_fifo_size = 512, 722801a6e0aSLorenzo Bianconi .id = { 72381956a93SLorenzo Bianconi { 72481956a93SLorenzo Bianconi .hw_id = ST_LSM6DSO_ID, 72581956a93SLorenzo Bianconi .name = ST_LSM6DSO_DEV_NAME, 72681956a93SLorenzo Bianconi }, { 72781956a93SLorenzo Bianconi .hw_id = ST_LSM6DSOX_ID, 72881956a93SLorenzo Bianconi .name = ST_LSM6DSOX_DEV_NAME, 72981956a93SLorenzo Bianconi }, 730801a6e0aSLorenzo Bianconi }, 731f48bc49bSLorenzo Bianconi .channels = { 732f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 733f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 734f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 735f48bc49bSLorenzo Bianconi }, 736f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 737f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 738f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 739f48bc49bSLorenzo Bianconi }, 740f48bc49bSLorenzo Bianconi }, 741960506edSLorenzo Bianconi .drdy_mask = { 742960506edSLorenzo Bianconi .addr = 0x13, 743960506edSLorenzo Bianconi .mask = BIT(3), 744960506edSLorenzo Bianconi }, 74540dd7343SLorenzo Bianconi .odr_table = { 74640dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 74740dd7343SLorenzo Bianconi .reg = { 74840dd7343SLorenzo Bianconi .addr = 0x10, 74940dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 75040dd7343SLorenzo Bianconi }, 751f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 752f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 753f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 754f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 755f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 756f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 75759af4e20SLorenzo Bianconi .odr_len = 6, 75840dd7343SLorenzo Bianconi }, 75940dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 76040dd7343SLorenzo Bianconi .reg = { 76140dd7343SLorenzo Bianconi .addr = 0x11, 76240dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 76340dd7343SLorenzo Bianconi }, 764f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 765f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 766f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 767f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 768f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 769f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 77059af4e20SLorenzo Bianconi .odr_len = 6, 77140dd7343SLorenzo Bianconi }, 77240dd7343SLorenzo Bianconi }, 773640aca3fSLorenzo Bianconi .fs_table = { 774640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 775640aca3fSLorenzo Bianconi .reg = { 776640aca3fSLorenzo Bianconi .addr = 0x10, 777640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 778640aca3fSLorenzo Bianconi }, 779640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 780640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 781640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 782640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 78385ae3aeeSLorenzo Bianconi .fs_len = 4, 784640aca3fSLorenzo Bianconi }, 785640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 786640aca3fSLorenzo Bianconi .reg = { 787640aca3fSLorenzo Bianconi .addr = 0x11, 788640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 789640aca3fSLorenzo Bianconi }, 790640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 791640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 792640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 793640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 79485ae3aeeSLorenzo Bianconi .fs_len = 4, 795640aca3fSLorenzo Bianconi }, 796640aca3fSLorenzo Bianconi }, 7977e906103SLorenzo Bianconi .irq_config = { 7987e906103SLorenzo Bianconi .irq1 = { 7997e906103SLorenzo Bianconi .addr = 0x0d, 8007e906103SLorenzo Bianconi .mask = BIT(3), 8017e906103SLorenzo Bianconi }, 8027e906103SLorenzo Bianconi .irq2 = { 8037e906103SLorenzo Bianconi .addr = 0x0e, 8047e906103SLorenzo Bianconi .mask = BIT(3), 8057e906103SLorenzo Bianconi }, 8067e906103SLorenzo Bianconi .lir = { 8077e906103SLorenzo Bianconi .addr = 0x56, 8087e906103SLorenzo Bianconi .mask = BIT(0), 8097e906103SLorenzo Bianconi }, 8107e906103SLorenzo Bianconi .clear_on_read = { 8117e906103SLorenzo Bianconi .addr = 0x56, 8127e906103SLorenzo Bianconi .mask = BIT(6), 8137e906103SLorenzo Bianconi }, 8143ea39d61SLorenzo Bianconi .irq1_func = { 8153ea39d61SLorenzo Bianconi .addr = 0x5e, 8163ea39d61SLorenzo Bianconi .mask = BIT(5), 8173ea39d61SLorenzo Bianconi }, 8183ea39d61SLorenzo Bianconi .irq2_func = { 8193ea39d61SLorenzo Bianconi .addr = 0x5f, 8203ea39d61SLorenzo Bianconi .mask = BIT(5), 8213ea39d61SLorenzo Bianconi }, 82231fe8d4eSLorenzo Bianconi .hla = { 82331fe8d4eSLorenzo Bianconi .addr = 0x12, 82431fe8d4eSLorenzo Bianconi .mask = BIT(5), 82531fe8d4eSLorenzo Bianconi }, 82631fe8d4eSLorenzo Bianconi .od = { 82731fe8d4eSLorenzo Bianconi .addr = 0x12, 82831fe8d4eSLorenzo Bianconi .mask = BIT(4), 82931fe8d4eSLorenzo Bianconi }, 8307e906103SLorenzo Bianconi }, 831801a6e0aSLorenzo Bianconi .batch = { 832801a6e0aSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 833801a6e0aSLorenzo Bianconi .addr = 0x09, 834801a6e0aSLorenzo Bianconi .mask = GENMASK(3, 0), 835801a6e0aSLorenzo Bianconi }, 836801a6e0aSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 837801a6e0aSLorenzo Bianconi .addr = 0x09, 838801a6e0aSLorenzo Bianconi .mask = GENMASK(7, 4), 839801a6e0aSLorenzo Bianconi }, 840801a6e0aSLorenzo Bianconi }, 841801a6e0aSLorenzo Bianconi .fifo_ops = { 8423b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 843801a6e0aSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 844801a6e0aSLorenzo Bianconi .fifo_th = { 845801a6e0aSLorenzo Bianconi .addr = 0x07, 846801a6e0aSLorenzo Bianconi .mask = GENMASK(8, 0), 847801a6e0aSLorenzo Bianconi }, 848801a6e0aSLorenzo Bianconi .fifo_diff = { 849801a6e0aSLorenzo Bianconi .addr = 0x3a, 85070575abeSmario tesi .mask = GENMASK(9, 0), 851801a6e0aSLorenzo Bianconi }, 852801a6e0aSLorenzo Bianconi .th_wl = 1, 853801a6e0aSLorenzo Bianconi }, 854801a6e0aSLorenzo Bianconi .ts_settings = { 855801a6e0aSLorenzo Bianconi .timer_en = { 856801a6e0aSLorenzo Bianconi .addr = 0x19, 857801a6e0aSLorenzo Bianconi .mask = BIT(5), 858801a6e0aSLorenzo Bianconi }, 859801a6e0aSLorenzo Bianconi .decimator = { 860801a6e0aSLorenzo Bianconi .addr = 0x0a, 861801a6e0aSLorenzo Bianconi .mask = GENMASK(7, 6), 862801a6e0aSLorenzo Bianconi }, 863cb3b6b8eSMario Tesi .freq_fine = 0x63, 864801a6e0aSLorenzo Bianconi }, 865c91c1c84SLorenzo Bianconi .shub_settings = { 866c91c1c84SLorenzo Bianconi .page_mux = { 867c91c1c84SLorenzo Bianconi .addr = 0x01, 868c91c1c84SLorenzo Bianconi .mask = BIT(6), 869c91c1c84SLorenzo Bianconi }, 870c91c1c84SLorenzo Bianconi .master_en = { 871c91c1c84SLorenzo Bianconi .addr = 0x14, 872c91c1c84SLorenzo Bianconi .mask = BIT(2), 873c91c1c84SLorenzo Bianconi }, 874c91c1c84SLorenzo Bianconi .pullup_en = { 875c91c1c84SLorenzo Bianconi .addr = 0x14, 876c91c1c84SLorenzo Bianconi .mask = BIT(3), 877c91c1c84SLorenzo Bianconi }, 878c91c1c84SLorenzo Bianconi .aux_sens = { 879c91c1c84SLorenzo Bianconi .addr = 0x14, 880c91c1c84SLorenzo Bianconi .mask = GENMASK(1, 0), 881c91c1c84SLorenzo Bianconi }, 8826d0205fdSLorenzo Bianconi .wr_once = { 8836d0205fdSLorenzo Bianconi .addr = 0x14, 8846d0205fdSLorenzo Bianconi .mask = BIT(6), 8856d0205fdSLorenzo Bianconi }, 886c91c1c84SLorenzo Bianconi .shub_out = 0x02, 887c91c1c84SLorenzo Bianconi .slv0_addr = 0x15, 888c91c1c84SLorenzo Bianconi .dw_slv0_addr = 0x21, 8896d0205fdSLorenzo Bianconi .batch_en = BIT(3), 8903ea39d61SLorenzo Bianconi }, 8913ea39d61SLorenzo Bianconi .event_settings = { 8923ea39d61SLorenzo Bianconi .enable_reg = { 8933ea39d61SLorenzo Bianconi .addr = 0x58, 8943ea39d61SLorenzo Bianconi .mask = BIT(7), 8953ea39d61SLorenzo Bianconi }, 8963ea39d61SLorenzo Bianconi .wakeup_reg = { 8973ea39d61SLorenzo Bianconi .addr = 0x5b, 8983ea39d61SLorenzo Bianconi .mask = GENMASK(5, 0), 8993ea39d61SLorenzo Bianconi }, 9003ea39d61SLorenzo Bianconi .wakeup_src_reg = 0x1b, 9013ea39d61SLorenzo Bianconi .wakeup_src_status_mask = BIT(3), 9023ea39d61SLorenzo Bianconi .wakeup_src_z_mask = BIT(0), 9033ea39d61SLorenzo Bianconi .wakeup_src_y_mask = BIT(1), 9043ea39d61SLorenzo Bianconi .wakeup_src_x_mask = BIT(2), 9053ea39d61SLorenzo Bianconi }, 906801a6e0aSLorenzo Bianconi }, 9073054c4ffSLorenzo Bianconi { 9083054c4ffSLorenzo Bianconi .wai = 0x6b, 90966b662a1SLorenzo Bianconi .reset = { 91066b662a1SLorenzo Bianconi .addr = 0x12, 91166b662a1SLorenzo Bianconi .mask = BIT(0), 91266b662a1SLorenzo Bianconi }, 91366b662a1SLorenzo Bianconi .boot = { 91466b662a1SLorenzo Bianconi .addr = 0x12, 91566b662a1SLorenzo Bianconi .mask = BIT(7), 91666b662a1SLorenzo Bianconi }, 91766b662a1SLorenzo Bianconi .bdu = { 91866b662a1SLorenzo Bianconi .addr = 0x12, 91966b662a1SLorenzo Bianconi .mask = BIT(6), 92066b662a1SLorenzo Bianconi }, 9213054c4ffSLorenzo Bianconi .max_fifo_size = 512, 9223054c4ffSLorenzo Bianconi .id = { 92381956a93SLorenzo Bianconi { 92481956a93SLorenzo Bianconi .hw_id = ST_ASM330LHH_ID, 92581956a93SLorenzo Bianconi .name = ST_ASM330LHH_DEV_NAME, 92681956a93SLorenzo Bianconi }, 9273054c4ffSLorenzo Bianconi }, 928f48bc49bSLorenzo Bianconi .channels = { 929f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 930f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 931f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 932f48bc49bSLorenzo Bianconi }, 933f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 934f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 935f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 936f48bc49bSLorenzo Bianconi }, 937f48bc49bSLorenzo Bianconi }, 938960506edSLorenzo Bianconi .drdy_mask = { 939960506edSLorenzo Bianconi .addr = 0x13, 940960506edSLorenzo Bianconi .mask = BIT(3), 941960506edSLorenzo Bianconi }, 94240dd7343SLorenzo Bianconi .odr_table = { 94340dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 94440dd7343SLorenzo Bianconi .reg = { 94540dd7343SLorenzo Bianconi .addr = 0x10, 94640dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 94740dd7343SLorenzo Bianconi }, 948f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 949f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 950f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 951f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 952f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 953f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 95459af4e20SLorenzo Bianconi .odr_len = 6, 95540dd7343SLorenzo Bianconi }, 95640dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 95740dd7343SLorenzo Bianconi .reg = { 95840dd7343SLorenzo Bianconi .addr = 0x11, 95940dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 96040dd7343SLorenzo Bianconi }, 961f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 962f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 963f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 964f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 965f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 966f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 96759af4e20SLorenzo Bianconi .odr_len = 6, 96840dd7343SLorenzo Bianconi }, 96940dd7343SLorenzo Bianconi }, 970640aca3fSLorenzo Bianconi .fs_table = { 971640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 972640aca3fSLorenzo Bianconi .reg = { 973640aca3fSLorenzo Bianconi .addr = 0x10, 974640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 975640aca3fSLorenzo Bianconi }, 976640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 977640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 978640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 979640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 98085ae3aeeSLorenzo Bianconi .fs_len = 4, 981640aca3fSLorenzo Bianconi }, 982640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 983640aca3fSLorenzo Bianconi .reg = { 984640aca3fSLorenzo Bianconi .addr = 0x11, 985640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 986640aca3fSLorenzo Bianconi }, 987640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 988640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 989640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 990640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 99185ae3aeeSLorenzo Bianconi .fs_len = 4, 992640aca3fSLorenzo Bianconi }, 993640aca3fSLorenzo Bianconi }, 9947e906103SLorenzo Bianconi .irq_config = { 9957e906103SLorenzo Bianconi .irq1 = { 9967e906103SLorenzo Bianconi .addr = 0x0d, 9977e906103SLorenzo Bianconi .mask = BIT(3), 9987e906103SLorenzo Bianconi }, 9997e906103SLorenzo Bianconi .irq2 = { 10007e906103SLorenzo Bianconi .addr = 0x0e, 10017e906103SLorenzo Bianconi .mask = BIT(3), 10027e906103SLorenzo Bianconi }, 10037e906103SLorenzo Bianconi .lir = { 10047e906103SLorenzo Bianconi .addr = 0x56, 10057e906103SLorenzo Bianconi .mask = BIT(0), 10067e906103SLorenzo Bianconi }, 10077e906103SLorenzo Bianconi .clear_on_read = { 10087e906103SLorenzo Bianconi .addr = 0x56, 10097e906103SLorenzo Bianconi .mask = BIT(6), 10107e906103SLorenzo Bianconi }, 10117e906103SLorenzo Bianconi .irq1_func = { 10127e906103SLorenzo Bianconi .addr = 0x5e, 10137e906103SLorenzo Bianconi .mask = BIT(5), 10147e906103SLorenzo Bianconi }, 10157e906103SLorenzo Bianconi .irq2_func = { 10167e906103SLorenzo Bianconi .addr = 0x5f, 10177e906103SLorenzo Bianconi .mask = BIT(5), 10187e906103SLorenzo Bianconi }, 101931fe8d4eSLorenzo Bianconi .hla = { 102031fe8d4eSLorenzo Bianconi .addr = 0x12, 102131fe8d4eSLorenzo Bianconi .mask = BIT(5), 102231fe8d4eSLorenzo Bianconi }, 102331fe8d4eSLorenzo Bianconi .od = { 102431fe8d4eSLorenzo Bianconi .addr = 0x12, 102531fe8d4eSLorenzo Bianconi .mask = BIT(4), 102631fe8d4eSLorenzo Bianconi }, 10277e906103SLorenzo Bianconi }, 10283054c4ffSLorenzo Bianconi .batch = { 10293054c4ffSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 10303054c4ffSLorenzo Bianconi .addr = 0x09, 10313054c4ffSLorenzo Bianconi .mask = GENMASK(3, 0), 10323054c4ffSLorenzo Bianconi }, 10333054c4ffSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 10343054c4ffSLorenzo Bianconi .addr = 0x09, 10353054c4ffSLorenzo Bianconi .mask = GENMASK(7, 4), 10363054c4ffSLorenzo Bianconi }, 10373054c4ffSLorenzo Bianconi }, 10383054c4ffSLorenzo Bianconi .fifo_ops = { 10393b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 10403054c4ffSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 10413054c4ffSLorenzo Bianconi .fifo_th = { 10423054c4ffSLorenzo Bianconi .addr = 0x07, 10433054c4ffSLorenzo Bianconi .mask = GENMASK(8, 0), 10443054c4ffSLorenzo Bianconi }, 10453054c4ffSLorenzo Bianconi .fifo_diff = { 10463054c4ffSLorenzo Bianconi .addr = 0x3a, 104770575abeSmario tesi .mask = GENMASK(9, 0), 10483054c4ffSLorenzo Bianconi }, 10493054c4ffSLorenzo Bianconi .th_wl = 1, 10503054c4ffSLorenzo Bianconi }, 10513054c4ffSLorenzo Bianconi .ts_settings = { 10523054c4ffSLorenzo Bianconi .timer_en = { 10533054c4ffSLorenzo Bianconi .addr = 0x19, 10543054c4ffSLorenzo Bianconi .mask = BIT(5), 10553054c4ffSLorenzo Bianconi }, 10563054c4ffSLorenzo Bianconi .decimator = { 10573054c4ffSLorenzo Bianconi .addr = 0x0a, 10583054c4ffSLorenzo Bianconi .mask = GENMASK(7, 6), 10593054c4ffSLorenzo Bianconi }, 1060cb3b6b8eSMario Tesi .freq_fine = 0x63, 10613054c4ffSLorenzo Bianconi }, 1062b5969abfSSean Nyekjaer .event_settings = { 1063b5969abfSSean Nyekjaer .enable_reg = { 1064b5969abfSSean Nyekjaer .addr = 0x58, 1065b5969abfSSean Nyekjaer .mask = BIT(7), 1066b5969abfSSean Nyekjaer }, 1067b5969abfSSean Nyekjaer .wakeup_reg = { 1068b5969abfSSean Nyekjaer .addr = 0x5B, 1069b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 1070b5969abfSSean Nyekjaer }, 10711aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 10721aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 10731aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 10741aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 10751aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 1076b5969abfSSean Nyekjaer }, 10773054c4ffSLorenzo Bianconi }, 107843901008SLorenzo Bianconi { 107943901008SLorenzo Bianconi .wai = 0x6b, 108066b662a1SLorenzo Bianconi .reset = { 108166b662a1SLorenzo Bianconi .addr = 0x12, 108266b662a1SLorenzo Bianconi .mask = BIT(0), 108366b662a1SLorenzo Bianconi }, 108466b662a1SLorenzo Bianconi .boot = { 108566b662a1SLorenzo Bianconi .addr = 0x12, 108666b662a1SLorenzo Bianconi .mask = BIT(7), 108766b662a1SLorenzo Bianconi }, 108866b662a1SLorenzo Bianconi .bdu = { 108966b662a1SLorenzo Bianconi .addr = 0x12, 109066b662a1SLorenzo Bianconi .mask = BIT(6), 109166b662a1SLorenzo Bianconi }, 109243901008SLorenzo Bianconi .max_fifo_size = 512, 109343901008SLorenzo Bianconi .id = { 109481956a93SLorenzo Bianconi { 109581956a93SLorenzo Bianconi .hw_id = ST_LSM6DSR_ID, 109681956a93SLorenzo Bianconi .name = ST_LSM6DSR_DEV_NAME, 1097db947a79SLorenzo Bianconi }, { 1098db947a79SLorenzo Bianconi .hw_id = ST_ISM330DHCX_ID, 1099db947a79SLorenzo Bianconi .name = ST_ISM330DHCX_DEV_NAME, 1100cf9c71b3SLorenzo Bianconi }, { 1101cf9c71b3SLorenzo Bianconi .hw_id = ST_LSM6DSRX_ID, 1102cf9c71b3SLorenzo Bianconi .name = ST_LSM6DSRX_DEV_NAME, 110381956a93SLorenzo Bianconi }, 110443901008SLorenzo Bianconi }, 1105f48bc49bSLorenzo Bianconi .channels = { 1106f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 1107f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 1108f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 1109f48bc49bSLorenzo Bianconi }, 1110f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 1111f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 1112f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 1113f48bc49bSLorenzo Bianconi }, 1114f48bc49bSLorenzo Bianconi }, 1115960506edSLorenzo Bianconi .drdy_mask = { 1116960506edSLorenzo Bianconi .addr = 0x13, 1117960506edSLorenzo Bianconi .mask = BIT(3), 1118960506edSLorenzo Bianconi }, 111940dd7343SLorenzo Bianconi .odr_table = { 112040dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 112140dd7343SLorenzo Bianconi .reg = { 112240dd7343SLorenzo Bianconi .addr = 0x10, 112340dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 112440dd7343SLorenzo Bianconi }, 1125f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 1126f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 1127f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 1128f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 1129f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 1130f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 113159af4e20SLorenzo Bianconi .odr_len = 6, 113240dd7343SLorenzo Bianconi }, 113340dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 113440dd7343SLorenzo Bianconi .reg = { 113540dd7343SLorenzo Bianconi .addr = 0x11, 113640dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 113740dd7343SLorenzo Bianconi }, 1138f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 1139f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 1140f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 1141f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 1142f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 1143f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 114459af4e20SLorenzo Bianconi .odr_len = 6, 114540dd7343SLorenzo Bianconi }, 114640dd7343SLorenzo Bianconi }, 1147640aca3fSLorenzo Bianconi .fs_table = { 1148640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 1149640aca3fSLorenzo Bianconi .reg = { 1150640aca3fSLorenzo Bianconi .addr = 0x10, 1151640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 1152640aca3fSLorenzo Bianconi }, 1153640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 1154640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 1155640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 1156640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 115785ae3aeeSLorenzo Bianconi .fs_len = 4, 1158640aca3fSLorenzo Bianconi }, 1159640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 1160640aca3fSLorenzo Bianconi .reg = { 1161640aca3fSLorenzo Bianconi .addr = 0x11, 1162640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 1163640aca3fSLorenzo Bianconi }, 1164640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 1165640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 1166640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 1167640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 116885ae3aeeSLorenzo Bianconi .fs_len = 4, 1169640aca3fSLorenzo Bianconi }, 1170640aca3fSLorenzo Bianconi }, 11717e906103SLorenzo Bianconi .irq_config = { 11727e906103SLorenzo Bianconi .irq1 = { 11737e906103SLorenzo Bianconi .addr = 0x0d, 11747e906103SLorenzo Bianconi .mask = BIT(3), 11757e906103SLorenzo Bianconi }, 11767e906103SLorenzo Bianconi .irq2 = { 11777e906103SLorenzo Bianconi .addr = 0x0e, 11787e906103SLorenzo Bianconi .mask = BIT(3), 11797e906103SLorenzo Bianconi }, 11807e906103SLorenzo Bianconi .lir = { 11817e906103SLorenzo Bianconi .addr = 0x56, 11827e906103SLorenzo Bianconi .mask = BIT(0), 11837e906103SLorenzo Bianconi }, 11847e906103SLorenzo Bianconi .clear_on_read = { 11857e906103SLorenzo Bianconi .addr = 0x56, 11867e906103SLorenzo Bianconi .mask = BIT(6), 11877e906103SLorenzo Bianconi }, 11887e906103SLorenzo Bianconi .irq1_func = { 11897e906103SLorenzo Bianconi .addr = 0x5e, 11907e906103SLorenzo Bianconi .mask = BIT(5), 11917e906103SLorenzo Bianconi }, 11927e906103SLorenzo Bianconi .irq2_func = { 11937e906103SLorenzo Bianconi .addr = 0x5f, 11947e906103SLorenzo Bianconi .mask = BIT(5), 11957e906103SLorenzo Bianconi }, 119631fe8d4eSLorenzo Bianconi .hla = { 119731fe8d4eSLorenzo Bianconi .addr = 0x12, 119831fe8d4eSLorenzo Bianconi .mask = BIT(5), 119931fe8d4eSLorenzo Bianconi }, 120031fe8d4eSLorenzo Bianconi .od = { 120131fe8d4eSLorenzo Bianconi .addr = 0x12, 120231fe8d4eSLorenzo Bianconi .mask = BIT(4), 120331fe8d4eSLorenzo Bianconi }, 12047e906103SLorenzo Bianconi }, 120543901008SLorenzo Bianconi .batch = { 120643901008SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 120743901008SLorenzo Bianconi .addr = 0x09, 120843901008SLorenzo Bianconi .mask = GENMASK(3, 0), 120943901008SLorenzo Bianconi }, 121043901008SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 121143901008SLorenzo Bianconi .addr = 0x09, 121243901008SLorenzo Bianconi .mask = GENMASK(7, 4), 121343901008SLorenzo Bianconi }, 121443901008SLorenzo Bianconi }, 121543901008SLorenzo Bianconi .fifo_ops = { 12163b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 121743901008SLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 121843901008SLorenzo Bianconi .fifo_th = { 121943901008SLorenzo Bianconi .addr = 0x07, 122043901008SLorenzo Bianconi .mask = GENMASK(8, 0), 122143901008SLorenzo Bianconi }, 122243901008SLorenzo Bianconi .fifo_diff = { 122343901008SLorenzo Bianconi .addr = 0x3a, 122470575abeSmario tesi .mask = GENMASK(9, 0), 122543901008SLorenzo Bianconi }, 122643901008SLorenzo Bianconi .th_wl = 1, 122743901008SLorenzo Bianconi }, 122843901008SLorenzo Bianconi .ts_settings = { 122943901008SLorenzo Bianconi .timer_en = { 123043901008SLorenzo Bianconi .addr = 0x19, 123143901008SLorenzo Bianconi .mask = BIT(5), 123243901008SLorenzo Bianconi }, 123343901008SLorenzo Bianconi .decimator = { 123443901008SLorenzo Bianconi .addr = 0x0a, 123543901008SLorenzo Bianconi .mask = GENMASK(7, 6), 123643901008SLorenzo Bianconi }, 1237cb3b6b8eSMario Tesi .freq_fine = 0x63, 123843901008SLorenzo Bianconi }, 123943901008SLorenzo Bianconi .shub_settings = { 124043901008SLorenzo Bianconi .page_mux = { 124143901008SLorenzo Bianconi .addr = 0x01, 124243901008SLorenzo Bianconi .mask = BIT(6), 124343901008SLorenzo Bianconi }, 124443901008SLorenzo Bianconi .master_en = { 124543901008SLorenzo Bianconi .addr = 0x14, 124643901008SLorenzo Bianconi .mask = BIT(2), 124743901008SLorenzo Bianconi }, 124843901008SLorenzo Bianconi .pullup_en = { 124943901008SLorenzo Bianconi .addr = 0x14, 125043901008SLorenzo Bianconi .mask = BIT(3), 125143901008SLorenzo Bianconi }, 125243901008SLorenzo Bianconi .aux_sens = { 125343901008SLorenzo Bianconi .addr = 0x14, 125443901008SLorenzo Bianconi .mask = GENMASK(1, 0), 125543901008SLorenzo Bianconi }, 125643901008SLorenzo Bianconi .wr_once = { 125743901008SLorenzo Bianconi .addr = 0x14, 125843901008SLorenzo Bianconi .mask = BIT(6), 125943901008SLorenzo Bianconi }, 126043901008SLorenzo Bianconi .shub_out = 0x02, 126143901008SLorenzo Bianconi .slv0_addr = 0x15, 126243901008SLorenzo Bianconi .dw_slv0_addr = 0x21, 126343901008SLorenzo Bianconi .batch_en = BIT(3), 1264b5969abfSSean Nyekjaer }, 1265b5969abfSSean Nyekjaer .event_settings = { 1266b5969abfSSean Nyekjaer .enable_reg = { 1267b5969abfSSean Nyekjaer .addr = 0x58, 1268b5969abfSSean Nyekjaer .mask = BIT(7), 1269b5969abfSSean Nyekjaer }, 1270b5969abfSSean Nyekjaer .wakeup_reg = { 1271b5969abfSSean Nyekjaer .addr = 0x5B, 1272b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 1273b5969abfSSean Nyekjaer }, 12741aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 12751aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 12761aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 12771aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 12781aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 127943901008SLorenzo Bianconi } 128043901008SLorenzo Bianconi }, 1281290a6ce1SLorenzo Bianconi }; 1282290a6ce1SLorenzo Bianconi 1283c91c1c84SLorenzo Bianconi int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable) 1284c91c1c84SLorenzo Bianconi { 1285c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 1286c91c1c84SLorenzo Bianconi unsigned int data; 1287c91c1c84SLorenzo Bianconi int err; 1288c91c1c84SLorenzo Bianconi 1289c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 1290c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask); 1291c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr, 1292c91c1c84SLorenzo Bianconi hub_settings->page_mux.mask, data); 1293c91c1c84SLorenzo Bianconi usleep_range(100, 150); 1294c91c1c84SLorenzo Bianconi 1295c91c1c84SLorenzo Bianconi return err; 1296c91c1c84SLorenzo Bianconi } 1297c91c1c84SLorenzo Bianconi 129881956a93SLorenzo Bianconi static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id, 129981956a93SLorenzo Bianconi const char **name) 1300290a6ce1SLorenzo Bianconi { 130151a8b707SLorenzo Bianconi int err, i, j, data; 1302290a6ce1SLorenzo Bianconi 1303290a6ce1SLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) { 1304d068e4a0SLorenzo Bianconi for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) { 130581956a93SLorenzo Bianconi if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id) 1306d068e4a0SLorenzo Bianconi break; 1307d068e4a0SLorenzo Bianconi } 1308d068e4a0SLorenzo Bianconi if (j < ST_LSM6DSX_MAX_ID) 1309290a6ce1SLorenzo Bianconi break; 1310290a6ce1SLorenzo Bianconi } 1311290a6ce1SLorenzo Bianconi 1312290a6ce1SLorenzo Bianconi if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) { 1313290a6ce1SLorenzo Bianconi dev_err(hw->dev, "unsupported hw id [%02x]\n", id); 1314290a6ce1SLorenzo Bianconi return -ENODEV; 1315290a6ce1SLorenzo Bianconi } 1316290a6ce1SLorenzo Bianconi 131751a8b707SLorenzo Bianconi err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data); 1318290a6ce1SLorenzo Bianconi if (err < 0) { 1319290a6ce1SLorenzo Bianconi dev_err(hw->dev, "failed to read whoami register\n"); 1320290a6ce1SLorenzo Bianconi return err; 1321290a6ce1SLorenzo Bianconi } 1322290a6ce1SLorenzo Bianconi 1323290a6ce1SLorenzo Bianconi if (data != st_lsm6dsx_sensor_settings[i].wai) { 1324290a6ce1SLorenzo Bianconi dev_err(hw->dev, "unsupported whoami [%02x]\n", data); 1325290a6ce1SLorenzo Bianconi return -ENODEV; 1326290a6ce1SLorenzo Bianconi } 1327290a6ce1SLorenzo Bianconi 132881956a93SLorenzo Bianconi *name = st_lsm6dsx_sensor_settings[i].id[j].name; 1329290a6ce1SLorenzo Bianconi hw->settings = &st_lsm6dsx_sensor_settings[i]; 1330290a6ce1SLorenzo Bianconi 1331290a6ce1SLorenzo Bianconi return 0; 1332290a6ce1SLorenzo Bianconi } 1333290a6ce1SLorenzo Bianconi 1334290a6ce1SLorenzo Bianconi static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, 1335290a6ce1SLorenzo Bianconi u32 gain) 1336290a6ce1SLorenzo Bianconi { 1337640aca3fSLorenzo Bianconi const struct st_lsm6dsx_fs_table_entry *fs_table; 1338739aff87SLorenzo Bianconi unsigned int data; 1339290a6ce1SLorenzo Bianconi int i, err; 1340290a6ce1SLorenzo Bianconi 1341640aca3fSLorenzo Bianconi fs_table = &sensor->hw->settings->fs_table[sensor->id]; 134285ae3aeeSLorenzo Bianconi for (i = 0; i < fs_table->fs_len; i++) { 1343640aca3fSLorenzo Bianconi if (fs_table->fs_avl[i].gain == gain) 1344290a6ce1SLorenzo Bianconi break; 134585ae3aeeSLorenzo Bianconi } 1346290a6ce1SLorenzo Bianconi 134785ae3aeeSLorenzo Bianconi if (i == fs_table->fs_len) 1348290a6ce1SLorenzo Bianconi return -EINVAL; 1349290a6ce1SLorenzo Bianconi 1350640aca3fSLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val, 1351640aca3fSLorenzo Bianconi fs_table->reg.mask); 1352640aca3fSLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr, 1353640aca3fSLorenzo Bianconi fs_table->reg.mask, data); 1354290a6ce1SLorenzo Bianconi if (err < 0) 1355290a6ce1SLorenzo Bianconi return err; 1356290a6ce1SLorenzo Bianconi 1357290a6ce1SLorenzo Bianconi sensor->gain = gain; 1358290a6ce1SLorenzo Bianconi 1359290a6ce1SLorenzo Bianconi return 0; 1360290a6ce1SLorenzo Bianconi } 1361290a6ce1SLorenzo Bianconi 1362f8710f03SLorenzo Bianconi int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val) 1363290a6ce1SLorenzo Bianconi { 136440dd7343SLorenzo Bianconi const struct st_lsm6dsx_odr_table_entry *odr_table; 13652ccc1503SLorenzo Bianconi int i; 1366290a6ce1SLorenzo Bianconi 136740dd7343SLorenzo Bianconi odr_table = &sensor->hw->settings->odr_table[sensor->id]; 136859af4e20SLorenzo Bianconi for (i = 0; i < odr_table->odr_len; i++) { 13696ffb55e5SLorenzo Bianconi /* 13706ffb55e5SLorenzo Bianconi * ext devices can run at different odr respect to 13716ffb55e5SLorenzo Bianconi * accel sensor 13726ffb55e5SLorenzo Bianconi */ 1373f8710f03SLorenzo Bianconi if (odr_table->odr_avl[i].milli_hz >= odr) 1374290a6ce1SLorenzo Bianconi break; 137559af4e20SLorenzo Bianconi } 1376290a6ce1SLorenzo Bianconi 137759af4e20SLorenzo Bianconi if (i == odr_table->odr_len) 1378290a6ce1SLorenzo Bianconi return -EINVAL; 1379290a6ce1SLorenzo Bianconi 138040dd7343SLorenzo Bianconi *val = odr_table->odr_avl[i].val; 1381f8710f03SLorenzo Bianconi return odr_table->odr_avl[i].milli_hz; 1382290a6ce1SLorenzo Bianconi } 1383290a6ce1SLorenzo Bianconi 1384f8710f03SLorenzo Bianconi static int 1385f8710f03SLorenzo Bianconi st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u32 odr, 13866ffb55e5SLorenzo Bianconi enum st_lsm6dsx_sensor_id id) 13872ccc1503SLorenzo Bianconi { 13886ffb55e5SLorenzo Bianconi struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]); 13896ffb55e5SLorenzo Bianconi 13906ffb55e5SLorenzo Bianconi if (odr > 0) { 13916ffb55e5SLorenzo Bianconi if (hw->enable_mask & BIT(id)) 1392f8710f03SLorenzo Bianconi return max_t(u32, ref->odr, odr); 13936ffb55e5SLorenzo Bianconi else 13946ffb55e5SLorenzo Bianconi return odr; 13956ffb55e5SLorenzo Bianconi } else { 13966ffb55e5SLorenzo Bianconi return (hw->enable_mask & BIT(id)) ? ref->odr : 0; 13976ffb55e5SLorenzo Bianconi } 13986ffb55e5SLorenzo Bianconi } 13996ffb55e5SLorenzo Bianconi 1400f8710f03SLorenzo Bianconi static int 1401f8710f03SLorenzo Bianconi st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u32 req_odr) 14026ffb55e5SLorenzo Bianconi { 14036ffb55e5SLorenzo Bianconi struct st_lsm6dsx_sensor *ref_sensor = sensor; 140451a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 140551a8b707SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 1406739aff87SLorenzo Bianconi unsigned int data; 14076ffb55e5SLorenzo Bianconi u8 val = 0; 14082ccc1503SLorenzo Bianconi int err; 14092ccc1503SLorenzo Bianconi 14106ffb55e5SLorenzo Bianconi switch (sensor->id) { 14116ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT0: 14126ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT1: 14136ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT2: 14146ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_ACC: { 1415f8710f03SLorenzo Bianconi u32 odr; 14166ffb55e5SLorenzo Bianconi int i; 14176ffb55e5SLorenzo Bianconi 14186ffb55e5SLorenzo Bianconi /* 14196ffb55e5SLorenzo Bianconi * i2c embedded controller relies on the accelerometer sensor as 14206ffb55e5SLorenzo Bianconi * bus read/write trigger so we need to enable accel device 14216ffb55e5SLorenzo Bianconi * at odr = max(accel_odr, ext_odr) in order to properly 14226ffb55e5SLorenzo Bianconi * communicate with i2c slave devices 14236ffb55e5SLorenzo Bianconi */ 14246ffb55e5SLorenzo Bianconi ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); 14256ffb55e5SLorenzo Bianconi for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) { 14266ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i] || i == sensor->id) 14276ffb55e5SLorenzo Bianconi continue; 14286ffb55e5SLorenzo Bianconi 14296ffb55e5SLorenzo Bianconi odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i); 14306ffb55e5SLorenzo Bianconi if (odr != req_odr) 14316ffb55e5SLorenzo Bianconi /* device already configured */ 14326ffb55e5SLorenzo Bianconi return 0; 14336ffb55e5SLorenzo Bianconi } 14346ffb55e5SLorenzo Bianconi break; 14356ffb55e5SLorenzo Bianconi } 14366ffb55e5SLorenzo Bianconi default: 14376ffb55e5SLorenzo Bianconi break; 14386ffb55e5SLorenzo Bianconi } 14396ffb55e5SLorenzo Bianconi 14406ffb55e5SLorenzo Bianconi if (req_odr > 0) { 14416ffb55e5SLorenzo Bianconi err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val); 14422ccc1503SLorenzo Bianconi if (err < 0) 14432ccc1503SLorenzo Bianconi return err; 14446ffb55e5SLorenzo Bianconi } 14452ccc1503SLorenzo Bianconi 144640dd7343SLorenzo Bianconi reg = &hw->settings->odr_table[ref_sensor->id].reg; 1447739aff87SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask); 1448739aff87SLorenzo Bianconi return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data); 14492ccc1503SLorenzo Bianconi } 14502ccc1503SLorenzo Bianconi 145117750443SLorenzo Bianconi int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, 145217750443SLorenzo Bianconi bool enable) 1453290a6ce1SLorenzo Bianconi { 145451a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1455f8710f03SLorenzo Bianconi u32 odr = enable ? sensor->odr : 0; 1456290a6ce1SLorenzo Bianconi int err; 1457290a6ce1SLorenzo Bianconi 145817750443SLorenzo Bianconi err = st_lsm6dsx_set_odr(sensor, odr); 1459290a6ce1SLorenzo Bianconi if (err < 0) 1460290a6ce1SLorenzo Bianconi return err; 1461290a6ce1SLorenzo Bianconi 146217750443SLorenzo Bianconi if (enable) 146317750443SLorenzo Bianconi hw->enable_mask |= BIT(sensor->id); 146417750443SLorenzo Bianconi else 146517750443SLorenzo Bianconi hw->enable_mask &= ~BIT(sensor->id); 1466290a6ce1SLorenzo Bianconi 1467290a6ce1SLorenzo Bianconi return 0; 1468290a6ce1SLorenzo Bianconi } 1469290a6ce1SLorenzo Bianconi 1470290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, 1471290a6ce1SLorenzo Bianconi u8 addr, int *val) 1472290a6ce1SLorenzo Bianconi { 147351a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1474290a6ce1SLorenzo Bianconi int err, delay; 1475290a6ce1SLorenzo Bianconi __le16 data; 1476290a6ce1SLorenzo Bianconi 147717750443SLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, true); 1478290a6ce1SLorenzo Bianconi if (err < 0) 1479290a6ce1SLorenzo Bianconi return err; 1480290a6ce1SLorenzo Bianconi 1481f8710f03SLorenzo Bianconi delay = 1000000000 / sensor->odr; 1482290a6ce1SLorenzo Bianconi usleep_range(delay, 2 * delay); 1483290a6ce1SLorenzo Bianconi 1484739aff87SLorenzo Bianconi err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data)); 1485290a6ce1SLorenzo Bianconi if (err < 0) 1486290a6ce1SLorenzo Bianconi return err; 1487290a6ce1SLorenzo Bianconi 1488b5969abfSSean Nyekjaer if (!hw->enable_event) 148917750443SLorenzo Bianconi st_lsm6dsx_sensor_set_enable(sensor, false); 1490290a6ce1SLorenzo Bianconi 14917b9ebe42SLorenzo Bianconi *val = (s16)le16_to_cpu(data); 1492290a6ce1SLorenzo Bianconi 1493290a6ce1SLorenzo Bianconi return IIO_VAL_INT; 1494290a6ce1SLorenzo Bianconi } 1495290a6ce1SLorenzo Bianconi 1496290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev, 1497290a6ce1SLorenzo Bianconi struct iio_chan_spec const *ch, 1498290a6ce1SLorenzo Bianconi int *val, int *val2, long mask) 1499290a6ce1SLorenzo Bianconi { 1500290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1501290a6ce1SLorenzo Bianconi int ret; 1502290a6ce1SLorenzo Bianconi 1503290a6ce1SLorenzo Bianconi switch (mask) { 1504290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_RAW: 1505290a6ce1SLorenzo Bianconi ret = iio_device_claim_direct_mode(iio_dev); 1506290a6ce1SLorenzo Bianconi if (ret) 1507290a6ce1SLorenzo Bianconi break; 1508290a6ce1SLorenzo Bianconi 1509290a6ce1SLorenzo Bianconi ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val); 1510290a6ce1SLorenzo Bianconi iio_device_release_direct_mode(iio_dev); 1511290a6ce1SLorenzo Bianconi break; 1512290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SAMP_FREQ: 1513f8710f03SLorenzo Bianconi *val = sensor->odr / 1000; 1514f8710f03SLorenzo Bianconi *val2 = (sensor->odr % 1000) * 1000; 1515f8710f03SLorenzo Bianconi ret = IIO_VAL_INT_PLUS_MICRO; 1516290a6ce1SLorenzo Bianconi break; 1517290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SCALE: 1518290a6ce1SLorenzo Bianconi *val = 0; 1519290a6ce1SLorenzo Bianconi *val2 = sensor->gain; 1520290a6ce1SLorenzo Bianconi ret = IIO_VAL_INT_PLUS_MICRO; 1521290a6ce1SLorenzo Bianconi break; 1522290a6ce1SLorenzo Bianconi default: 1523290a6ce1SLorenzo Bianconi ret = -EINVAL; 1524290a6ce1SLorenzo Bianconi break; 1525290a6ce1SLorenzo Bianconi } 1526290a6ce1SLorenzo Bianconi 1527290a6ce1SLorenzo Bianconi return ret; 1528290a6ce1SLorenzo Bianconi } 1529290a6ce1SLorenzo Bianconi 1530290a6ce1SLorenzo Bianconi static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev, 1531290a6ce1SLorenzo Bianconi struct iio_chan_spec const *chan, 1532290a6ce1SLorenzo Bianconi int val, int val2, long mask) 1533290a6ce1SLorenzo Bianconi { 1534290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1535290a6ce1SLorenzo Bianconi int err; 1536290a6ce1SLorenzo Bianconi 1537290a6ce1SLorenzo Bianconi err = iio_device_claim_direct_mode(iio_dev); 1538290a6ce1SLorenzo Bianconi if (err) 1539290a6ce1SLorenzo Bianconi return err; 1540290a6ce1SLorenzo Bianconi 1541290a6ce1SLorenzo Bianconi switch (mask) { 1542290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SCALE: 1543290a6ce1SLorenzo Bianconi err = st_lsm6dsx_set_full_scale(sensor, val2); 1544290a6ce1SLorenzo Bianconi break; 15452ccc1503SLorenzo Bianconi case IIO_CHAN_INFO_SAMP_FREQ: { 15462ccc1503SLorenzo Bianconi u8 data; 15472ccc1503SLorenzo Bianconi 1548f8710f03SLorenzo Bianconi val = val * 1000 + val2 / 1000; 1549fc3f6ad7SLorenzo Bianconi val = st_lsm6dsx_check_odr(sensor, val, &data); 1550fc3f6ad7SLorenzo Bianconi if (val < 0) 1551fc3f6ad7SLorenzo Bianconi err = val; 1552fc3f6ad7SLorenzo Bianconi else 15535e3c3e33SLorenzo Bianconi sensor->odr = val; 1554290a6ce1SLorenzo Bianconi break; 15552ccc1503SLorenzo Bianconi } 1556290a6ce1SLorenzo Bianconi default: 1557290a6ce1SLorenzo Bianconi err = -EINVAL; 1558290a6ce1SLorenzo Bianconi break; 1559290a6ce1SLorenzo Bianconi } 1560290a6ce1SLorenzo Bianconi 1561290a6ce1SLorenzo Bianconi iio_device_release_direct_mode(iio_dev); 1562290a6ce1SLorenzo Bianconi 1563290a6ce1SLorenzo Bianconi return err; 1564290a6ce1SLorenzo Bianconi } 1565290a6ce1SLorenzo Bianconi 1566b5969abfSSean Nyekjaer static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state) 1567b5969abfSSean Nyekjaer { 156884b2e7c3SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 156904ca37d5SLorenzo Bianconi unsigned int data; 1570b5969abfSSean Nyekjaer int err; 1571b5969abfSSean Nyekjaer 15727e906103SLorenzo Bianconi if (!hw->settings->irq_config.irq1_func.addr) 1573b5969abfSSean Nyekjaer return -ENOTSUPP; 1574b5969abfSSean Nyekjaer 157584b2e7c3SLorenzo Bianconi reg = &hw->settings->event_settings.enable_reg; 157684b2e7c3SLorenzo Bianconi if (reg->addr) { 157704ca37d5SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(state, reg->mask); 157804ca37d5SLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(hw, reg->addr, 157904ca37d5SLorenzo Bianconi reg->mask, data); 1580b5969abfSSean Nyekjaer if (err < 0) 1581b5969abfSSean Nyekjaer return err; 158284b2e7c3SLorenzo Bianconi } 1583b5969abfSSean Nyekjaer 1584b5969abfSSean Nyekjaer /* Enable wakeup interrupt */ 158504ca37d5SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(state, hw->irq_routing->mask); 158604ca37d5SLorenzo Bianconi return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing->addr, 158704ca37d5SLorenzo Bianconi hw->irq_routing->mask, data); 1588b5969abfSSean Nyekjaer } 1589b5969abfSSean Nyekjaer 1590b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event(struct iio_dev *iio_dev, 1591b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1592b5969abfSSean Nyekjaer enum iio_event_type type, 1593b5969abfSSean Nyekjaer enum iio_event_direction dir, 1594b5969abfSSean Nyekjaer enum iio_event_info info, 1595b5969abfSSean Nyekjaer int *val, int *val2) 1596b5969abfSSean Nyekjaer { 1597b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1598b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 1599b5969abfSSean Nyekjaer 1600b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1601b5969abfSSean Nyekjaer return -EINVAL; 1602b5969abfSSean Nyekjaer 1603b5969abfSSean Nyekjaer *val2 = 0; 1604b5969abfSSean Nyekjaer *val = hw->event_threshold; 1605b5969abfSSean Nyekjaer 1606b5969abfSSean Nyekjaer return IIO_VAL_INT; 1607b5969abfSSean Nyekjaer } 1608b5969abfSSean Nyekjaer 1609b307f495SLorenzo Bianconi static int 1610b307f495SLorenzo Bianconi st_lsm6dsx_write_event(struct iio_dev *iio_dev, 1611b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1612b5969abfSSean Nyekjaer enum iio_event_type type, 1613b5969abfSSean Nyekjaer enum iio_event_direction dir, 1614b5969abfSSean Nyekjaer enum iio_event_info info, 1615b5969abfSSean Nyekjaer int val, int val2) 1616b5969abfSSean Nyekjaer { 1617b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1618b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 161904ca37d5SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 162004ca37d5SLorenzo Bianconi unsigned int data; 1621b5969abfSSean Nyekjaer int err; 1622b5969abfSSean Nyekjaer 1623b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1624b5969abfSSean Nyekjaer return -EINVAL; 1625b5969abfSSean Nyekjaer 1626b5969abfSSean Nyekjaer if (val < 0 || val > 31) 1627b5969abfSSean Nyekjaer return -EINVAL; 1628b5969abfSSean Nyekjaer 162904ca37d5SLorenzo Bianconi reg = &hw->settings->event_settings.wakeup_reg; 163004ca37d5SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask); 163104ca37d5SLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(hw, reg->addr, 163204ca37d5SLorenzo Bianconi reg->mask, data); 163304ca37d5SLorenzo Bianconi if (err < 0) 1634b5969abfSSean Nyekjaer return -EINVAL; 1635b5969abfSSean Nyekjaer 1636b5969abfSSean Nyekjaer hw->event_threshold = val; 1637b5969abfSSean Nyekjaer 1638b5969abfSSean Nyekjaer return 0; 1639b5969abfSSean Nyekjaer } 1640b5969abfSSean Nyekjaer 1641b307f495SLorenzo Bianconi static int 1642b307f495SLorenzo Bianconi st_lsm6dsx_read_event_config(struct iio_dev *iio_dev, 1643b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1644b5969abfSSean Nyekjaer enum iio_event_type type, 1645b5969abfSSean Nyekjaer enum iio_event_direction dir) 1646b5969abfSSean Nyekjaer { 1647b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1648b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 1649b5969abfSSean Nyekjaer 1650b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1651b5969abfSSean Nyekjaer return -EINVAL; 1652b5969abfSSean Nyekjaer 16531aabad1fSSean Nyekjaer return !!(hw->enable_event & BIT(chan->channel2)); 1654b5969abfSSean Nyekjaer } 1655b5969abfSSean Nyekjaer 1656b307f495SLorenzo Bianconi static int 1657b307f495SLorenzo Bianconi st_lsm6dsx_write_event_config(struct iio_dev *iio_dev, 1658b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1659b5969abfSSean Nyekjaer enum iio_event_type type, 1660b307f495SLorenzo Bianconi enum iio_event_direction dir, int state) 1661b5969abfSSean Nyekjaer { 1662b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1663b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 16641aabad1fSSean Nyekjaer u8 enable_event; 1665b5969abfSSean Nyekjaer int err = 0; 1666b5969abfSSean Nyekjaer 1667b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1668b5969abfSSean Nyekjaer return -EINVAL; 1669b5969abfSSean Nyekjaer 16701aabad1fSSean Nyekjaer if (state) { 16711aabad1fSSean Nyekjaer enable_event = hw->enable_event | BIT(chan->channel2); 16721aabad1fSSean Nyekjaer 1673b5969abfSSean Nyekjaer /* do not enable events if they are already enabled */ 16741aabad1fSSean Nyekjaer if (hw->enable_event) 16751aabad1fSSean Nyekjaer goto out; 16761aabad1fSSean Nyekjaer } else { 16771aabad1fSSean Nyekjaer enable_event = hw->enable_event & ~BIT(chan->channel2); 16781aabad1fSSean Nyekjaer 16791aabad1fSSean Nyekjaer /* only turn off sensor if no events is enabled */ 16801aabad1fSSean Nyekjaer if (enable_event) 16811aabad1fSSean Nyekjaer goto out; 16821aabad1fSSean Nyekjaer } 16831aabad1fSSean Nyekjaer 16841aabad1fSSean Nyekjaer /* stop here if no changes have been made */ 16851aabad1fSSean Nyekjaer if (hw->enable_event == enable_event) 1686b5969abfSSean Nyekjaer return 0; 1687b5969abfSSean Nyekjaer 1688b5969abfSSean Nyekjaer err = st_lsm6dsx_event_setup(hw, state); 1689b5969abfSSean Nyekjaer if (err < 0) 1690b5969abfSSean Nyekjaer return err; 1691b5969abfSSean Nyekjaer 1692d278d447SLorenzo Bianconi mutex_lock(&hw->conf_lock); 1693b5969abfSSean Nyekjaer err = st_lsm6dsx_sensor_set_enable(sensor, state); 1694d278d447SLorenzo Bianconi mutex_unlock(&hw->conf_lock); 1695b5969abfSSean Nyekjaer if (err < 0) 1696b5969abfSSean Nyekjaer return err; 1697b5969abfSSean Nyekjaer 16981aabad1fSSean Nyekjaer out: 16991aabad1fSSean Nyekjaer hw->enable_event = enable_event; 1700b5969abfSSean Nyekjaer 1701b5969abfSSean Nyekjaer return 0; 1702b5969abfSSean Nyekjaer } 1703b5969abfSSean Nyekjaer 1704d40464f3SLorenzo Bianconi int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val) 1705290a6ce1SLorenzo Bianconi { 1706290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1707290a6ce1SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 17088f2a88a2SLorenzo Bianconi int err; 1709290a6ce1SLorenzo Bianconi 17108f2a88a2SLorenzo Bianconi if (val < 1 || val > hw->settings->max_fifo_size) 1711290a6ce1SLorenzo Bianconi return -EINVAL; 1712290a6ce1SLorenzo Bianconi 1713335eaedcSLorenzo Bianconi mutex_lock(&hw->conf_lock); 1714335eaedcSLorenzo Bianconi 1715290a6ce1SLorenzo Bianconi err = st_lsm6dsx_update_watermark(sensor, val); 1716335eaedcSLorenzo Bianconi 1717335eaedcSLorenzo Bianconi mutex_unlock(&hw->conf_lock); 1718335eaedcSLorenzo Bianconi 1719290a6ce1SLorenzo Bianconi if (err < 0) 1720290a6ce1SLorenzo Bianconi return err; 1721290a6ce1SLorenzo Bianconi 1722290a6ce1SLorenzo Bianconi sensor->watermark = val; 1723290a6ce1SLorenzo Bianconi 1724290a6ce1SLorenzo Bianconi return 0; 1725290a6ce1SLorenzo Bianconi } 1726290a6ce1SLorenzo Bianconi 1727290a6ce1SLorenzo Bianconi static ssize_t 1728290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev, 1729290a6ce1SLorenzo Bianconi struct device_attribute *attr, 1730290a6ce1SLorenzo Bianconi char *buf) 1731290a6ce1SLorenzo Bianconi { 1732290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); 173359af4e20SLorenzo Bianconi const struct st_lsm6dsx_odr_table_entry *odr_table; 1734290a6ce1SLorenzo Bianconi int i, len = 0; 1735290a6ce1SLorenzo Bianconi 173659af4e20SLorenzo Bianconi odr_table = &sensor->hw->settings->odr_table[sensor->id]; 173759af4e20SLorenzo Bianconi for (i = 0; i < odr_table->odr_len; i++) 1738f8710f03SLorenzo Bianconi len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%03d ", 1739f8710f03SLorenzo Bianconi odr_table->odr_avl[i].milli_hz / 1000, 1740f8710f03SLorenzo Bianconi odr_table->odr_avl[i].milli_hz % 1000); 1741290a6ce1SLorenzo Bianconi buf[len - 1] = '\n'; 1742290a6ce1SLorenzo Bianconi 1743290a6ce1SLorenzo Bianconi return len; 1744290a6ce1SLorenzo Bianconi } 1745290a6ce1SLorenzo Bianconi 1746290a6ce1SLorenzo Bianconi static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev, 1747290a6ce1SLorenzo Bianconi struct device_attribute *attr, 1748290a6ce1SLorenzo Bianconi char *buf) 1749290a6ce1SLorenzo Bianconi { 1750290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); 17510f7e1728SLorenzo Bianconi const struct st_lsm6dsx_fs_table_entry *fs_table; 1752640aca3fSLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1753290a6ce1SLorenzo Bianconi int i, len = 0; 1754290a6ce1SLorenzo Bianconi 175585ae3aeeSLorenzo Bianconi fs_table = &hw->settings->fs_table[sensor->id]; 175685ae3aeeSLorenzo Bianconi for (i = 0; i < fs_table->fs_len; i++) 1757290a6ce1SLorenzo Bianconi len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", 17580f7e1728SLorenzo Bianconi fs_table->fs_avl[i].gain); 1759290a6ce1SLorenzo Bianconi buf[len - 1] = '\n'; 1760290a6ce1SLorenzo Bianconi 1761290a6ce1SLorenzo Bianconi return len; 1762290a6ce1SLorenzo Bianconi } 1763290a6ce1SLorenzo Bianconi 1764290a6ce1SLorenzo Bianconi static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail); 1765290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_accel_scale_available, 0444, 1766290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_scale_avail, NULL, 0); 1767290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444, 1768290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_scale_avail, NULL, 0); 1769290a6ce1SLorenzo Bianconi 1770290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_acc_attributes[] = { 1771290a6ce1SLorenzo Bianconi &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 1772290a6ce1SLorenzo Bianconi &iio_dev_attr_in_accel_scale_available.dev_attr.attr, 1773290a6ce1SLorenzo Bianconi NULL, 1774290a6ce1SLorenzo Bianconi }; 1775290a6ce1SLorenzo Bianconi 1776290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_acc_attribute_group = { 1777290a6ce1SLorenzo Bianconi .attrs = st_lsm6dsx_acc_attributes, 1778290a6ce1SLorenzo Bianconi }; 1779290a6ce1SLorenzo Bianconi 1780290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_acc_info = { 1781290a6ce1SLorenzo Bianconi .attrs = &st_lsm6dsx_acc_attribute_group, 1782290a6ce1SLorenzo Bianconi .read_raw = st_lsm6dsx_read_raw, 1783290a6ce1SLorenzo Bianconi .write_raw = st_lsm6dsx_write_raw, 1784b5969abfSSean Nyekjaer .read_event_value = st_lsm6dsx_read_event, 1785b5969abfSSean Nyekjaer .write_event_value = st_lsm6dsx_write_event, 1786b5969abfSSean Nyekjaer .read_event_config = st_lsm6dsx_read_event_config, 1787b5969abfSSean Nyekjaer .write_event_config = st_lsm6dsx_write_event_config, 1788290a6ce1SLorenzo Bianconi .hwfifo_set_watermark = st_lsm6dsx_set_watermark, 1789290a6ce1SLorenzo Bianconi }; 1790290a6ce1SLorenzo Bianconi 1791290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_gyro_attributes[] = { 1792290a6ce1SLorenzo Bianconi &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 1793290a6ce1SLorenzo Bianconi &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr, 1794290a6ce1SLorenzo Bianconi NULL, 1795290a6ce1SLorenzo Bianconi }; 1796290a6ce1SLorenzo Bianconi 1797290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_gyro_attribute_group = { 1798290a6ce1SLorenzo Bianconi .attrs = st_lsm6dsx_gyro_attributes, 1799290a6ce1SLorenzo Bianconi }; 1800290a6ce1SLorenzo Bianconi 1801290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_gyro_info = { 1802290a6ce1SLorenzo Bianconi .attrs = &st_lsm6dsx_gyro_attribute_group, 1803290a6ce1SLorenzo Bianconi .read_raw = st_lsm6dsx_read_raw, 1804290a6ce1SLorenzo Bianconi .write_raw = st_lsm6dsx_write_raw, 1805290a6ce1SLorenzo Bianconi .hwfifo_set_watermark = st_lsm6dsx_set_watermark, 1806290a6ce1SLorenzo Bianconi }; 1807290a6ce1SLorenzo Bianconi 180803d4c566SAndy Shevchenko static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) 1809dba32904SLorenzo Bianconi { 181003d4c566SAndy Shevchenko struct device *dev = hw->dev; 1811dba32904SLorenzo Bianconi 181203d4c566SAndy Shevchenko if (!dev_fwnode(dev)) 1813dba32904SLorenzo Bianconi return -EINVAL; 1814dba32904SLorenzo Bianconi 181503d4c566SAndy Shevchenko return device_property_read_u32(dev, "st,drdy-int-pin", drdy_pin); 1816dba32904SLorenzo Bianconi } 1817dba32904SLorenzo Bianconi 18187e906103SLorenzo Bianconi static int 18197e906103SLorenzo Bianconi st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, 18207e906103SLorenzo Bianconi const struct st_lsm6dsx_reg **drdy_reg) 1821dba32904SLorenzo Bianconi { 1822dba32904SLorenzo Bianconi int err = 0, drdy_pin; 1823dba32904SLorenzo Bianconi 182403d4c566SAndy Shevchenko if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) { 1825dba32904SLorenzo Bianconi struct st_sensors_platform_data *pdata; 1826dba32904SLorenzo Bianconi struct device *dev = hw->dev; 1827dba32904SLorenzo Bianconi 1828dba32904SLorenzo Bianconi pdata = (struct st_sensors_platform_data *)dev->platform_data; 1829dba32904SLorenzo Bianconi drdy_pin = pdata ? pdata->drdy_int_pin : 1; 1830dba32904SLorenzo Bianconi } 1831dba32904SLorenzo Bianconi 1832dba32904SLorenzo Bianconi switch (drdy_pin) { 1833dba32904SLorenzo Bianconi case 1: 18347e906103SLorenzo Bianconi hw->irq_routing = &hw->settings->irq_config.irq1_func; 18357e906103SLorenzo Bianconi *drdy_reg = &hw->settings->irq_config.irq1; 1836dba32904SLorenzo Bianconi break; 1837dba32904SLorenzo Bianconi case 2: 18387e906103SLorenzo Bianconi hw->irq_routing = &hw->settings->irq_config.irq2_func; 18397e906103SLorenzo Bianconi *drdy_reg = &hw->settings->irq_config.irq2; 1840dba32904SLorenzo Bianconi break; 1841dba32904SLorenzo Bianconi default: 1842dba32904SLorenzo Bianconi dev_err(hw->dev, "unsupported data ready pin\n"); 1843dba32904SLorenzo Bianconi err = -EINVAL; 1844dba32904SLorenzo Bianconi break; 1845dba32904SLorenzo Bianconi } 1846dba32904SLorenzo Bianconi 1847dba32904SLorenzo Bianconi return err; 1848dba32904SLorenzo Bianconi } 1849dba32904SLorenzo Bianconi 1850c91c1c84SLorenzo Bianconi static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw) 1851c91c1c84SLorenzo Bianconi { 1852c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 1853c91c1c84SLorenzo Bianconi struct st_sensors_platform_data *pdata; 185403d4c566SAndy Shevchenko struct device *dev = hw->dev; 1855c91c1c84SLorenzo Bianconi unsigned int data; 1856c91c1c84SLorenzo Bianconi int err = 0; 1857c91c1c84SLorenzo Bianconi 1858c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 1859c91c1c84SLorenzo Bianconi 186003d4c566SAndy Shevchenko pdata = (struct st_sensors_platform_data *)dev->platform_data; 186103d4c566SAndy Shevchenko if ((dev_fwnode(dev) && device_property_read_bool(dev, "st,pullups")) || 1862c91c1c84SLorenzo Bianconi (pdata && pdata->pullups)) { 1863c91c1c84SLorenzo Bianconi err = st_lsm6dsx_set_page(hw, true); 1864c91c1c84SLorenzo Bianconi if (err < 0) 1865c91c1c84SLorenzo Bianconi return err; 1866c91c1c84SLorenzo Bianconi 1867c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask); 1868c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 1869c91c1c84SLorenzo Bianconi hub_settings->pullup_en.addr, 1870c91c1c84SLorenzo Bianconi hub_settings->pullup_en.mask, data); 1871c91c1c84SLorenzo Bianconi 1872c91c1c84SLorenzo Bianconi st_lsm6dsx_set_page(hw, false); 1873c91c1c84SLorenzo Bianconi 1874c91c1c84SLorenzo Bianconi if (err < 0) 1875c91c1c84SLorenzo Bianconi return err; 1876c91c1c84SLorenzo Bianconi } 1877c91c1c84SLorenzo Bianconi 1878c91c1c84SLorenzo Bianconi if (hub_settings->aux_sens.addr) { 1879c91c1c84SLorenzo Bianconi /* configure aux sensors */ 1880c91c1c84SLorenzo Bianconi err = st_lsm6dsx_set_page(hw, true); 1881c91c1c84SLorenzo Bianconi if (err < 0) 1882c91c1c84SLorenzo Bianconi return err; 1883c91c1c84SLorenzo Bianconi 1884c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask); 1885c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 1886c91c1c84SLorenzo Bianconi hub_settings->aux_sens.addr, 1887c91c1c84SLorenzo Bianconi hub_settings->aux_sens.mask, data); 1888c91c1c84SLorenzo Bianconi 1889c91c1c84SLorenzo Bianconi st_lsm6dsx_set_page(hw, false); 1890c91c1c84SLorenzo Bianconi } 1891c91c1c84SLorenzo Bianconi 1892c91c1c84SLorenzo Bianconi return err; 1893c91c1c84SLorenzo Bianconi } 1894c91c1c84SLorenzo Bianconi 189521345107SLorenzo Bianconi static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw) 189621345107SLorenzo Bianconi { 189721345107SLorenzo Bianconi const struct st_lsm6dsx_hw_ts_settings *ts_settings; 189821345107SLorenzo Bianconi int err, val; 189921345107SLorenzo Bianconi 190021345107SLorenzo Bianconi ts_settings = &hw->settings->ts_settings; 190121345107SLorenzo Bianconi /* enable hw timestamp generation if necessary */ 190221345107SLorenzo Bianconi if (ts_settings->timer_en.addr) { 190321345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask); 190421345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 190521345107SLorenzo Bianconi ts_settings->timer_en.addr, 190621345107SLorenzo Bianconi ts_settings->timer_en.mask, val); 190721345107SLorenzo Bianconi if (err < 0) 190821345107SLorenzo Bianconi return err; 190921345107SLorenzo Bianconi } 191021345107SLorenzo Bianconi 191121345107SLorenzo Bianconi /* enable high resolution for hw ts timer if necessary */ 191221345107SLorenzo Bianconi if (ts_settings->hr_timer.addr) { 191321345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask); 191421345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 191521345107SLorenzo Bianconi ts_settings->hr_timer.addr, 191621345107SLorenzo Bianconi ts_settings->hr_timer.mask, val); 191721345107SLorenzo Bianconi if (err < 0) 191821345107SLorenzo Bianconi return err; 191921345107SLorenzo Bianconi } 192021345107SLorenzo Bianconi 192121345107SLorenzo Bianconi /* enable ts queueing in FIFO if necessary */ 192221345107SLorenzo Bianconi if (ts_settings->fifo_en.addr) { 192321345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask); 192421345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 192521345107SLorenzo Bianconi ts_settings->fifo_en.addr, 192621345107SLorenzo Bianconi ts_settings->fifo_en.mask, val); 192721345107SLorenzo Bianconi if (err < 0) 192821345107SLorenzo Bianconi return err; 192921345107SLorenzo Bianconi } 1930cb3b6b8eSMario Tesi 1931cb3b6b8eSMario Tesi /* calibrate timestamp sensitivity */ 1932cb3b6b8eSMario Tesi hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY; 1933cb3b6b8eSMario Tesi if (ts_settings->freq_fine) { 1934cb3b6b8eSMario Tesi err = regmap_read(hw->regmap, ts_settings->freq_fine, &val); 1935cb3b6b8eSMario Tesi if (err < 0) 1936cb3b6b8eSMario Tesi return err; 1937cb3b6b8eSMario Tesi 1938cb3b6b8eSMario Tesi /* 1939cb3b6b8eSMario Tesi * linearize the AN5192 formula: 1940cb3b6b8eSMario Tesi * 1 / (1 + x) ~= 1 - x (Taylor’s Series) 1941cb3b6b8eSMario Tesi * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val)) 1942cb3b6b8eSMario Tesi * ttrim[ns] ~= 25000 - 37.5 * val 1943cb3b6b8eSMario Tesi * ttrim[ns] ~= 25000 - (37500 * val) / 1000 1944cb3b6b8eSMario Tesi */ 1945cb3b6b8eSMario Tesi hw->ts_gain -= ((s8)val * 37500) / 1000; 1946cb3b6b8eSMario Tesi } 1947cb3b6b8eSMario Tesi 194821345107SLorenzo Bianconi return 0; 194921345107SLorenzo Bianconi } 195021345107SLorenzo Bianconi 1951290a6ce1SLorenzo Bianconi static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) 1952290a6ce1SLorenzo Bianconi { 19537e906103SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 1954290a6ce1SLorenzo Bianconi int err; 1955290a6ce1SLorenzo Bianconi 195619435425SLorenzo Bianconi /* device sw reset */ 195766b662a1SLorenzo Bianconi reg = &hw->settings->reset; 195866b662a1SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 195966b662a1SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 1960290a6ce1SLorenzo Bianconi if (err < 0) 1961290a6ce1SLorenzo Bianconi return err; 1962290a6ce1SLorenzo Bianconi 196319435425SLorenzo Bianconi msleep(50); 196419435425SLorenzo Bianconi 196519435425SLorenzo Bianconi /* reload trimming parameter */ 196666b662a1SLorenzo Bianconi reg = &hw->settings->boot; 196766b662a1SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 196866b662a1SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 196919435425SLorenzo Bianconi if (err < 0) 197019435425SLorenzo Bianconi return err; 197119435425SLorenzo Bianconi 197219435425SLorenzo Bianconi msleep(50); 1973290a6ce1SLorenzo Bianconi 1974290a6ce1SLorenzo Bianconi /* enable Block Data Update */ 197566b662a1SLorenzo Bianconi reg = &hw->settings->bdu; 197666b662a1SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 197766b662a1SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 1978290a6ce1SLorenzo Bianconi if (err < 0) 1979290a6ce1SLorenzo Bianconi return err; 1980290a6ce1SLorenzo Bianconi 1981290a6ce1SLorenzo Bianconi /* enable FIFO watermak interrupt */ 19827e906103SLorenzo Bianconi err = st_lsm6dsx_get_drdy_reg(hw, ®); 1983290a6ce1SLorenzo Bianconi if (err < 0) 1984290a6ce1SLorenzo Bianconi return err; 1985290a6ce1SLorenzo Bianconi 19867e906103SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 19877e906103SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 198821345107SLorenzo Bianconi if (err < 0) 198921345107SLorenzo Bianconi return err; 199021345107SLorenzo Bianconi 19919db02d32SLorenzo Bianconi /* enable Latched interrupts for device events */ 19927e906103SLorenzo Bianconi if (hw->settings->irq_config.lir.addr) { 19937e906103SLorenzo Bianconi reg = &hw->settings->irq_config.lir; 19947e906103SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 19957e906103SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 19969db02d32SLorenzo Bianconi if (err < 0) 19979db02d32SLorenzo Bianconi return err; 199822ea5651SLorenzo Bianconi 199922ea5651SLorenzo Bianconi /* enable clear on read for latched interrupts */ 20007e906103SLorenzo Bianconi if (hw->settings->irq_config.clear_on_read.addr) { 20017e906103SLorenzo Bianconi reg = &hw->settings->irq_config.clear_on_read; 200222ea5651SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 20037e906103SLorenzo Bianconi reg->addr, reg->mask, 20047e906103SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 200522ea5651SLorenzo Bianconi if (err < 0) 200622ea5651SLorenzo Bianconi return err; 200722ea5651SLorenzo Bianconi } 20089db02d32SLorenzo Bianconi } 20099db02d32SLorenzo Bianconi 2010960506edSLorenzo Bianconi /* enable drdy-mas if available */ 2011960506edSLorenzo Bianconi if (hw->settings->drdy_mask.addr) { 2012960506edSLorenzo Bianconi reg = &hw->settings->drdy_mask; 2013960506edSLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 2014960506edSLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 2015960506edSLorenzo Bianconi if (err < 0) 2016960506edSLorenzo Bianconi return err; 2017960506edSLorenzo Bianconi } 2018960506edSLorenzo Bianconi 2019c91c1c84SLorenzo Bianconi err = st_lsm6dsx_init_shub(hw); 2020c91c1c84SLorenzo Bianconi if (err < 0) 2021c91c1c84SLorenzo Bianconi return err; 2022c91c1c84SLorenzo Bianconi 202321345107SLorenzo Bianconi return st_lsm6dsx_init_hw_timer(hw); 2024290a6ce1SLorenzo Bianconi } 2025290a6ce1SLorenzo Bianconi 2026290a6ce1SLorenzo Bianconi static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, 2027510c0106SLorenzo Bianconi enum st_lsm6dsx_sensor_id id, 2028510c0106SLorenzo Bianconi const char *name) 2029290a6ce1SLorenzo Bianconi { 2030290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 2031290a6ce1SLorenzo Bianconi struct iio_dev *iio_dev; 2032290a6ce1SLorenzo Bianconi 2033290a6ce1SLorenzo Bianconi iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor)); 2034290a6ce1SLorenzo Bianconi if (!iio_dev) 2035290a6ce1SLorenzo Bianconi return NULL; 2036290a6ce1SLorenzo Bianconi 2037290a6ce1SLorenzo Bianconi iio_dev->modes = INDIO_DIRECT_MODE; 2038290a6ce1SLorenzo Bianconi iio_dev->dev.parent = hw->dev; 2039290a6ce1SLorenzo Bianconi iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks; 2040f48bc49bSLorenzo Bianconi iio_dev->channels = hw->settings->channels[id].chan; 2041f48bc49bSLorenzo Bianconi iio_dev->num_channels = hw->settings->channels[id].len; 2042290a6ce1SLorenzo Bianconi 2043290a6ce1SLorenzo Bianconi sensor = iio_priv(iio_dev); 2044290a6ce1SLorenzo Bianconi sensor->id = id; 2045290a6ce1SLorenzo Bianconi sensor->hw = hw; 2046f8710f03SLorenzo Bianconi sensor->odr = hw->settings->odr_table[id].odr_avl[0].milli_hz; 2047640aca3fSLorenzo Bianconi sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain; 2048290a6ce1SLorenzo Bianconi sensor->watermark = 1; 2049290a6ce1SLorenzo Bianconi 2050290a6ce1SLorenzo Bianconi switch (id) { 2051290a6ce1SLorenzo Bianconi case ST_LSM6DSX_ID_ACC: 2052290a6ce1SLorenzo Bianconi iio_dev->info = &st_lsm6dsx_acc_info; 2053510c0106SLorenzo Bianconi scnprintf(sensor->name, sizeof(sensor->name), "%s_accel", 2054510c0106SLorenzo Bianconi name); 2055290a6ce1SLorenzo Bianconi break; 2056290a6ce1SLorenzo Bianconi case ST_LSM6DSX_ID_GYRO: 2057290a6ce1SLorenzo Bianconi iio_dev->info = &st_lsm6dsx_gyro_info; 2058510c0106SLorenzo Bianconi scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro", 2059510c0106SLorenzo Bianconi name); 2060290a6ce1SLorenzo Bianconi break; 2061290a6ce1SLorenzo Bianconi default: 2062290a6ce1SLorenzo Bianconi return NULL; 2063290a6ce1SLorenzo Bianconi } 2064510c0106SLorenzo Bianconi iio_dev->name = sensor->name; 2065290a6ce1SLorenzo Bianconi 2066290a6ce1SLorenzo Bianconi return iio_dev; 2067290a6ce1SLorenzo Bianconi } 2068290a6ce1SLorenzo Bianconi 2069615bd378SLorenzo Bianconi static bool 2070615bd378SLorenzo Bianconi st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw) 20711aabad1fSSean Nyekjaer { 2072615bd378SLorenzo Bianconi const struct st_lsm6dsx_event_settings *event_settings; 2073615bd378SLorenzo Bianconi int err, data; 2074615bd378SLorenzo Bianconi s64 timestamp; 20751aabad1fSSean Nyekjaer 2076615bd378SLorenzo Bianconi if (!hw->enable_event) 2077615bd378SLorenzo Bianconi return false; 2078615bd378SLorenzo Bianconi 2079615bd378SLorenzo Bianconi event_settings = &hw->settings->event_settings; 2080615bd378SLorenzo Bianconi err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg, 2081615bd378SLorenzo Bianconi &data, sizeof(data)); 2082615bd378SLorenzo Bianconi if (err < 0) 2083615bd378SLorenzo Bianconi return false; 2084615bd378SLorenzo Bianconi 2085615bd378SLorenzo Bianconi timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]); 20861aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_z_mask) && 20871aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_Z))) 20881aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 20891aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 20901aabad1fSSean Nyekjaer 0, 20911aabad1fSSean Nyekjaer IIO_MOD_Z, 20921aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 20931aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 20941aabad1fSSean Nyekjaer timestamp); 20951aabad1fSSean Nyekjaer 20961aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_y_mask) && 20971aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_Y))) 20981aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 20991aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 21001aabad1fSSean Nyekjaer 0, 21011aabad1fSSean Nyekjaer IIO_MOD_Y, 21021aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 21031aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 21041aabad1fSSean Nyekjaer timestamp); 21051aabad1fSSean Nyekjaer 21061aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_x_mask) && 21071aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_X))) 21081aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 21091aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 21101aabad1fSSean Nyekjaer 0, 21111aabad1fSSean Nyekjaer IIO_MOD_X, 21121aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 21131aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 21141aabad1fSSean Nyekjaer timestamp); 2115615bd378SLorenzo Bianconi 2116615bd378SLorenzo Bianconi return data & event_settings->wakeup_src_status_mask; 21171aabad1fSSean Nyekjaer } 21181aabad1fSSean Nyekjaer 21196ee6a368SSean Nyekjaer static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) 21206ee6a368SSean Nyekjaer { 21216ee6a368SSean Nyekjaer struct st_lsm6dsx_hw *hw = private; 2122615bd378SLorenzo Bianconi bool event; 21236ee6a368SSean Nyekjaer int count; 21241aabad1fSSean Nyekjaer 2125615bd378SLorenzo Bianconi event = st_lsm6dsx_report_motion_event(hw); 21266ee6a368SSean Nyekjaer 2127a912ee4cSLorenzo Bianconi if (!hw->settings->fifo_ops.read_fifo) 2128a912ee4cSLorenzo Bianconi return event ? IRQ_HANDLED : IRQ_NONE; 2129a912ee4cSLorenzo Bianconi 21306ee6a368SSean Nyekjaer mutex_lock(&hw->fifo_lock); 21316ee6a368SSean Nyekjaer count = hw->settings->fifo_ops.read_fifo(hw); 21326ee6a368SSean Nyekjaer mutex_unlock(&hw->fifo_lock); 21336ee6a368SSean Nyekjaer 2134615bd378SLorenzo Bianconi return count || event ? IRQ_HANDLED : IRQ_NONE; 21356ee6a368SSean Nyekjaer } 21366ee6a368SSean Nyekjaer 21376ee6a368SSean Nyekjaer static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) 21386ee6a368SSean Nyekjaer { 213931fe8d4eSLorenzo Bianconi struct st_sensors_platform_data *pdata; 214031fe8d4eSLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 214103d4c566SAndy Shevchenko struct device *dev = hw->dev; 21426ee6a368SSean Nyekjaer unsigned long irq_type; 21436ee6a368SSean Nyekjaer bool irq_active_low; 21446ee6a368SSean Nyekjaer int err; 21456ee6a368SSean Nyekjaer 21466ee6a368SSean Nyekjaer irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq)); 21476ee6a368SSean Nyekjaer 21486ee6a368SSean Nyekjaer switch (irq_type) { 21496ee6a368SSean Nyekjaer case IRQF_TRIGGER_HIGH: 21506ee6a368SSean Nyekjaer case IRQF_TRIGGER_RISING: 21516ee6a368SSean Nyekjaer irq_active_low = false; 21526ee6a368SSean Nyekjaer break; 21536ee6a368SSean Nyekjaer case IRQF_TRIGGER_LOW: 21546ee6a368SSean Nyekjaer case IRQF_TRIGGER_FALLING: 21556ee6a368SSean Nyekjaer irq_active_low = true; 21566ee6a368SSean Nyekjaer break; 21576ee6a368SSean Nyekjaer default: 21586ee6a368SSean Nyekjaer dev_info(hw->dev, "mode %lx unsupported\n", irq_type); 21596ee6a368SSean Nyekjaer return -EINVAL; 21606ee6a368SSean Nyekjaer } 21616ee6a368SSean Nyekjaer 216231fe8d4eSLorenzo Bianconi reg = &hw->settings->irq_config.hla; 216331fe8d4eSLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 216431fe8d4eSLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(irq_active_low, 216531fe8d4eSLorenzo Bianconi reg->mask)); 21666ee6a368SSean Nyekjaer if (err < 0) 21676ee6a368SSean Nyekjaer return err; 21686ee6a368SSean Nyekjaer 216903d4c566SAndy Shevchenko pdata = (struct st_sensors_platform_data *)dev->platform_data; 217003d4c566SAndy Shevchenko if ((dev_fwnode(dev) && device_property_read_bool(dev, "drive-open-drain")) || 21716ee6a368SSean Nyekjaer (pdata && pdata->open_drain)) { 217231fe8d4eSLorenzo Bianconi reg = &hw->settings->irq_config.od; 217331fe8d4eSLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 217431fe8d4eSLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 21756ee6a368SSean Nyekjaer if (err < 0) 21766ee6a368SSean Nyekjaer return err; 21776ee6a368SSean Nyekjaer 21786ee6a368SSean Nyekjaer irq_type |= IRQF_SHARED; 21796ee6a368SSean Nyekjaer } 21806ee6a368SSean Nyekjaer 21816ee6a368SSean Nyekjaer err = devm_request_threaded_irq(hw->dev, hw->irq, 2182a3aa17d4SSean Nyekjaer NULL, 21836ee6a368SSean Nyekjaer st_lsm6dsx_handler_thread, 21846ee6a368SSean Nyekjaer irq_type | IRQF_ONESHOT, 21856ee6a368SSean Nyekjaer "lsm6dsx", hw); 21866ee6a368SSean Nyekjaer if (err) { 21876ee6a368SSean Nyekjaer dev_err(hw->dev, "failed to request trigger irq %d\n", 21886ee6a368SSean Nyekjaer hw->irq); 21896ee6a368SSean Nyekjaer return err; 21906ee6a368SSean Nyekjaer } 21916ee6a368SSean Nyekjaer 21926ee6a368SSean Nyekjaer return 0; 21936ee6a368SSean Nyekjaer } 21946ee6a368SSean Nyekjaer 219581956a93SLorenzo Bianconi int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, 219651a8b707SLorenzo Bianconi struct regmap *regmap) 2197290a6ce1SLorenzo Bianconi { 2198b7a73b33SLorenzo Bianconi struct st_sensors_platform_data *pdata = dev->platform_data; 2199c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 2200290a6ce1SLorenzo Bianconi struct st_lsm6dsx_hw *hw; 220181956a93SLorenzo Bianconi const char *name = NULL; 2202290a6ce1SLorenzo Bianconi int i, err; 2203290a6ce1SLorenzo Bianconi 2204290a6ce1SLorenzo Bianconi hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); 2205290a6ce1SLorenzo Bianconi if (!hw) 2206290a6ce1SLorenzo Bianconi return -ENOMEM; 2207290a6ce1SLorenzo Bianconi 2208290a6ce1SLorenzo Bianconi dev_set_drvdata(dev, (void *)hw); 2209290a6ce1SLorenzo Bianconi 2210290a6ce1SLorenzo Bianconi mutex_init(&hw->fifo_lock); 2211335eaedcSLorenzo Bianconi mutex_init(&hw->conf_lock); 2212739aff87SLorenzo Bianconi mutex_init(&hw->page_lock); 2213290a6ce1SLorenzo Bianconi 221491a6b841SLorenzo Bianconi hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL); 221591a6b841SLorenzo Bianconi if (!hw->buff) 221691a6b841SLorenzo Bianconi return -ENOMEM; 221791a6b841SLorenzo Bianconi 2218290a6ce1SLorenzo Bianconi hw->dev = dev; 2219290a6ce1SLorenzo Bianconi hw->irq = irq; 222051a8b707SLorenzo Bianconi hw->regmap = regmap; 2221290a6ce1SLorenzo Bianconi 222281956a93SLorenzo Bianconi err = st_lsm6dsx_check_whoami(hw, hw_id, &name); 2223290a6ce1SLorenzo Bianconi if (err < 0) 2224290a6ce1SLorenzo Bianconi return err; 2225290a6ce1SLorenzo Bianconi 22266ffb55e5SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) { 2227510c0106SLorenzo Bianconi hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name); 2228290a6ce1SLorenzo Bianconi if (!hw->iio_devs[i]) 2229290a6ce1SLorenzo Bianconi return -ENOMEM; 2230290a6ce1SLorenzo Bianconi } 2231290a6ce1SLorenzo Bianconi 2232290a6ce1SLorenzo Bianconi err = st_lsm6dsx_init_device(hw); 2233290a6ce1SLorenzo Bianconi if (err < 0) 2234290a6ce1SLorenzo Bianconi return err; 2235290a6ce1SLorenzo Bianconi 2236c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 2237c91c1c84SLorenzo Bianconi if (hub_settings->master_en.addr) { 2238c91c1c84SLorenzo Bianconi err = st_lsm6dsx_shub_probe(hw, name); 2239c91c1c84SLorenzo Bianconi if (err < 0) 2240c91c1c84SLorenzo Bianconi return err; 2241c91c1c84SLorenzo Bianconi } 2242c91c1c84SLorenzo Bianconi 2243290a6ce1SLorenzo Bianconi if (hw->irq > 0) { 22446ee6a368SSean Nyekjaer err = st_lsm6dsx_irq_setup(hw); 22456ee6a368SSean Nyekjaer if (err < 0) 22466ee6a368SSean Nyekjaer return err; 22476ee6a368SSean Nyekjaer 2248290a6ce1SLorenzo Bianconi err = st_lsm6dsx_fifo_setup(hw); 2249290a6ce1SLorenzo Bianconi if (err < 0) 2250290a6ce1SLorenzo Bianconi return err; 2251290a6ce1SLorenzo Bianconi } 2252290a6ce1SLorenzo Bianconi 2253290a6ce1SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 22546ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 22556ffb55e5SLorenzo Bianconi continue; 22566ffb55e5SLorenzo Bianconi 2257290a6ce1SLorenzo Bianconi err = devm_iio_device_register(hw->dev, hw->iio_devs[i]); 2258290a6ce1SLorenzo Bianconi if (err) 2259290a6ce1SLorenzo Bianconi return err; 2260290a6ce1SLorenzo Bianconi } 2261290a6ce1SLorenzo Bianconi 226203d4c566SAndy Shevchenko if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) || 2263b7a73b33SLorenzo Bianconi (pdata && pdata->wakeup_source)) 22644c997dfaSSean Nyekjaer device_init_wakeup(dev, true); 22654c997dfaSSean Nyekjaer 2266290a6ce1SLorenzo Bianconi return 0; 2267290a6ce1SLorenzo Bianconi } 2268290a6ce1SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_probe); 2269290a6ce1SLorenzo Bianconi 22703cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_suspend(struct device *dev) 2271d3f77058SLorenzo Bianconi { 2272d3f77058SLorenzo Bianconi struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); 2273d3f77058SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 2274d3f77058SLorenzo Bianconi int i, err = 0; 2275d3f77058SLorenzo Bianconi 2276d3f77058SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 22776ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 22786ffb55e5SLorenzo Bianconi continue; 22796ffb55e5SLorenzo Bianconi 2280d3f77058SLorenzo Bianconi sensor = iio_priv(hw->iio_devs[i]); 2281d3f77058SLorenzo Bianconi if (!(hw->enable_mask & BIT(sensor->id))) 2282d3f77058SLorenzo Bianconi continue; 2283d3f77058SLorenzo Bianconi 22844c997dfaSSean Nyekjaer if (device_may_wakeup(dev) && 22854c997dfaSSean Nyekjaer sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) { 22864c997dfaSSean Nyekjaer /* Enable wake from IRQ */ 22874c997dfaSSean Nyekjaer enable_irq_wake(hw->irq); 22884c997dfaSSean Nyekjaer continue; 22894c997dfaSSean Nyekjaer } 22904c997dfaSSean Nyekjaer 2291bce0d57dSLorenzo Bianconi if (sensor->id == ST_LSM6DSX_ID_EXT0 || 2292bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT1 || 2293bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT2) 2294bce0d57dSLorenzo Bianconi err = st_lsm6dsx_shub_set_enable(sensor, false); 2295bce0d57dSLorenzo Bianconi else 2296bce0d57dSLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, false); 2297d3f77058SLorenzo Bianconi if (err < 0) 2298d3f77058SLorenzo Bianconi return err; 2299bce0d57dSLorenzo Bianconi 2300bce0d57dSLorenzo Bianconi hw->suspend_mask |= BIT(sensor->id); 2301d3f77058SLorenzo Bianconi } 2302d3f77058SLorenzo Bianconi 2303d3f77058SLorenzo Bianconi if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS) 2304d3f77058SLorenzo Bianconi err = st_lsm6dsx_flush_fifo(hw); 2305d3f77058SLorenzo Bianconi 2306d3f77058SLorenzo Bianconi return err; 2307d3f77058SLorenzo Bianconi } 2308d3f77058SLorenzo Bianconi 23093cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_resume(struct device *dev) 2310d3f77058SLorenzo Bianconi { 2311d3f77058SLorenzo Bianconi struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); 2312d3f77058SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 2313d3f77058SLorenzo Bianconi int i, err = 0; 2314d3f77058SLorenzo Bianconi 2315d3f77058SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 23166ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 23176ffb55e5SLorenzo Bianconi continue; 23186ffb55e5SLorenzo Bianconi 2319d3f77058SLorenzo Bianconi sensor = iio_priv(hw->iio_devs[i]); 23204c997dfaSSean Nyekjaer if (device_may_wakeup(dev) && 23214c997dfaSSean Nyekjaer sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) 23224c997dfaSSean Nyekjaer disable_irq_wake(hw->irq); 23234c997dfaSSean Nyekjaer 2324bce0d57dSLorenzo Bianconi if (!(hw->suspend_mask & BIT(sensor->id))) 2325d3f77058SLorenzo Bianconi continue; 2326d3f77058SLorenzo Bianconi 2327bce0d57dSLorenzo Bianconi if (sensor->id == ST_LSM6DSX_ID_EXT0 || 2328bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT1 || 2329bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT2) 2330bce0d57dSLorenzo Bianconi err = st_lsm6dsx_shub_set_enable(sensor, true); 2331bce0d57dSLorenzo Bianconi else 2332bce0d57dSLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, true); 2333d3f77058SLorenzo Bianconi if (err < 0) 2334d3f77058SLorenzo Bianconi return err; 2335bce0d57dSLorenzo Bianconi 2336bce0d57dSLorenzo Bianconi hw->suspend_mask &= ~BIT(sensor->id); 2337d3f77058SLorenzo Bianconi } 2338d3f77058SLorenzo Bianconi 2339d3f77058SLorenzo Bianconi if (hw->enable_mask) 2340d3f77058SLorenzo Bianconi err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT); 2341d3f77058SLorenzo Bianconi 2342d3f77058SLorenzo Bianconi return err; 2343d3f77058SLorenzo Bianconi } 2344d3f77058SLorenzo Bianconi 2345d3f77058SLorenzo Bianconi const struct dev_pm_ops st_lsm6dsx_pm_ops = { 2346d3f77058SLorenzo Bianconi SET_SYSTEM_SLEEP_PM_OPS(st_lsm6dsx_suspend, st_lsm6dsx_resume) 2347d3f77058SLorenzo Bianconi }; 2348d3f77058SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_pm_ops); 2349d3f77058SLorenzo Bianconi 2350290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>"); 2351290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 2352290a6ce1SLorenzo Bianconi MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver"); 2353290a6ce1SLorenzo Bianconi MODULE_LICENSE("GPL v2"); 2354