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: 18f7d5c18aSSean Nyekjaer * - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 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: 24f7d5c18aSSean Nyekjaer * - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 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 * 29*fdd70d7aSLorenzo Bianconi * - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP: 30f7d5c18aSSean Nyekjaer * - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416, 318f9a5249SLorenzo Bianconi * 833 32801a6e0aSLorenzo Bianconi * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 33801a6e0aSLorenzo Bianconi * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 34801a6e0aSLorenzo Bianconi * - FIFO size: 3KB 35801a6e0aSLorenzo Bianconi * 36fa060a3dSLorenzo Bianconi * - LSM9DS1/LSM6DS0: 3752f4b1f1SMartin Kepplinger * - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952 3852f4b1f1SMartin Kepplinger * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 3952f4b1f1SMartin Kepplinger * - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952 4052f4b1f1SMartin Kepplinger * - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000 4152f4b1f1SMartin Kepplinger * - FIFO size: 32 4252f4b1f1SMartin Kepplinger * 43290a6ce1SLorenzo Bianconi * Copyright 2016 STMicroelectronics Inc. 44290a6ce1SLorenzo Bianconi * 45290a6ce1SLorenzo Bianconi * Lorenzo Bianconi <lorenzo.bianconi@st.com> 46290a6ce1SLorenzo Bianconi * Denis Ciocca <denis.ciocca@st.com> 47290a6ce1SLorenzo Bianconi */ 48290a6ce1SLorenzo Bianconi 49290a6ce1SLorenzo Bianconi #include <linux/kernel.h> 50290a6ce1SLorenzo Bianconi #include <linux/module.h> 51290a6ce1SLorenzo Bianconi #include <linux/delay.h> 521aabad1fSSean Nyekjaer #include <linux/iio/events.h> 53290a6ce1SLorenzo Bianconi #include <linux/iio/iio.h> 54290a6ce1SLorenzo Bianconi #include <linux/iio/sysfs.h> 556ee6a368SSean Nyekjaer #include <linux/interrupt.h> 566ee6a368SSean Nyekjaer #include <linux/irq.h> 57d3f77058SLorenzo Bianconi #include <linux/pm.h> 5803d4c566SAndy Shevchenko #include <linux/property.h> 5951a8b707SLorenzo Bianconi #include <linux/regmap.h> 6051a8b707SLorenzo Bianconi #include <linux/bitfield.h> 61290a6ce1SLorenzo Bianconi 62dba32904SLorenzo Bianconi #include <linux/platform_data/st_sensors_pdata.h> 63dba32904SLorenzo Bianconi 64290a6ce1SLorenzo Bianconi #include "st_lsm6dsx.h" 65290a6ce1SLorenzo Bianconi 66290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f 67290a6ce1SLorenzo Bianconi 68cb3b6b8eSMario Tesi #define ST_LSM6DSX_TS_SENSITIVITY 25000UL /* 25us */ 69cb3b6b8eSMario Tesi 70f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { 71b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0), 72b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1), 73b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2), 74f48bc49bSLorenzo Bianconi IIO_CHAN_SOFT_TIMESTAMP(3), 75f48bc49bSLorenzo Bianconi }; 76f48bc49bSLorenzo Bianconi 77f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = { 78f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0), 79f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1), 80f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2), 81f48bc49bSLorenzo Bianconi IIO_CHAN_SOFT_TIMESTAMP(3), 82f48bc49bSLorenzo Bianconi }; 83f48bc49bSLorenzo Bianconi 8452f4b1f1SMartin Kepplinger static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = { 8552f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0), 8652f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1), 8752f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2), 8852f4b1f1SMartin Kepplinger IIO_CHAN_SOFT_TIMESTAMP(3), 8952f4b1f1SMartin Kepplinger }; 9052f4b1f1SMartin Kepplinger 91290a6ce1SLorenzo Bianconi static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { 92290a6ce1SLorenzo Bianconi { 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 .id = { 10652f4b1f1SMartin Kepplinger { 10752f4b1f1SMartin Kepplinger .hw_id = ST_LSM9DS1_ID, 10852f4b1f1SMartin Kepplinger .name = ST_LSM9DS1_DEV_NAME, 10998c3544aSLorenzo Bianconi .wai = 0x68, 110fa060a3dSLorenzo Bianconi }, { 111fa060a3dSLorenzo Bianconi .hw_id = ST_LSM6DS0_ID, 112fa060a3dSLorenzo Bianconi .name = ST_LSM6DS0_DEV_NAME, 11398c3544aSLorenzo Bianconi .wai = 0x68, 11452f4b1f1SMartin Kepplinger }, 11552f4b1f1SMartin Kepplinger }, 11652f4b1f1SMartin Kepplinger .channels = { 11752f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 11852f4b1f1SMartin Kepplinger .chan = st_lsm6dsx_acc_channels, 11952f4b1f1SMartin Kepplinger .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 12052f4b1f1SMartin Kepplinger }, 12152f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 12252f4b1f1SMartin Kepplinger .chan = st_lsm6ds0_gyro_channels, 12352f4b1f1SMartin Kepplinger .len = ARRAY_SIZE(st_lsm6ds0_gyro_channels), 12452f4b1f1SMartin Kepplinger }, 12552f4b1f1SMartin Kepplinger }, 12652f4b1f1SMartin Kepplinger .odr_table = { 12752f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 12852f4b1f1SMartin Kepplinger .reg = { 12952f4b1f1SMartin Kepplinger .addr = 0x20, 13052f4b1f1SMartin Kepplinger .mask = GENMASK(7, 5), 13152f4b1f1SMartin Kepplinger }, 132f8710f03SLorenzo Bianconi .odr_avl[0] = { 10000, 0x01 }, 133f8710f03SLorenzo Bianconi .odr_avl[1] = { 50000, 0x02 }, 134f8710f03SLorenzo Bianconi .odr_avl[2] = { 119000, 0x03 }, 135f8710f03SLorenzo Bianconi .odr_avl[3] = { 238000, 0x04 }, 136f8710f03SLorenzo Bianconi .odr_avl[4] = { 476000, 0x05 }, 137f8710f03SLorenzo Bianconi .odr_avl[5] = { 952000, 0x06 }, 13859af4e20SLorenzo Bianconi .odr_len = 6, 13952f4b1f1SMartin Kepplinger }, 14052f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 14152f4b1f1SMartin Kepplinger .reg = { 14252f4b1f1SMartin Kepplinger .addr = 0x10, 14352f4b1f1SMartin Kepplinger .mask = GENMASK(7, 5), 14452f4b1f1SMartin Kepplinger }, 145f8710f03SLorenzo Bianconi .odr_avl[0] = { 14900, 0x01 }, 146f8710f03SLorenzo Bianconi .odr_avl[1] = { 59500, 0x02 }, 147f8710f03SLorenzo Bianconi .odr_avl[2] = { 119000, 0x03 }, 148f8710f03SLorenzo Bianconi .odr_avl[3] = { 238000, 0x04 }, 149f8710f03SLorenzo Bianconi .odr_avl[4] = { 476000, 0x05 }, 150f8710f03SLorenzo Bianconi .odr_avl[5] = { 952000, 0x06 }, 15159af4e20SLorenzo Bianconi .odr_len = 6, 15252f4b1f1SMartin Kepplinger }, 15352f4b1f1SMartin Kepplinger }, 15452f4b1f1SMartin Kepplinger .fs_table = { 15552f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 15652f4b1f1SMartin Kepplinger .reg = { 15752f4b1f1SMartin Kepplinger .addr = 0x20, 15852f4b1f1SMartin Kepplinger .mask = GENMASK(4, 3), 15952f4b1f1SMartin Kepplinger }, 16044a76de8SMario Tesi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 16144a76de8SMario Tesi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 16244a76de8SMario Tesi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 16344a76de8SMario Tesi .fs_avl[3] = { IIO_G_TO_M_S_2(732000), 0x1 }, 16485ae3aeeSLorenzo Bianconi .fs_len = 4, 16552f4b1f1SMartin Kepplinger }, 16652f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 16752f4b1f1SMartin Kepplinger .reg = { 16852f4b1f1SMartin Kepplinger .addr = 0x10, 16952f4b1f1SMartin Kepplinger .mask = GENMASK(4, 3), 17052f4b1f1SMartin Kepplinger }, 1711b375101SLorenzo Bianconi 17244a76de8SMario Tesi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 17344a76de8SMario Tesi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 17444a76de8SMario Tesi .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 17585ae3aeeSLorenzo Bianconi .fs_len = 3, 17652f4b1f1SMartin Kepplinger }, 17752f4b1f1SMartin Kepplinger }, 1787e906103SLorenzo Bianconi .irq_config = { 1797e906103SLorenzo Bianconi .irq1 = { 1807e906103SLorenzo Bianconi .addr = 0x0c, 1817e906103SLorenzo Bianconi .mask = BIT(3), 1827e906103SLorenzo Bianconi }, 1837e906103SLorenzo Bianconi .irq2 = { 1847e906103SLorenzo Bianconi .addr = 0x0d, 1857e906103SLorenzo Bianconi .mask = BIT(3), 1867e906103SLorenzo Bianconi }, 18731fe8d4eSLorenzo Bianconi .hla = { 18831fe8d4eSLorenzo Bianconi .addr = 0x22, 18931fe8d4eSLorenzo Bianconi .mask = BIT(5), 19031fe8d4eSLorenzo Bianconi }, 19131fe8d4eSLorenzo Bianconi .od = { 19231fe8d4eSLorenzo Bianconi .addr = 0x22, 19331fe8d4eSLorenzo Bianconi .mask = BIT(4), 19431fe8d4eSLorenzo Bianconi }, 1957e906103SLorenzo Bianconi }, 1961b7da2faSLorenzo Bianconi .fifo_ops = { 1971b7da2faSLorenzo Bianconi .max_size = 32, 1981b7da2faSLorenzo Bianconi }, 19952f4b1f1SMartin Kepplinger }, 20052f4b1f1SMartin Kepplinger { 20166b662a1SLorenzo Bianconi .reset = { 20266b662a1SLorenzo Bianconi .addr = 0x12, 20366b662a1SLorenzo Bianconi .mask = BIT(0), 20466b662a1SLorenzo Bianconi }, 20566b662a1SLorenzo Bianconi .boot = { 20666b662a1SLorenzo Bianconi .addr = 0x12, 20766b662a1SLorenzo Bianconi .mask = BIT(7), 20866b662a1SLorenzo Bianconi }, 20966b662a1SLorenzo Bianconi .bdu = { 21066b662a1SLorenzo Bianconi .addr = 0x12, 21166b662a1SLorenzo Bianconi .mask = BIT(6), 21266b662a1SLorenzo Bianconi }, 213d068e4a0SLorenzo Bianconi .id = { 21481956a93SLorenzo Bianconi { 21581956a93SLorenzo Bianconi .hw_id = ST_LSM6DS3_ID, 21681956a93SLorenzo Bianconi .name = ST_LSM6DS3_DEV_NAME, 21798c3544aSLorenzo Bianconi .wai = 0x69, 21881956a93SLorenzo Bianconi }, 219d068e4a0SLorenzo Bianconi }, 220f48bc49bSLorenzo Bianconi .channels = { 221f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 222f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 223f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 224f48bc49bSLorenzo Bianconi }, 225f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 226f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 227f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 228f48bc49bSLorenzo Bianconi }, 229f48bc49bSLorenzo Bianconi }, 23040dd7343SLorenzo Bianconi .odr_table = { 23140dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 23240dd7343SLorenzo Bianconi .reg = { 23340dd7343SLorenzo Bianconi .addr = 0x10, 23440dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 23540dd7343SLorenzo Bianconi }, 236f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 237f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 238f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 239f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 240f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 241f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 24259af4e20SLorenzo Bianconi .odr_len = 6, 24340dd7343SLorenzo Bianconi }, 24440dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 24540dd7343SLorenzo Bianconi .reg = { 24640dd7343SLorenzo Bianconi .addr = 0x11, 24740dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 24840dd7343SLorenzo Bianconi }, 249f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 250f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 251f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 252f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 253f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 254f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 25559af4e20SLorenzo Bianconi .odr_len = 6, 25640dd7343SLorenzo Bianconi }, 25740dd7343SLorenzo Bianconi }, 258640aca3fSLorenzo Bianconi .fs_table = { 259640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 260640aca3fSLorenzo Bianconi .reg = { 261640aca3fSLorenzo Bianconi .addr = 0x10, 262640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 263640aca3fSLorenzo Bianconi }, 26444a76de8SMario Tesi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 26544a76de8SMario Tesi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 26644a76de8SMario Tesi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 26744a76de8SMario Tesi .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, 26885ae3aeeSLorenzo Bianconi .fs_len = 4, 269640aca3fSLorenzo Bianconi }, 270640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 271640aca3fSLorenzo Bianconi .reg = { 272640aca3fSLorenzo Bianconi .addr = 0x11, 273640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 274640aca3fSLorenzo Bianconi }, 27544a76de8SMario Tesi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 27644a76de8SMario Tesi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 27744a76de8SMario Tesi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, 27844a76de8SMario Tesi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 27985ae3aeeSLorenzo Bianconi .fs_len = 4, 280640aca3fSLorenzo Bianconi }, 281640aca3fSLorenzo Bianconi }, 2827e906103SLorenzo Bianconi .irq_config = { 2837e906103SLorenzo Bianconi .irq1 = { 2847e906103SLorenzo Bianconi .addr = 0x0d, 2857e906103SLorenzo Bianconi .mask = BIT(3), 2867e906103SLorenzo Bianconi }, 2877e906103SLorenzo Bianconi .irq2 = { 2887e906103SLorenzo Bianconi .addr = 0x0e, 2897e906103SLorenzo Bianconi .mask = BIT(3), 2907e906103SLorenzo Bianconi }, 2917e906103SLorenzo Bianconi .lir = { 2927e906103SLorenzo Bianconi .addr = 0x58, 2937e906103SLorenzo Bianconi .mask = BIT(0), 2947e906103SLorenzo Bianconi }, 2957e906103SLorenzo Bianconi .irq1_func = { 2967e906103SLorenzo Bianconi .addr = 0x5e, 2977e906103SLorenzo Bianconi .mask = BIT(5), 2987e906103SLorenzo Bianconi }, 2997e906103SLorenzo Bianconi .irq2_func = { 3007e906103SLorenzo Bianconi .addr = 0x5f, 3017e906103SLorenzo Bianconi .mask = BIT(5), 3027e906103SLorenzo Bianconi }, 30331fe8d4eSLorenzo Bianconi .hla = { 30431fe8d4eSLorenzo Bianconi .addr = 0x12, 30531fe8d4eSLorenzo Bianconi .mask = BIT(5), 30631fe8d4eSLorenzo Bianconi }, 30731fe8d4eSLorenzo Bianconi .od = { 30831fe8d4eSLorenzo Bianconi .addr = 0x12, 30931fe8d4eSLorenzo Bianconi .mask = BIT(4), 31031fe8d4eSLorenzo Bianconi }, 3117e906103SLorenzo Bianconi }, 3127ca3ac9eSLorenzo Bianconi .decimator = { 3137ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 3147ca3ac9eSLorenzo Bianconi .addr = 0x08, 3157ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 3167ca3ac9eSLorenzo Bianconi }, 3177ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 3187ca3ac9eSLorenzo Bianconi .addr = 0x08, 3197ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 3207ca3ac9eSLorenzo Bianconi }, 3217ca3ac9eSLorenzo Bianconi }, 32292617c15SLorenzo Bianconi .fifo_ops = { 3233b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 32450ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 32592617c15SLorenzo Bianconi .fifo_th = { 32692617c15SLorenzo Bianconi .addr = 0x06, 32792617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 32892617c15SLorenzo Bianconi }, 32992617c15SLorenzo Bianconi .fifo_diff = { 33092617c15SLorenzo Bianconi .addr = 0x3a, 33192617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 33292617c15SLorenzo Bianconi }, 3331b7da2faSLorenzo Bianconi .max_size = 1365, 33492617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 33592617c15SLorenzo Bianconi }, 33621345107SLorenzo Bianconi .ts_settings = { 33721345107SLorenzo Bianconi .timer_en = { 33821345107SLorenzo Bianconi .addr = 0x58, 33921345107SLorenzo Bianconi .mask = BIT(7), 34021345107SLorenzo Bianconi }, 34121345107SLorenzo Bianconi .hr_timer = { 34221345107SLorenzo Bianconi .addr = 0x5c, 34321345107SLorenzo Bianconi .mask = BIT(4), 34421345107SLorenzo Bianconi }, 34521345107SLorenzo Bianconi .fifo_en = { 34621345107SLorenzo Bianconi .addr = 0x07, 34721345107SLorenzo Bianconi .mask = BIT(7), 34821345107SLorenzo Bianconi }, 34921345107SLorenzo Bianconi .decimator = { 35021345107SLorenzo Bianconi .addr = 0x09, 35121345107SLorenzo Bianconi .mask = GENMASK(5, 3), 35221345107SLorenzo Bianconi }, 35321345107SLorenzo Bianconi }, 354b5969abfSSean Nyekjaer .event_settings = { 355b5969abfSSean Nyekjaer .wakeup_reg = { 356b5969abfSSean Nyekjaer .addr = 0x5B, 357b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 358b5969abfSSean Nyekjaer }, 3591aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 3601aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 3611aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 3621aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 3631aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 364b5969abfSSean Nyekjaer }, 365290a6ce1SLorenzo Bianconi }, 366290a6ce1SLorenzo Bianconi { 36766b662a1SLorenzo Bianconi .reset = { 36866b662a1SLorenzo Bianconi .addr = 0x12, 36966b662a1SLorenzo Bianconi .mask = BIT(0), 37066b662a1SLorenzo Bianconi }, 37166b662a1SLorenzo Bianconi .boot = { 37266b662a1SLorenzo Bianconi .addr = 0x12, 37366b662a1SLorenzo Bianconi .mask = BIT(7), 37466b662a1SLorenzo Bianconi }, 37566b662a1SLorenzo Bianconi .bdu = { 37666b662a1SLorenzo Bianconi .addr = 0x12, 37766b662a1SLorenzo Bianconi .mask = BIT(6), 37866b662a1SLorenzo Bianconi }, 379df47710aSLorenzo Bianconi .id = { 38081956a93SLorenzo Bianconi { 38181956a93SLorenzo Bianconi .hw_id = ST_LSM6DS3H_ID, 38281956a93SLorenzo Bianconi .name = ST_LSM6DS3H_DEV_NAME, 38398c3544aSLorenzo Bianconi .wai = 0x69, 38481956a93SLorenzo Bianconi }, 385df47710aSLorenzo Bianconi }, 386f48bc49bSLorenzo Bianconi .channels = { 387f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 388f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 389f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 390f48bc49bSLorenzo Bianconi }, 391f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 392f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 393f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 394f48bc49bSLorenzo Bianconi }, 395f48bc49bSLorenzo Bianconi }, 39640dd7343SLorenzo Bianconi .odr_table = { 39740dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 39840dd7343SLorenzo Bianconi .reg = { 39940dd7343SLorenzo Bianconi .addr = 0x10, 40040dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 40140dd7343SLorenzo Bianconi }, 402f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 403f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 404f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 405f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 406f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 407f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 40859af4e20SLorenzo Bianconi .odr_len = 6, 40940dd7343SLorenzo Bianconi }, 41040dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 41140dd7343SLorenzo Bianconi .reg = { 41240dd7343SLorenzo Bianconi .addr = 0x11, 41340dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 41440dd7343SLorenzo Bianconi }, 415f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 416f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 417f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 418f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 419f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 420f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 42159af4e20SLorenzo Bianconi .odr_len = 6, 42240dd7343SLorenzo Bianconi }, 42340dd7343SLorenzo Bianconi }, 424640aca3fSLorenzo Bianconi .fs_table = { 425640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 426640aca3fSLorenzo Bianconi .reg = { 427640aca3fSLorenzo Bianconi .addr = 0x10, 428640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 429640aca3fSLorenzo Bianconi }, 43044a76de8SMario Tesi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 43144a76de8SMario Tesi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 43244a76de8SMario Tesi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 43344a76de8SMario Tesi .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, 43485ae3aeeSLorenzo Bianconi .fs_len = 4, 435640aca3fSLorenzo Bianconi }, 436640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 437640aca3fSLorenzo Bianconi .reg = { 438640aca3fSLorenzo Bianconi .addr = 0x11, 439640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 440640aca3fSLorenzo Bianconi }, 44144a76de8SMario Tesi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 44244a76de8SMario Tesi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 44344a76de8SMario Tesi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, 44444a76de8SMario Tesi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 44585ae3aeeSLorenzo Bianconi .fs_len = 4, 446640aca3fSLorenzo Bianconi }, 447640aca3fSLorenzo Bianconi }, 4487e906103SLorenzo Bianconi .irq_config = { 4497e906103SLorenzo Bianconi .irq1 = { 4507e906103SLorenzo Bianconi .addr = 0x0d, 4517e906103SLorenzo Bianconi .mask = BIT(3), 4527e906103SLorenzo Bianconi }, 4537e906103SLorenzo Bianconi .irq2 = { 4547e906103SLorenzo Bianconi .addr = 0x0e, 4557e906103SLorenzo Bianconi .mask = BIT(3), 4567e906103SLorenzo Bianconi }, 4577e906103SLorenzo Bianconi .lir = { 4587e906103SLorenzo Bianconi .addr = 0x58, 4597e906103SLorenzo Bianconi .mask = BIT(0), 4607e906103SLorenzo Bianconi }, 4617e906103SLorenzo Bianconi .irq1_func = { 4627e906103SLorenzo Bianconi .addr = 0x5e, 4637e906103SLorenzo Bianconi .mask = BIT(5), 4647e906103SLorenzo Bianconi }, 4657e906103SLorenzo Bianconi .irq2_func = { 4667e906103SLorenzo Bianconi .addr = 0x5f, 4677e906103SLorenzo Bianconi .mask = BIT(5), 4687e906103SLorenzo Bianconi }, 46931fe8d4eSLorenzo Bianconi .hla = { 47031fe8d4eSLorenzo Bianconi .addr = 0x12, 47131fe8d4eSLorenzo Bianconi .mask = BIT(5), 47231fe8d4eSLorenzo Bianconi }, 47331fe8d4eSLorenzo Bianconi .od = { 47431fe8d4eSLorenzo Bianconi .addr = 0x12, 47531fe8d4eSLorenzo Bianconi .mask = BIT(4), 47631fe8d4eSLorenzo Bianconi }, 4777e906103SLorenzo Bianconi }, 4787ca3ac9eSLorenzo Bianconi .decimator = { 4797ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 4807ca3ac9eSLorenzo Bianconi .addr = 0x08, 4817ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 4827ca3ac9eSLorenzo Bianconi }, 4837ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 4847ca3ac9eSLorenzo Bianconi .addr = 0x08, 4857ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 4867ca3ac9eSLorenzo Bianconi }, 4877ca3ac9eSLorenzo Bianconi }, 48892617c15SLorenzo Bianconi .fifo_ops = { 4893b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 49050ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 49192617c15SLorenzo Bianconi .fifo_th = { 49292617c15SLorenzo Bianconi .addr = 0x06, 49392617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 49492617c15SLorenzo Bianconi }, 49592617c15SLorenzo Bianconi .fifo_diff = { 49692617c15SLorenzo Bianconi .addr = 0x3a, 49792617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 49892617c15SLorenzo Bianconi }, 4991b7da2faSLorenzo Bianconi .max_size = 682, 50092617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 50192617c15SLorenzo Bianconi }, 50221345107SLorenzo Bianconi .ts_settings = { 50321345107SLorenzo Bianconi .timer_en = { 50421345107SLorenzo Bianconi .addr = 0x58, 50521345107SLorenzo Bianconi .mask = BIT(7), 50621345107SLorenzo Bianconi }, 50721345107SLorenzo Bianconi .hr_timer = { 50821345107SLorenzo Bianconi .addr = 0x5c, 50921345107SLorenzo Bianconi .mask = BIT(4), 51021345107SLorenzo Bianconi }, 51121345107SLorenzo Bianconi .fifo_en = { 51221345107SLorenzo Bianconi .addr = 0x07, 51321345107SLorenzo Bianconi .mask = BIT(7), 51421345107SLorenzo Bianconi }, 51521345107SLorenzo Bianconi .decimator = { 51621345107SLorenzo Bianconi .addr = 0x09, 51721345107SLorenzo Bianconi .mask = GENMASK(5, 3), 51821345107SLorenzo Bianconi }, 51921345107SLorenzo Bianconi }, 520b5969abfSSean Nyekjaer .event_settings = { 521b5969abfSSean Nyekjaer .wakeup_reg = { 522b5969abfSSean Nyekjaer .addr = 0x5B, 523b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 524b5969abfSSean Nyekjaer }, 5251aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 5261aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 5271aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 5281aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 5291aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 530b5969abfSSean Nyekjaer }, 531df47710aSLorenzo Bianconi }, 532df47710aSLorenzo Bianconi { 53366b662a1SLorenzo Bianconi .reset = { 53466b662a1SLorenzo Bianconi .addr = 0x12, 53566b662a1SLorenzo Bianconi .mask = BIT(0), 53666b662a1SLorenzo Bianconi }, 53766b662a1SLorenzo Bianconi .boot = { 53866b662a1SLorenzo Bianconi .addr = 0x12, 53966b662a1SLorenzo Bianconi .mask = BIT(7), 54066b662a1SLorenzo Bianconi }, 54166b662a1SLorenzo Bianconi .bdu = { 54266b662a1SLorenzo Bianconi .addr = 0x12, 54366b662a1SLorenzo Bianconi .mask = BIT(6), 54466b662a1SLorenzo Bianconi }, 545d068e4a0SLorenzo Bianconi .id = { 54681956a93SLorenzo Bianconi { 54781956a93SLorenzo Bianconi .hw_id = ST_LSM6DSL_ID, 54881956a93SLorenzo Bianconi .name = ST_LSM6DSL_DEV_NAME, 54998c3544aSLorenzo Bianconi .wai = 0x6a, 55081956a93SLorenzo Bianconi }, { 55181956a93SLorenzo Bianconi .hw_id = ST_LSM6DSM_ID, 55281956a93SLorenzo Bianconi .name = ST_LSM6DSM_DEV_NAME, 55398c3544aSLorenzo Bianconi .wai = 0x6a, 55481956a93SLorenzo Bianconi }, { 55581956a93SLorenzo Bianconi .hw_id = ST_ISM330DLC_ID, 55681956a93SLorenzo Bianconi .name = ST_ISM330DLC_DEV_NAME, 55798c3544aSLorenzo Bianconi .wai = 0x6a, 558dbcd2088SLorenzo Bianconi }, { 559dbcd2088SLorenzo Bianconi .hw_id = ST_LSM6DS3TRC_ID, 560dbcd2088SLorenzo Bianconi .name = ST_LSM6DS3TRC_DEV_NAME, 56198c3544aSLorenzo Bianconi .wai = 0x6a, 56281956a93SLorenzo Bianconi }, 563d068e4a0SLorenzo Bianconi }, 564f48bc49bSLorenzo Bianconi .channels = { 565f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 566f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 567f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 568f48bc49bSLorenzo Bianconi }, 569f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 570f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 571f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 572f48bc49bSLorenzo Bianconi }, 573f48bc49bSLorenzo Bianconi }, 57440dd7343SLorenzo Bianconi .odr_table = { 57540dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 57640dd7343SLorenzo Bianconi .reg = { 57740dd7343SLorenzo Bianconi .addr = 0x10, 57840dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 57940dd7343SLorenzo Bianconi }, 580f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 581f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 582f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 583f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 584f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 585f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 58659af4e20SLorenzo Bianconi .odr_len = 6, 58740dd7343SLorenzo Bianconi }, 58840dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 58940dd7343SLorenzo Bianconi .reg = { 59040dd7343SLorenzo Bianconi .addr = 0x11, 59140dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 59240dd7343SLorenzo Bianconi }, 593f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 594f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 595f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 596f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 597f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 598f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 59959af4e20SLorenzo Bianconi .odr_len = 6, 60040dd7343SLorenzo Bianconi }, 60140dd7343SLorenzo Bianconi }, 602640aca3fSLorenzo Bianconi .fs_table = { 603640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 604640aca3fSLorenzo Bianconi .reg = { 605640aca3fSLorenzo Bianconi .addr = 0x10, 606640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 607640aca3fSLorenzo Bianconi }, 60844a76de8SMario Tesi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 60944a76de8SMario Tesi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 61044a76de8SMario Tesi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 61144a76de8SMario Tesi .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, 61285ae3aeeSLorenzo Bianconi .fs_len = 4, 613640aca3fSLorenzo Bianconi }, 614640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 615640aca3fSLorenzo Bianconi .reg = { 616640aca3fSLorenzo Bianconi .addr = 0x11, 617640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 618640aca3fSLorenzo Bianconi }, 61944a76de8SMario Tesi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 62044a76de8SMario Tesi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 62144a76de8SMario Tesi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, 62244a76de8SMario Tesi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 62385ae3aeeSLorenzo Bianconi .fs_len = 4, 624640aca3fSLorenzo Bianconi }, 625640aca3fSLorenzo Bianconi }, 6267e906103SLorenzo Bianconi .irq_config = { 6277e906103SLorenzo Bianconi .irq1 = { 6287e906103SLorenzo Bianconi .addr = 0x0d, 6297e906103SLorenzo Bianconi .mask = BIT(3), 6307e906103SLorenzo Bianconi }, 6317e906103SLorenzo Bianconi .irq2 = { 6327e906103SLorenzo Bianconi .addr = 0x0e, 6337e906103SLorenzo Bianconi .mask = BIT(3), 6347e906103SLorenzo Bianconi }, 6357e906103SLorenzo Bianconi .lir = { 6367e906103SLorenzo Bianconi .addr = 0x58, 6377e906103SLorenzo Bianconi .mask = BIT(0), 6387e906103SLorenzo Bianconi }, 6397e906103SLorenzo Bianconi .irq1_func = { 6407e906103SLorenzo Bianconi .addr = 0x5e, 6417e906103SLorenzo Bianconi .mask = BIT(5), 6427e906103SLorenzo Bianconi }, 6437e906103SLorenzo Bianconi .irq2_func = { 6447e906103SLorenzo Bianconi .addr = 0x5f, 6457e906103SLorenzo Bianconi .mask = BIT(5), 6467e906103SLorenzo Bianconi }, 64731fe8d4eSLorenzo Bianconi .hla = { 64831fe8d4eSLorenzo Bianconi .addr = 0x12, 64931fe8d4eSLorenzo Bianconi .mask = BIT(5), 65031fe8d4eSLorenzo Bianconi }, 65131fe8d4eSLorenzo Bianconi .od = { 65231fe8d4eSLorenzo Bianconi .addr = 0x12, 65331fe8d4eSLorenzo Bianconi .mask = BIT(4), 65431fe8d4eSLorenzo Bianconi }, 6557e906103SLorenzo Bianconi }, 6567ca3ac9eSLorenzo Bianconi .decimator = { 6577ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 6587ca3ac9eSLorenzo Bianconi .addr = 0x08, 6597ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 6607ca3ac9eSLorenzo Bianconi }, 6617ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 6627ca3ac9eSLorenzo Bianconi .addr = 0x08, 6637ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 6647ca3ac9eSLorenzo Bianconi }, 665e485e2a2SLorenzo Bianconi [ST_LSM6DSX_ID_EXT0] = { 666e485e2a2SLorenzo Bianconi .addr = 0x09, 667e485e2a2SLorenzo Bianconi .mask = GENMASK(2, 0), 668e485e2a2SLorenzo Bianconi }, 6697ca3ac9eSLorenzo Bianconi }, 67092617c15SLorenzo Bianconi .fifo_ops = { 6713b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 67250ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 67392617c15SLorenzo Bianconi .fifo_th = { 67492617c15SLorenzo Bianconi .addr = 0x06, 675be75eb86SLorenzo Bianconi .mask = GENMASK(10, 0), 67692617c15SLorenzo Bianconi }, 67792617c15SLorenzo Bianconi .fifo_diff = { 67892617c15SLorenzo Bianconi .addr = 0x3a, 679be75eb86SLorenzo Bianconi .mask = GENMASK(10, 0), 68092617c15SLorenzo Bianconi }, 6811b7da2faSLorenzo Bianconi .max_size = 682, 68292617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 68392617c15SLorenzo Bianconi }, 68421345107SLorenzo Bianconi .ts_settings = { 68521345107SLorenzo Bianconi .timer_en = { 68621345107SLorenzo Bianconi .addr = 0x19, 68721345107SLorenzo Bianconi .mask = BIT(5), 68821345107SLorenzo Bianconi }, 68921345107SLorenzo Bianconi .hr_timer = { 69021345107SLorenzo Bianconi .addr = 0x5c, 69121345107SLorenzo Bianconi .mask = BIT(4), 69221345107SLorenzo Bianconi }, 69321345107SLorenzo Bianconi .fifo_en = { 69421345107SLorenzo Bianconi .addr = 0x07, 69521345107SLorenzo Bianconi .mask = BIT(7), 69621345107SLorenzo Bianconi }, 69721345107SLorenzo Bianconi .decimator = { 69821345107SLorenzo Bianconi .addr = 0x09, 69921345107SLorenzo Bianconi .mask = GENMASK(5, 3), 70021345107SLorenzo Bianconi }, 70121345107SLorenzo Bianconi }, 702e485e2a2SLorenzo Bianconi .shub_settings = { 703e485e2a2SLorenzo Bianconi .page_mux = { 704e485e2a2SLorenzo Bianconi .addr = 0x01, 705e485e2a2SLorenzo Bianconi .mask = BIT(7), 706e485e2a2SLorenzo Bianconi }, 707e485e2a2SLorenzo Bianconi .master_en = { 708e485e2a2SLorenzo Bianconi .addr = 0x1a, 709e485e2a2SLorenzo Bianconi .mask = BIT(0), 710e485e2a2SLorenzo Bianconi }, 711e485e2a2SLorenzo Bianconi .pullup_en = { 712e485e2a2SLorenzo Bianconi .addr = 0x1a, 713e485e2a2SLorenzo Bianconi .mask = BIT(3), 714e485e2a2SLorenzo Bianconi }, 715e485e2a2SLorenzo Bianconi .aux_sens = { 716e485e2a2SLorenzo Bianconi .addr = 0x04, 717e485e2a2SLorenzo Bianconi .mask = GENMASK(5, 4), 718e485e2a2SLorenzo Bianconi }, 719e485e2a2SLorenzo Bianconi .wr_once = { 720e485e2a2SLorenzo Bianconi .addr = 0x07, 721e485e2a2SLorenzo Bianconi .mask = BIT(5), 722e485e2a2SLorenzo Bianconi }, 723e485e2a2SLorenzo Bianconi .emb_func = { 724e485e2a2SLorenzo Bianconi .addr = 0x19, 725e485e2a2SLorenzo Bianconi .mask = BIT(2), 726e485e2a2SLorenzo Bianconi }, 727e485e2a2SLorenzo Bianconi .num_ext_dev = 1, 728e485e2a2SLorenzo Bianconi .shub_out = { 729e485e2a2SLorenzo Bianconi .addr = 0x2e, 730e485e2a2SLorenzo Bianconi }, 731e485e2a2SLorenzo Bianconi .slv0_addr = 0x02, 732e485e2a2SLorenzo Bianconi .dw_slv0_addr = 0x0e, 733e485e2a2SLorenzo Bianconi .pause = 0x7, 734e485e2a2SLorenzo Bianconi }, 735b5969abfSSean Nyekjaer .event_settings = { 736b5969abfSSean Nyekjaer .enable_reg = { 737b5969abfSSean Nyekjaer .addr = 0x58, 738b5969abfSSean Nyekjaer .mask = BIT(7), 739b5969abfSSean Nyekjaer }, 740b5969abfSSean Nyekjaer .wakeup_reg = { 741b5969abfSSean Nyekjaer .addr = 0x5B, 742b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 743b5969abfSSean Nyekjaer }, 7441aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 7451aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 7461aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 7471aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 7481aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 749b5969abfSSean Nyekjaer }, 750290a6ce1SLorenzo Bianconi }, 751801a6e0aSLorenzo Bianconi { 75266b662a1SLorenzo Bianconi .reset = { 75366b662a1SLorenzo Bianconi .addr = 0x12, 75466b662a1SLorenzo Bianconi .mask = BIT(0), 75566b662a1SLorenzo Bianconi }, 75666b662a1SLorenzo Bianconi .boot = { 75766b662a1SLorenzo Bianconi .addr = 0x12, 75866b662a1SLorenzo Bianconi .mask = BIT(7), 75966b662a1SLorenzo Bianconi }, 76066b662a1SLorenzo Bianconi .bdu = { 76166b662a1SLorenzo Bianconi .addr = 0x12, 76266b662a1SLorenzo Bianconi .mask = BIT(6), 76366b662a1SLorenzo Bianconi }, 76443901008SLorenzo Bianconi .id = { 76581956a93SLorenzo Bianconi { 76681956a93SLorenzo Bianconi .hw_id = ST_LSM6DSR_ID, 76781956a93SLorenzo Bianconi .name = ST_LSM6DSR_DEV_NAME, 76898c3544aSLorenzo Bianconi .wai = 0x6b, 769db947a79SLorenzo Bianconi }, { 770db947a79SLorenzo Bianconi .hw_id = ST_ISM330DHCX_ID, 771db947a79SLorenzo Bianconi .name = ST_ISM330DHCX_DEV_NAME, 77298c3544aSLorenzo Bianconi .wai = 0x6b, 773cf9c71b3SLorenzo Bianconi }, { 774cf9c71b3SLorenzo Bianconi .hw_id = ST_LSM6DSRX_ID, 775cf9c71b3SLorenzo Bianconi .name = ST_LSM6DSRX_DEV_NAME, 77698c3544aSLorenzo Bianconi .wai = 0x6b, 77798c3544aSLorenzo Bianconi }, { 77898c3544aSLorenzo Bianconi .hw_id = ST_LSM6DSO_ID, 77998c3544aSLorenzo Bianconi .name = ST_LSM6DSO_DEV_NAME, 78098c3544aSLorenzo Bianconi .wai = 0x6c, 78198c3544aSLorenzo Bianconi }, { 78298c3544aSLorenzo Bianconi .hw_id = ST_LSM6DSOX_ID, 78398c3544aSLorenzo Bianconi .name = ST_LSM6DSOX_DEV_NAME, 78498c3544aSLorenzo Bianconi .wai = 0x6c, 78598c3544aSLorenzo Bianconi }, { 7864393e4c5SLorenzo Bianconi .hw_id = ST_LSM6DST_ID, 7874393e4c5SLorenzo Bianconi .name = ST_LSM6DST_DEV_NAME, 78898c3544aSLorenzo Bianconi .wai = 0x6d, 789*fdd70d7aSLorenzo Bianconi }, { 790*fdd70d7aSLorenzo Bianconi .hw_id = ST_ASM330LHHX_ID, 791*fdd70d7aSLorenzo Bianconi .name = ST_ASM330LHHX_DEV_NAME, 792*fdd70d7aSLorenzo Bianconi .wai = 0x6b, 7934393e4c5SLorenzo Bianconi }, 7944393e4c5SLorenzo Bianconi }, 7954393e4c5SLorenzo Bianconi .channels = { 7964393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 7974393e4c5SLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 7984393e4c5SLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 7994393e4c5SLorenzo Bianconi }, 8004393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 8014393e4c5SLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 8024393e4c5SLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 8034393e4c5SLorenzo Bianconi }, 8044393e4c5SLorenzo Bianconi }, 8054393e4c5SLorenzo Bianconi .drdy_mask = { 8064393e4c5SLorenzo Bianconi .addr = 0x13, 8074393e4c5SLorenzo Bianconi .mask = BIT(3), 8084393e4c5SLorenzo Bianconi }, 8094393e4c5SLorenzo Bianconi .odr_table = { 8104393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 8114393e4c5SLorenzo Bianconi .reg = { 8124393e4c5SLorenzo Bianconi .addr = 0x10, 8134393e4c5SLorenzo Bianconi .mask = GENMASK(7, 4), 8144393e4c5SLorenzo Bianconi }, 8154393e4c5SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 8164393e4c5SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 8174393e4c5SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 8184393e4c5SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 8194393e4c5SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 8204393e4c5SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 8214393e4c5SLorenzo Bianconi .odr_avl[6] = { 833000, 0x07 }, 8224393e4c5SLorenzo Bianconi .odr_len = 7, 8234393e4c5SLorenzo Bianconi }, 8244393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 8254393e4c5SLorenzo Bianconi .reg = { 8264393e4c5SLorenzo Bianconi .addr = 0x11, 8274393e4c5SLorenzo Bianconi .mask = GENMASK(7, 4), 8284393e4c5SLorenzo Bianconi }, 8294393e4c5SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 8304393e4c5SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 8314393e4c5SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 8324393e4c5SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 8334393e4c5SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 8344393e4c5SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 8354393e4c5SLorenzo Bianconi .odr_avl[6] = { 833000, 0x07 }, 8364393e4c5SLorenzo Bianconi .odr_len = 7, 8374393e4c5SLorenzo Bianconi }, 8384393e4c5SLorenzo Bianconi }, 8394393e4c5SLorenzo Bianconi .fs_table = { 8404393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 8414393e4c5SLorenzo Bianconi .reg = { 8424393e4c5SLorenzo Bianconi .addr = 0x10, 8434393e4c5SLorenzo Bianconi .mask = GENMASK(3, 2), 8444393e4c5SLorenzo Bianconi }, 8454393e4c5SLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 8464393e4c5SLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 8474393e4c5SLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 8484393e4c5SLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, 8494393e4c5SLorenzo Bianconi .fs_len = 4, 8504393e4c5SLorenzo Bianconi }, 8514393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 8524393e4c5SLorenzo Bianconi .reg = { 8534393e4c5SLorenzo Bianconi .addr = 0x11, 8544393e4c5SLorenzo Bianconi .mask = GENMASK(3, 2), 8554393e4c5SLorenzo Bianconi }, 8564393e4c5SLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 8574393e4c5SLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 8584393e4c5SLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, 8594393e4c5SLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 8604393e4c5SLorenzo Bianconi .fs_len = 4, 8614393e4c5SLorenzo Bianconi }, 8624393e4c5SLorenzo Bianconi }, 8634393e4c5SLorenzo Bianconi .irq_config = { 8644393e4c5SLorenzo Bianconi .irq1 = { 8654393e4c5SLorenzo Bianconi .addr = 0x0d, 8664393e4c5SLorenzo Bianconi .mask = BIT(3), 8674393e4c5SLorenzo Bianconi }, 8684393e4c5SLorenzo Bianconi .irq2 = { 8694393e4c5SLorenzo Bianconi .addr = 0x0e, 8704393e4c5SLorenzo Bianconi .mask = BIT(3), 8714393e4c5SLorenzo Bianconi }, 8724393e4c5SLorenzo Bianconi .lir = { 8734393e4c5SLorenzo Bianconi .addr = 0x56, 8744393e4c5SLorenzo Bianconi .mask = BIT(0), 8754393e4c5SLorenzo Bianconi }, 8764393e4c5SLorenzo Bianconi .clear_on_read = { 8774393e4c5SLorenzo Bianconi .addr = 0x56, 8784393e4c5SLorenzo Bianconi .mask = BIT(6), 8794393e4c5SLorenzo Bianconi }, 8804393e4c5SLorenzo Bianconi .irq1_func = { 8814393e4c5SLorenzo Bianconi .addr = 0x5e, 8824393e4c5SLorenzo Bianconi .mask = BIT(5), 8834393e4c5SLorenzo Bianconi }, 8844393e4c5SLorenzo Bianconi .irq2_func = { 8854393e4c5SLorenzo Bianconi .addr = 0x5f, 8864393e4c5SLorenzo Bianconi .mask = BIT(5), 8874393e4c5SLorenzo Bianconi }, 8884393e4c5SLorenzo Bianconi .hla = { 8894393e4c5SLorenzo Bianconi .addr = 0x12, 8904393e4c5SLorenzo Bianconi .mask = BIT(5), 8914393e4c5SLorenzo Bianconi }, 8924393e4c5SLorenzo Bianconi .od = { 8934393e4c5SLorenzo Bianconi .addr = 0x12, 8944393e4c5SLorenzo Bianconi .mask = BIT(4), 8954393e4c5SLorenzo Bianconi }, 8964393e4c5SLorenzo Bianconi }, 8974393e4c5SLorenzo Bianconi .batch = { 8984393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 8994393e4c5SLorenzo Bianconi .addr = 0x09, 9004393e4c5SLorenzo Bianconi .mask = GENMASK(3, 0), 9014393e4c5SLorenzo Bianconi }, 9024393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 9034393e4c5SLorenzo Bianconi .addr = 0x09, 9044393e4c5SLorenzo Bianconi .mask = GENMASK(7, 4), 9054393e4c5SLorenzo Bianconi }, 9064393e4c5SLorenzo Bianconi }, 9074393e4c5SLorenzo Bianconi .fifo_ops = { 9084393e4c5SLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 9094393e4c5SLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 9104393e4c5SLorenzo Bianconi .fifo_th = { 9114393e4c5SLorenzo Bianconi .addr = 0x07, 9124393e4c5SLorenzo Bianconi .mask = GENMASK(8, 0), 9134393e4c5SLorenzo Bianconi }, 9144393e4c5SLorenzo Bianconi .fifo_diff = { 9154393e4c5SLorenzo Bianconi .addr = 0x3a, 9164393e4c5SLorenzo Bianconi .mask = GENMASK(9, 0), 9174393e4c5SLorenzo Bianconi }, 9181b7da2faSLorenzo Bianconi .max_size = 512, 9194393e4c5SLorenzo Bianconi .th_wl = 1, 9204393e4c5SLorenzo Bianconi }, 9214393e4c5SLorenzo Bianconi .ts_settings = { 9224393e4c5SLorenzo Bianconi .timer_en = { 9234393e4c5SLorenzo Bianconi .addr = 0x19, 9244393e4c5SLorenzo Bianconi .mask = BIT(5), 9254393e4c5SLorenzo Bianconi }, 9264393e4c5SLorenzo Bianconi .decimator = { 9274393e4c5SLorenzo Bianconi .addr = 0x0a, 9284393e4c5SLorenzo Bianconi .mask = GENMASK(7, 6), 9294393e4c5SLorenzo Bianconi }, 9304393e4c5SLorenzo Bianconi .freq_fine = 0x63, 9314393e4c5SLorenzo Bianconi }, 9324393e4c5SLorenzo Bianconi .shub_settings = { 9334393e4c5SLorenzo Bianconi .page_mux = { 9344393e4c5SLorenzo Bianconi .addr = 0x01, 9354393e4c5SLorenzo Bianconi .mask = BIT(6), 9364393e4c5SLorenzo Bianconi }, 9374393e4c5SLorenzo Bianconi .master_en = { 9384393e4c5SLorenzo Bianconi .sec_page = true, 9394393e4c5SLorenzo Bianconi .addr = 0x14, 9404393e4c5SLorenzo Bianconi .mask = BIT(2), 9414393e4c5SLorenzo Bianconi }, 9424393e4c5SLorenzo Bianconi .pullup_en = { 9434393e4c5SLorenzo Bianconi .sec_page = true, 9444393e4c5SLorenzo Bianconi .addr = 0x14, 9454393e4c5SLorenzo Bianconi .mask = BIT(3), 9464393e4c5SLorenzo Bianconi }, 9474393e4c5SLorenzo Bianconi .aux_sens = { 9484393e4c5SLorenzo Bianconi .addr = 0x14, 9494393e4c5SLorenzo Bianconi .mask = GENMASK(1, 0), 9504393e4c5SLorenzo Bianconi }, 9514393e4c5SLorenzo Bianconi .wr_once = { 9524393e4c5SLorenzo Bianconi .addr = 0x14, 9534393e4c5SLorenzo Bianconi .mask = BIT(6), 9544393e4c5SLorenzo Bianconi }, 9554393e4c5SLorenzo Bianconi .num_ext_dev = 3, 9564393e4c5SLorenzo Bianconi .shub_out = { 9574393e4c5SLorenzo Bianconi .sec_page = true, 9584393e4c5SLorenzo Bianconi .addr = 0x02, 9594393e4c5SLorenzo Bianconi }, 9604393e4c5SLorenzo Bianconi .slv0_addr = 0x15, 9614393e4c5SLorenzo Bianconi .dw_slv0_addr = 0x21, 9624393e4c5SLorenzo Bianconi .batch_en = BIT(3), 9634393e4c5SLorenzo Bianconi }, 9644393e4c5SLorenzo Bianconi .event_settings = { 9654393e4c5SLorenzo Bianconi .enable_reg = { 9664393e4c5SLorenzo Bianconi .addr = 0x58, 9674393e4c5SLorenzo Bianconi .mask = BIT(7), 9684393e4c5SLorenzo Bianconi }, 9694393e4c5SLorenzo Bianconi .wakeup_reg = { 9704393e4c5SLorenzo Bianconi .addr = 0x5b, 9714393e4c5SLorenzo Bianconi .mask = GENMASK(5, 0), 9724393e4c5SLorenzo Bianconi }, 9734393e4c5SLorenzo Bianconi .wakeup_src_reg = 0x1b, 9744393e4c5SLorenzo Bianconi .wakeup_src_status_mask = BIT(3), 9754393e4c5SLorenzo Bianconi .wakeup_src_z_mask = BIT(0), 9764393e4c5SLorenzo Bianconi .wakeup_src_y_mask = BIT(1), 9774393e4c5SLorenzo Bianconi .wakeup_src_x_mask = BIT(2), 9784393e4c5SLorenzo Bianconi }, 9794393e4c5SLorenzo Bianconi }, 98098c3544aSLorenzo Bianconi { 98198c3544aSLorenzo Bianconi .reset = { 98298c3544aSLorenzo Bianconi .addr = 0x12, 98398c3544aSLorenzo Bianconi .mask = BIT(0), 98498c3544aSLorenzo Bianconi }, 98598c3544aSLorenzo Bianconi .boot = { 98698c3544aSLorenzo Bianconi .addr = 0x12, 98798c3544aSLorenzo Bianconi .mask = BIT(7), 98898c3544aSLorenzo Bianconi }, 98998c3544aSLorenzo Bianconi .bdu = { 99098c3544aSLorenzo Bianconi .addr = 0x12, 99198c3544aSLorenzo Bianconi .mask = BIT(6), 99298c3544aSLorenzo Bianconi }, 99398c3544aSLorenzo Bianconi .id = { 99498c3544aSLorenzo Bianconi { 99598c3544aSLorenzo Bianconi .hw_id = ST_ASM330LHH_ID, 99698c3544aSLorenzo Bianconi .name = ST_ASM330LHH_DEV_NAME, 99798c3544aSLorenzo Bianconi .wai = 0x6b, 9982c57d265SLorenzo Bianconi }, { 9992c57d265SLorenzo Bianconi .hw_id = ST_LSM6DSOP_ID, 10002c57d265SLorenzo Bianconi .name = ST_LSM6DSOP_DEV_NAME, 10012c57d265SLorenzo Bianconi .wai = 0x6c, 100298c3544aSLorenzo Bianconi }, 100398c3544aSLorenzo Bianconi }, 100498c3544aSLorenzo Bianconi .channels = { 100598c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 100698c3544aSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 100798c3544aSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 100898c3544aSLorenzo Bianconi }, 100998c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 101098c3544aSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 101198c3544aSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 101298c3544aSLorenzo Bianconi }, 101398c3544aSLorenzo Bianconi }, 101498c3544aSLorenzo Bianconi .drdy_mask = { 101598c3544aSLorenzo Bianconi .addr = 0x13, 101698c3544aSLorenzo Bianconi .mask = BIT(3), 101798c3544aSLorenzo Bianconi }, 101898c3544aSLorenzo Bianconi .odr_table = { 101998c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 102098c3544aSLorenzo Bianconi .reg = { 102198c3544aSLorenzo Bianconi .addr = 0x10, 102298c3544aSLorenzo Bianconi .mask = GENMASK(7, 4), 102398c3544aSLorenzo Bianconi }, 102498c3544aSLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 102598c3544aSLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 102698c3544aSLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 102798c3544aSLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 102898c3544aSLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 102998c3544aSLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 103098c3544aSLorenzo Bianconi .odr_avl[6] = { 833000, 0x07 }, 103198c3544aSLorenzo Bianconi .odr_len = 7, 103298c3544aSLorenzo Bianconi }, 103398c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 103498c3544aSLorenzo Bianconi .reg = { 103598c3544aSLorenzo Bianconi .addr = 0x11, 103698c3544aSLorenzo Bianconi .mask = GENMASK(7, 4), 103798c3544aSLorenzo Bianconi }, 103898c3544aSLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 103998c3544aSLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 104098c3544aSLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 104198c3544aSLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 104298c3544aSLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 104398c3544aSLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 104498c3544aSLorenzo Bianconi .odr_avl[6] = { 833000, 0x07 }, 104598c3544aSLorenzo Bianconi .odr_len = 7, 104698c3544aSLorenzo Bianconi }, 104798c3544aSLorenzo Bianconi }, 104898c3544aSLorenzo Bianconi .fs_table = { 104998c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 105098c3544aSLorenzo Bianconi .reg = { 105198c3544aSLorenzo Bianconi .addr = 0x10, 105298c3544aSLorenzo Bianconi .mask = GENMASK(3, 2), 105398c3544aSLorenzo Bianconi }, 105498c3544aSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 105598c3544aSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 105698c3544aSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 105798c3544aSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, 105898c3544aSLorenzo Bianconi .fs_len = 4, 105998c3544aSLorenzo Bianconi }, 106098c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 106198c3544aSLorenzo Bianconi .reg = { 106298c3544aSLorenzo Bianconi .addr = 0x11, 106398c3544aSLorenzo Bianconi .mask = GENMASK(3, 2), 106498c3544aSLorenzo Bianconi }, 106598c3544aSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 106698c3544aSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 106798c3544aSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, 106898c3544aSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 106998c3544aSLorenzo Bianconi .fs_len = 4, 107098c3544aSLorenzo Bianconi }, 107198c3544aSLorenzo Bianconi }, 107298c3544aSLorenzo Bianconi .irq_config = { 107398c3544aSLorenzo Bianconi .irq1 = { 107498c3544aSLorenzo Bianconi .addr = 0x0d, 107598c3544aSLorenzo Bianconi .mask = BIT(3), 107698c3544aSLorenzo Bianconi }, 107798c3544aSLorenzo Bianconi .irq2 = { 107898c3544aSLorenzo Bianconi .addr = 0x0e, 107998c3544aSLorenzo Bianconi .mask = BIT(3), 108098c3544aSLorenzo Bianconi }, 108198c3544aSLorenzo Bianconi .lir = { 108298c3544aSLorenzo Bianconi .addr = 0x56, 108398c3544aSLorenzo Bianconi .mask = BIT(0), 108498c3544aSLorenzo Bianconi }, 108598c3544aSLorenzo Bianconi .clear_on_read = { 108698c3544aSLorenzo Bianconi .addr = 0x56, 108798c3544aSLorenzo Bianconi .mask = BIT(6), 108898c3544aSLorenzo Bianconi }, 108998c3544aSLorenzo Bianconi .irq1_func = { 109098c3544aSLorenzo Bianconi .addr = 0x5e, 109198c3544aSLorenzo Bianconi .mask = BIT(5), 109298c3544aSLorenzo Bianconi }, 109398c3544aSLorenzo Bianconi .irq2_func = { 109498c3544aSLorenzo Bianconi .addr = 0x5f, 109598c3544aSLorenzo Bianconi .mask = BIT(5), 109698c3544aSLorenzo Bianconi }, 109798c3544aSLorenzo Bianconi .hla = { 109898c3544aSLorenzo Bianconi .addr = 0x12, 109998c3544aSLorenzo Bianconi .mask = BIT(5), 110098c3544aSLorenzo Bianconi }, 110198c3544aSLorenzo Bianconi .od = { 110298c3544aSLorenzo Bianconi .addr = 0x12, 110398c3544aSLorenzo Bianconi .mask = BIT(4), 110498c3544aSLorenzo Bianconi }, 110598c3544aSLorenzo Bianconi }, 110698c3544aSLorenzo Bianconi .batch = { 110798c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 110898c3544aSLorenzo Bianconi .addr = 0x09, 110998c3544aSLorenzo Bianconi .mask = GENMASK(3, 0), 111098c3544aSLorenzo Bianconi }, 111198c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 111298c3544aSLorenzo Bianconi .addr = 0x09, 111398c3544aSLorenzo Bianconi .mask = GENMASK(7, 4), 111498c3544aSLorenzo Bianconi }, 111598c3544aSLorenzo Bianconi }, 111698c3544aSLorenzo Bianconi .fifo_ops = { 111798c3544aSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 111898c3544aSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 111998c3544aSLorenzo Bianconi .fifo_th = { 112098c3544aSLorenzo Bianconi .addr = 0x07, 112198c3544aSLorenzo Bianconi .mask = GENMASK(8, 0), 112298c3544aSLorenzo Bianconi }, 112398c3544aSLorenzo Bianconi .fifo_diff = { 112498c3544aSLorenzo Bianconi .addr = 0x3a, 112598c3544aSLorenzo Bianconi .mask = GENMASK(9, 0), 112698c3544aSLorenzo Bianconi }, 11271b7da2faSLorenzo Bianconi .max_size = 512, 112898c3544aSLorenzo Bianconi .th_wl = 1, 112998c3544aSLorenzo Bianconi }, 113098c3544aSLorenzo Bianconi .ts_settings = { 113198c3544aSLorenzo Bianconi .timer_en = { 113298c3544aSLorenzo Bianconi .addr = 0x19, 113398c3544aSLorenzo Bianconi .mask = BIT(5), 113498c3544aSLorenzo Bianconi }, 113598c3544aSLorenzo Bianconi .decimator = { 113698c3544aSLorenzo Bianconi .addr = 0x0a, 113798c3544aSLorenzo Bianconi .mask = GENMASK(7, 6), 113898c3544aSLorenzo Bianconi }, 113998c3544aSLorenzo Bianconi .freq_fine = 0x63, 114098c3544aSLorenzo Bianconi }, 114198c3544aSLorenzo Bianconi .event_settings = { 114298c3544aSLorenzo Bianconi .enable_reg = { 114398c3544aSLorenzo Bianconi .addr = 0x58, 114498c3544aSLorenzo Bianconi .mask = BIT(7), 114598c3544aSLorenzo Bianconi }, 114698c3544aSLorenzo Bianconi .wakeup_reg = { 114798c3544aSLorenzo Bianconi .addr = 0x5B, 114898c3544aSLorenzo Bianconi .mask = GENMASK(5, 0), 114998c3544aSLorenzo Bianconi }, 115098c3544aSLorenzo Bianconi .wakeup_src_reg = 0x1b, 115198c3544aSLorenzo Bianconi .wakeup_src_status_mask = BIT(3), 115298c3544aSLorenzo Bianconi .wakeup_src_z_mask = BIT(0), 115398c3544aSLorenzo Bianconi .wakeup_src_y_mask = BIT(1), 115498c3544aSLorenzo Bianconi .wakeup_src_x_mask = BIT(2), 115598c3544aSLorenzo Bianconi }, 115698c3544aSLorenzo Bianconi }, 1157290a6ce1SLorenzo Bianconi }; 1158290a6ce1SLorenzo Bianconi 1159c91c1c84SLorenzo Bianconi int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable) 1160c91c1c84SLorenzo Bianconi { 1161c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 1162c91c1c84SLorenzo Bianconi unsigned int data; 1163c91c1c84SLorenzo Bianconi int err; 1164c91c1c84SLorenzo Bianconi 1165c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 1166c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask); 1167c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr, 1168c91c1c84SLorenzo Bianconi hub_settings->page_mux.mask, data); 1169c91c1c84SLorenzo Bianconi usleep_range(100, 150); 1170c91c1c84SLorenzo Bianconi 1171c91c1c84SLorenzo Bianconi return err; 1172c91c1c84SLorenzo Bianconi } 1173c91c1c84SLorenzo Bianconi 117481956a93SLorenzo Bianconi static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id, 117581956a93SLorenzo Bianconi const char **name) 1176290a6ce1SLorenzo Bianconi { 117751a8b707SLorenzo Bianconi int err, i, j, data; 1178290a6ce1SLorenzo Bianconi 1179290a6ce1SLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) { 1180d068e4a0SLorenzo Bianconi for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) { 1181fb4fbc89SStephan Gerhold if (st_lsm6dsx_sensor_settings[i].id[j].name && 1182fb4fbc89SStephan Gerhold id == st_lsm6dsx_sensor_settings[i].id[j].hw_id) 1183d068e4a0SLorenzo Bianconi break; 1184d068e4a0SLorenzo Bianconi } 1185d068e4a0SLorenzo Bianconi if (j < ST_LSM6DSX_MAX_ID) 1186290a6ce1SLorenzo Bianconi break; 1187290a6ce1SLorenzo Bianconi } 1188290a6ce1SLorenzo Bianconi 1189290a6ce1SLorenzo Bianconi if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) { 1190290a6ce1SLorenzo Bianconi dev_err(hw->dev, "unsupported hw id [%02x]\n", id); 1191290a6ce1SLorenzo Bianconi return -ENODEV; 1192290a6ce1SLorenzo Bianconi } 1193290a6ce1SLorenzo Bianconi 119451a8b707SLorenzo Bianconi err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data); 1195290a6ce1SLorenzo Bianconi if (err < 0) { 1196290a6ce1SLorenzo Bianconi dev_err(hw->dev, "failed to read whoami register\n"); 1197290a6ce1SLorenzo Bianconi return err; 1198290a6ce1SLorenzo Bianconi } 1199290a6ce1SLorenzo Bianconi 120098c3544aSLorenzo Bianconi if (data != st_lsm6dsx_sensor_settings[i].id[j].wai) { 1201290a6ce1SLorenzo Bianconi dev_err(hw->dev, "unsupported whoami [%02x]\n", data); 1202290a6ce1SLorenzo Bianconi return -ENODEV; 1203290a6ce1SLorenzo Bianconi } 1204290a6ce1SLorenzo Bianconi 120581956a93SLorenzo Bianconi *name = st_lsm6dsx_sensor_settings[i].id[j].name; 1206290a6ce1SLorenzo Bianconi hw->settings = &st_lsm6dsx_sensor_settings[i]; 1207290a6ce1SLorenzo Bianconi 1208290a6ce1SLorenzo Bianconi return 0; 1209290a6ce1SLorenzo Bianconi } 1210290a6ce1SLorenzo Bianconi 1211290a6ce1SLorenzo Bianconi static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, 1212290a6ce1SLorenzo Bianconi u32 gain) 1213290a6ce1SLorenzo Bianconi { 1214640aca3fSLorenzo Bianconi const struct st_lsm6dsx_fs_table_entry *fs_table; 1215739aff87SLorenzo Bianconi unsigned int data; 1216290a6ce1SLorenzo Bianconi int i, err; 1217290a6ce1SLorenzo Bianconi 1218640aca3fSLorenzo Bianconi fs_table = &sensor->hw->settings->fs_table[sensor->id]; 121985ae3aeeSLorenzo Bianconi for (i = 0; i < fs_table->fs_len; i++) { 1220640aca3fSLorenzo Bianconi if (fs_table->fs_avl[i].gain == gain) 1221290a6ce1SLorenzo Bianconi break; 122285ae3aeeSLorenzo Bianconi } 1223290a6ce1SLorenzo Bianconi 122485ae3aeeSLorenzo Bianconi if (i == fs_table->fs_len) 1225290a6ce1SLorenzo Bianconi return -EINVAL; 1226290a6ce1SLorenzo Bianconi 1227640aca3fSLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val, 1228640aca3fSLorenzo Bianconi fs_table->reg.mask); 1229640aca3fSLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr, 1230640aca3fSLorenzo Bianconi fs_table->reg.mask, data); 1231290a6ce1SLorenzo Bianconi if (err < 0) 1232290a6ce1SLorenzo Bianconi return err; 1233290a6ce1SLorenzo Bianconi 1234290a6ce1SLorenzo Bianconi sensor->gain = gain; 1235290a6ce1SLorenzo Bianconi 1236290a6ce1SLorenzo Bianconi return 0; 1237290a6ce1SLorenzo Bianconi } 1238290a6ce1SLorenzo Bianconi 1239f8710f03SLorenzo Bianconi int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val) 1240290a6ce1SLorenzo Bianconi { 124140dd7343SLorenzo Bianconi const struct st_lsm6dsx_odr_table_entry *odr_table; 12422ccc1503SLorenzo Bianconi int i; 1243290a6ce1SLorenzo Bianconi 124440dd7343SLorenzo Bianconi odr_table = &sensor->hw->settings->odr_table[sensor->id]; 124559af4e20SLorenzo Bianconi for (i = 0; i < odr_table->odr_len; i++) { 12466ffb55e5SLorenzo Bianconi /* 12476ffb55e5SLorenzo Bianconi * ext devices can run at different odr respect to 12486ffb55e5SLorenzo Bianconi * accel sensor 12496ffb55e5SLorenzo Bianconi */ 1250f8710f03SLorenzo Bianconi if (odr_table->odr_avl[i].milli_hz >= odr) 1251290a6ce1SLorenzo Bianconi break; 125259af4e20SLorenzo Bianconi } 1253290a6ce1SLorenzo Bianconi 125459af4e20SLorenzo Bianconi if (i == odr_table->odr_len) 1255290a6ce1SLorenzo Bianconi return -EINVAL; 1256290a6ce1SLorenzo Bianconi 125740dd7343SLorenzo Bianconi *val = odr_table->odr_avl[i].val; 1258f8710f03SLorenzo Bianconi return odr_table->odr_avl[i].milli_hz; 1259290a6ce1SLorenzo Bianconi } 1260290a6ce1SLorenzo Bianconi 1261f8710f03SLorenzo Bianconi static int 1262f8710f03SLorenzo Bianconi st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u32 odr, 12636ffb55e5SLorenzo Bianconi enum st_lsm6dsx_sensor_id id) 12642ccc1503SLorenzo Bianconi { 12656ffb55e5SLorenzo Bianconi struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]); 12666ffb55e5SLorenzo Bianconi 12676ffb55e5SLorenzo Bianconi if (odr > 0) { 12686ffb55e5SLorenzo Bianconi if (hw->enable_mask & BIT(id)) 1269f8710f03SLorenzo Bianconi return max_t(u32, ref->odr, odr); 12706ffb55e5SLorenzo Bianconi else 12716ffb55e5SLorenzo Bianconi return odr; 12726ffb55e5SLorenzo Bianconi } else { 12736ffb55e5SLorenzo Bianconi return (hw->enable_mask & BIT(id)) ? ref->odr : 0; 12746ffb55e5SLorenzo Bianconi } 12756ffb55e5SLorenzo Bianconi } 12766ffb55e5SLorenzo Bianconi 1277f8710f03SLorenzo Bianconi static int 1278f8710f03SLorenzo Bianconi st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u32 req_odr) 12796ffb55e5SLorenzo Bianconi { 12806ffb55e5SLorenzo Bianconi struct st_lsm6dsx_sensor *ref_sensor = sensor; 128151a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 128251a8b707SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 1283739aff87SLorenzo Bianconi unsigned int data; 12846ffb55e5SLorenzo Bianconi u8 val = 0; 12852ccc1503SLorenzo Bianconi int err; 12862ccc1503SLorenzo Bianconi 12876ffb55e5SLorenzo Bianconi switch (sensor->id) { 128894be878cSTeng Qi case ST_LSM6DSX_ID_GYRO: 128994be878cSTeng Qi break; 12906ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT0: 12916ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT1: 12926ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT2: 12936ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_ACC: { 1294f8710f03SLorenzo Bianconi u32 odr; 12956ffb55e5SLorenzo Bianconi int i; 12966ffb55e5SLorenzo Bianconi 12976ffb55e5SLorenzo Bianconi /* 12986ffb55e5SLorenzo Bianconi * i2c embedded controller relies on the accelerometer sensor as 12996ffb55e5SLorenzo Bianconi * bus read/write trigger so we need to enable accel device 13006ffb55e5SLorenzo Bianconi * at odr = max(accel_odr, ext_odr) in order to properly 13016ffb55e5SLorenzo Bianconi * communicate with i2c slave devices 13026ffb55e5SLorenzo Bianconi */ 13036ffb55e5SLorenzo Bianconi ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); 13046ffb55e5SLorenzo Bianconi for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) { 13056ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i] || i == sensor->id) 13066ffb55e5SLorenzo Bianconi continue; 13076ffb55e5SLorenzo Bianconi 13086ffb55e5SLorenzo Bianconi odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i); 13096ffb55e5SLorenzo Bianconi if (odr != req_odr) 13106ffb55e5SLorenzo Bianconi /* device already configured */ 13116ffb55e5SLorenzo Bianconi return 0; 13126ffb55e5SLorenzo Bianconi } 13136ffb55e5SLorenzo Bianconi break; 13146ffb55e5SLorenzo Bianconi } 131594be878cSTeng Qi default: /* should never occur */ 131694be878cSTeng Qi return -EINVAL; 13176ffb55e5SLorenzo Bianconi } 13186ffb55e5SLorenzo Bianconi 13196ffb55e5SLorenzo Bianconi if (req_odr > 0) { 13206ffb55e5SLorenzo Bianconi err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val); 13212ccc1503SLorenzo Bianconi if (err < 0) 13222ccc1503SLorenzo Bianconi return err; 13236ffb55e5SLorenzo Bianconi } 13242ccc1503SLorenzo Bianconi 132540dd7343SLorenzo Bianconi reg = &hw->settings->odr_table[ref_sensor->id].reg; 1326739aff87SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask); 1327739aff87SLorenzo Bianconi return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data); 13282ccc1503SLorenzo Bianconi } 13292ccc1503SLorenzo Bianconi 1330bd41c445SLorenzo Bianconi static int 1331bd41c445SLorenzo Bianconi __st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, 133217750443SLorenzo Bianconi bool enable) 1333290a6ce1SLorenzo Bianconi { 133451a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1335f8710f03SLorenzo Bianconi u32 odr = enable ? sensor->odr : 0; 1336290a6ce1SLorenzo Bianconi int err; 1337290a6ce1SLorenzo Bianconi 133817750443SLorenzo Bianconi err = st_lsm6dsx_set_odr(sensor, odr); 1339290a6ce1SLorenzo Bianconi if (err < 0) 1340290a6ce1SLorenzo Bianconi return err; 1341290a6ce1SLorenzo Bianconi 134217750443SLorenzo Bianconi if (enable) 134317750443SLorenzo Bianconi hw->enable_mask |= BIT(sensor->id); 134417750443SLorenzo Bianconi else 134517750443SLorenzo Bianconi hw->enable_mask &= ~BIT(sensor->id); 1346290a6ce1SLorenzo Bianconi 1347290a6ce1SLorenzo Bianconi return 0; 1348290a6ce1SLorenzo Bianconi } 1349290a6ce1SLorenzo Bianconi 1350bd41c445SLorenzo Bianconi static int 1351bd41c445SLorenzo Bianconi st_lsm6dsx_check_events(struct st_lsm6dsx_sensor *sensor, bool enable) 1352bd41c445SLorenzo Bianconi { 1353bd41c445SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1354bd41c445SLorenzo Bianconi 1355bd41c445SLorenzo Bianconi if (sensor->id == ST_LSM6DSX_ID_GYRO || enable) 1356bd41c445SLorenzo Bianconi return 0; 1357bd41c445SLorenzo Bianconi 1358bd41c445SLorenzo Bianconi return hw->enable_event; 1359bd41c445SLorenzo Bianconi } 1360bd41c445SLorenzo Bianconi 1361bd41c445SLorenzo Bianconi int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, 1362bd41c445SLorenzo Bianconi bool enable) 1363bd41c445SLorenzo Bianconi { 1364bd41c445SLorenzo Bianconi if (st_lsm6dsx_check_events(sensor, enable)) 1365bd41c445SLorenzo Bianconi return 0; 1366bd41c445SLorenzo Bianconi 1367bd41c445SLorenzo Bianconi return __st_lsm6dsx_sensor_set_enable(sensor, enable); 1368bd41c445SLorenzo Bianconi } 1369bd41c445SLorenzo Bianconi 1370290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, 1371290a6ce1SLorenzo Bianconi u8 addr, int *val) 1372290a6ce1SLorenzo Bianconi { 137351a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1374290a6ce1SLorenzo Bianconi int err, delay; 1375290a6ce1SLorenzo Bianconi __le16 data; 1376290a6ce1SLorenzo Bianconi 137717750443SLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, true); 1378290a6ce1SLorenzo Bianconi if (err < 0) 1379290a6ce1SLorenzo Bianconi return err; 1380290a6ce1SLorenzo Bianconi 1381ea85bf90SLorenzo Bianconi /* 1382ea85bf90SLorenzo Bianconi * we need to wait for sensor settling time before 1383ea85bf90SLorenzo Bianconi * reading data in order to avoid corrupted samples 1384ea85bf90SLorenzo Bianconi */ 1385f8710f03SLorenzo Bianconi delay = 1000000000 / sensor->odr; 1386ea85bf90SLorenzo Bianconi usleep_range(3 * delay, 4 * delay); 1387290a6ce1SLorenzo Bianconi 1388739aff87SLorenzo Bianconi err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data)); 1389290a6ce1SLorenzo Bianconi if (err < 0) 1390290a6ce1SLorenzo Bianconi return err; 1391290a6ce1SLorenzo Bianconi 1392a2dd9bd9SLorenzo Bianconi if (!hw->enable_event) { 1393a2dd9bd9SLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, false); 1394a2dd9bd9SLorenzo Bianconi if (err < 0) 1395a2dd9bd9SLorenzo Bianconi return err; 1396a2dd9bd9SLorenzo Bianconi } 1397290a6ce1SLorenzo Bianconi 13987b9ebe42SLorenzo Bianconi *val = (s16)le16_to_cpu(data); 1399290a6ce1SLorenzo Bianconi 1400290a6ce1SLorenzo Bianconi return IIO_VAL_INT; 1401290a6ce1SLorenzo Bianconi } 1402290a6ce1SLorenzo Bianconi 1403290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev, 1404290a6ce1SLorenzo Bianconi struct iio_chan_spec const *ch, 1405290a6ce1SLorenzo Bianconi int *val, int *val2, long mask) 1406290a6ce1SLorenzo Bianconi { 1407290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1408290a6ce1SLorenzo Bianconi int ret; 1409290a6ce1SLorenzo Bianconi 1410290a6ce1SLorenzo Bianconi switch (mask) { 1411290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_RAW: 1412290a6ce1SLorenzo Bianconi ret = iio_device_claim_direct_mode(iio_dev); 1413290a6ce1SLorenzo Bianconi if (ret) 1414290a6ce1SLorenzo Bianconi break; 1415290a6ce1SLorenzo Bianconi 1416290a6ce1SLorenzo Bianconi ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val); 1417290a6ce1SLorenzo Bianconi iio_device_release_direct_mode(iio_dev); 1418290a6ce1SLorenzo Bianconi break; 1419290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SAMP_FREQ: 1420f8710f03SLorenzo Bianconi *val = sensor->odr / 1000; 1421f8710f03SLorenzo Bianconi *val2 = (sensor->odr % 1000) * 1000; 1422f8710f03SLorenzo Bianconi ret = IIO_VAL_INT_PLUS_MICRO; 1423290a6ce1SLorenzo Bianconi break; 1424290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SCALE: 1425290a6ce1SLorenzo Bianconi *val = 0; 1426290a6ce1SLorenzo Bianconi *val2 = sensor->gain; 142744a76de8SMario Tesi ret = IIO_VAL_INT_PLUS_NANO; 1428290a6ce1SLorenzo Bianconi break; 1429290a6ce1SLorenzo Bianconi default: 1430290a6ce1SLorenzo Bianconi ret = -EINVAL; 1431290a6ce1SLorenzo Bianconi break; 1432290a6ce1SLorenzo Bianconi } 1433290a6ce1SLorenzo Bianconi 1434290a6ce1SLorenzo Bianconi return ret; 1435290a6ce1SLorenzo Bianconi } 1436290a6ce1SLorenzo Bianconi 1437290a6ce1SLorenzo Bianconi static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev, 1438290a6ce1SLorenzo Bianconi struct iio_chan_spec const *chan, 1439290a6ce1SLorenzo Bianconi int val, int val2, long mask) 1440290a6ce1SLorenzo Bianconi { 1441290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1442290a6ce1SLorenzo Bianconi int err; 1443290a6ce1SLorenzo Bianconi 1444290a6ce1SLorenzo Bianconi err = iio_device_claim_direct_mode(iio_dev); 1445290a6ce1SLorenzo Bianconi if (err) 1446290a6ce1SLorenzo Bianconi return err; 1447290a6ce1SLorenzo Bianconi 1448290a6ce1SLorenzo Bianconi switch (mask) { 1449290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SCALE: 1450290a6ce1SLorenzo Bianconi err = st_lsm6dsx_set_full_scale(sensor, val2); 1451290a6ce1SLorenzo Bianconi break; 14522ccc1503SLorenzo Bianconi case IIO_CHAN_INFO_SAMP_FREQ: { 14532ccc1503SLorenzo Bianconi u8 data; 14542ccc1503SLorenzo Bianconi 1455f8710f03SLorenzo Bianconi val = val * 1000 + val2 / 1000; 1456fc3f6ad7SLorenzo Bianconi val = st_lsm6dsx_check_odr(sensor, val, &data); 1457fc3f6ad7SLorenzo Bianconi if (val < 0) 1458fc3f6ad7SLorenzo Bianconi err = val; 1459fc3f6ad7SLorenzo Bianconi else 14605e3c3e33SLorenzo Bianconi sensor->odr = val; 1461290a6ce1SLorenzo Bianconi break; 14622ccc1503SLorenzo Bianconi } 1463290a6ce1SLorenzo Bianconi default: 1464290a6ce1SLorenzo Bianconi err = -EINVAL; 1465290a6ce1SLorenzo Bianconi break; 1466290a6ce1SLorenzo Bianconi } 1467290a6ce1SLorenzo Bianconi 1468290a6ce1SLorenzo Bianconi iio_device_release_direct_mode(iio_dev); 1469290a6ce1SLorenzo Bianconi 1470290a6ce1SLorenzo Bianconi return err; 1471290a6ce1SLorenzo Bianconi } 1472290a6ce1SLorenzo Bianconi 1473b5969abfSSean Nyekjaer static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state) 1474b5969abfSSean Nyekjaer { 147584b2e7c3SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 147604ca37d5SLorenzo Bianconi unsigned int data; 1477b5969abfSSean Nyekjaer int err; 1478b5969abfSSean Nyekjaer 14797e906103SLorenzo Bianconi if (!hw->settings->irq_config.irq1_func.addr) 1480b5969abfSSean Nyekjaer return -ENOTSUPP; 1481b5969abfSSean Nyekjaer 148284b2e7c3SLorenzo Bianconi reg = &hw->settings->event_settings.enable_reg; 148384b2e7c3SLorenzo Bianconi if (reg->addr) { 148404ca37d5SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(state, reg->mask); 148504ca37d5SLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(hw, reg->addr, 148604ca37d5SLorenzo Bianconi reg->mask, data); 1487b5969abfSSean Nyekjaer if (err < 0) 1488b5969abfSSean Nyekjaer return err; 148984b2e7c3SLorenzo Bianconi } 1490b5969abfSSean Nyekjaer 1491b5969abfSSean Nyekjaer /* Enable wakeup interrupt */ 149204ca37d5SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(state, hw->irq_routing->mask); 149304ca37d5SLorenzo Bianconi return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing->addr, 149404ca37d5SLorenzo Bianconi hw->irq_routing->mask, data); 1495b5969abfSSean Nyekjaer } 1496b5969abfSSean Nyekjaer 1497b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event(struct iio_dev *iio_dev, 1498b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1499b5969abfSSean Nyekjaer enum iio_event_type type, 1500b5969abfSSean Nyekjaer enum iio_event_direction dir, 1501b5969abfSSean Nyekjaer enum iio_event_info info, 1502b5969abfSSean Nyekjaer int *val, int *val2) 1503b5969abfSSean Nyekjaer { 1504b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1505b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 1506b5969abfSSean Nyekjaer 1507b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1508b5969abfSSean Nyekjaer return -EINVAL; 1509b5969abfSSean Nyekjaer 1510b5969abfSSean Nyekjaer *val2 = 0; 1511b5969abfSSean Nyekjaer *val = hw->event_threshold; 1512b5969abfSSean Nyekjaer 1513b5969abfSSean Nyekjaer return IIO_VAL_INT; 1514b5969abfSSean Nyekjaer } 1515b5969abfSSean Nyekjaer 1516b307f495SLorenzo Bianconi static int 1517b307f495SLorenzo Bianconi st_lsm6dsx_write_event(struct iio_dev *iio_dev, 1518b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1519b5969abfSSean Nyekjaer enum iio_event_type type, 1520b5969abfSSean Nyekjaer enum iio_event_direction dir, 1521b5969abfSSean Nyekjaer enum iio_event_info info, 1522b5969abfSSean Nyekjaer int val, int val2) 1523b5969abfSSean Nyekjaer { 1524b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1525b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 152604ca37d5SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 152704ca37d5SLorenzo Bianconi unsigned int data; 1528b5969abfSSean Nyekjaer int err; 1529b5969abfSSean Nyekjaer 1530b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1531b5969abfSSean Nyekjaer return -EINVAL; 1532b5969abfSSean Nyekjaer 1533b5969abfSSean Nyekjaer if (val < 0 || val > 31) 1534b5969abfSSean Nyekjaer return -EINVAL; 1535b5969abfSSean Nyekjaer 153604ca37d5SLorenzo Bianconi reg = &hw->settings->event_settings.wakeup_reg; 153704ca37d5SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask); 153804ca37d5SLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(hw, reg->addr, 153904ca37d5SLorenzo Bianconi reg->mask, data); 154004ca37d5SLorenzo Bianconi if (err < 0) 1541b5969abfSSean Nyekjaer return -EINVAL; 1542b5969abfSSean Nyekjaer 1543b5969abfSSean Nyekjaer hw->event_threshold = val; 1544b5969abfSSean Nyekjaer 1545b5969abfSSean Nyekjaer return 0; 1546b5969abfSSean Nyekjaer } 1547b5969abfSSean Nyekjaer 1548b307f495SLorenzo Bianconi static int 1549b307f495SLorenzo Bianconi st_lsm6dsx_read_event_config(struct iio_dev *iio_dev, 1550b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1551b5969abfSSean Nyekjaer enum iio_event_type type, 1552b5969abfSSean Nyekjaer enum iio_event_direction dir) 1553b5969abfSSean Nyekjaer { 1554b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1555b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 1556b5969abfSSean Nyekjaer 1557b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1558b5969abfSSean Nyekjaer return -EINVAL; 1559b5969abfSSean Nyekjaer 15601aabad1fSSean Nyekjaer return !!(hw->enable_event & BIT(chan->channel2)); 1561b5969abfSSean Nyekjaer } 1562b5969abfSSean Nyekjaer 1563b307f495SLorenzo Bianconi static int 1564b307f495SLorenzo Bianconi st_lsm6dsx_write_event_config(struct iio_dev *iio_dev, 1565b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1566b5969abfSSean Nyekjaer enum iio_event_type type, 1567b307f495SLorenzo Bianconi enum iio_event_direction dir, int state) 1568b5969abfSSean Nyekjaer { 1569b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1570b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 15711aabad1fSSean Nyekjaer u8 enable_event; 1572bd41c445SLorenzo Bianconi int err; 1573b5969abfSSean Nyekjaer 1574b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1575b5969abfSSean Nyekjaer return -EINVAL; 1576b5969abfSSean Nyekjaer 15771aabad1fSSean Nyekjaer if (state) { 15781aabad1fSSean Nyekjaer enable_event = hw->enable_event | BIT(chan->channel2); 15791aabad1fSSean Nyekjaer 1580b5969abfSSean Nyekjaer /* do not enable events if they are already enabled */ 15811aabad1fSSean Nyekjaer if (hw->enable_event) 15821aabad1fSSean Nyekjaer goto out; 15831aabad1fSSean Nyekjaer } else { 15841aabad1fSSean Nyekjaer enable_event = hw->enable_event & ~BIT(chan->channel2); 15851aabad1fSSean Nyekjaer 15861aabad1fSSean Nyekjaer /* only turn off sensor if no events is enabled */ 15871aabad1fSSean Nyekjaer if (enable_event) 15881aabad1fSSean Nyekjaer goto out; 15891aabad1fSSean Nyekjaer } 15901aabad1fSSean Nyekjaer 15911aabad1fSSean Nyekjaer /* stop here if no changes have been made */ 15921aabad1fSSean Nyekjaer if (hw->enable_event == enable_event) 1593b5969abfSSean Nyekjaer return 0; 1594b5969abfSSean Nyekjaer 1595b5969abfSSean Nyekjaer err = st_lsm6dsx_event_setup(hw, state); 1596b5969abfSSean Nyekjaer if (err < 0) 1597b5969abfSSean Nyekjaer return err; 1598b5969abfSSean Nyekjaer 1599d278d447SLorenzo Bianconi mutex_lock(&hw->conf_lock); 1600bd41c445SLorenzo Bianconi if (enable_event || !(hw->fifo_mask & BIT(sensor->id))) 1601bd41c445SLorenzo Bianconi err = __st_lsm6dsx_sensor_set_enable(sensor, state); 1602d278d447SLorenzo Bianconi mutex_unlock(&hw->conf_lock); 1603b5969abfSSean Nyekjaer if (err < 0) 1604b5969abfSSean Nyekjaer return err; 1605b5969abfSSean Nyekjaer 16061aabad1fSSean Nyekjaer out: 16071aabad1fSSean Nyekjaer hw->enable_event = enable_event; 1608b5969abfSSean Nyekjaer 1609b5969abfSSean Nyekjaer return 0; 1610b5969abfSSean Nyekjaer } 1611b5969abfSSean Nyekjaer 1612d40464f3SLorenzo Bianconi int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val) 1613290a6ce1SLorenzo Bianconi { 1614290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1615290a6ce1SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 16168f2a88a2SLorenzo Bianconi int err; 1617290a6ce1SLorenzo Bianconi 16181b7da2faSLorenzo Bianconi if (val < 1 || val > hw->settings->fifo_ops.max_size) 1619290a6ce1SLorenzo Bianconi return -EINVAL; 1620290a6ce1SLorenzo Bianconi 1621335eaedcSLorenzo Bianconi mutex_lock(&hw->conf_lock); 1622335eaedcSLorenzo Bianconi 1623290a6ce1SLorenzo Bianconi err = st_lsm6dsx_update_watermark(sensor, val); 1624335eaedcSLorenzo Bianconi 1625335eaedcSLorenzo Bianconi mutex_unlock(&hw->conf_lock); 1626335eaedcSLorenzo Bianconi 1627290a6ce1SLorenzo Bianconi if (err < 0) 1628290a6ce1SLorenzo Bianconi return err; 1629290a6ce1SLorenzo Bianconi 1630290a6ce1SLorenzo Bianconi sensor->watermark = val; 1631290a6ce1SLorenzo Bianconi 1632290a6ce1SLorenzo Bianconi return 0; 1633290a6ce1SLorenzo Bianconi } 1634290a6ce1SLorenzo Bianconi 1635290a6ce1SLorenzo Bianconi static ssize_t 1636290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev, 1637290a6ce1SLorenzo Bianconi struct device_attribute *attr, 1638290a6ce1SLorenzo Bianconi char *buf) 1639290a6ce1SLorenzo Bianconi { 16406270bf1fSHaibo Chen struct st_lsm6dsx_sensor *sensor = iio_priv(dev_to_iio_dev(dev)); 164159af4e20SLorenzo Bianconi const struct st_lsm6dsx_odr_table_entry *odr_table; 1642290a6ce1SLorenzo Bianconi int i, len = 0; 1643290a6ce1SLorenzo Bianconi 164459af4e20SLorenzo Bianconi odr_table = &sensor->hw->settings->odr_table[sensor->id]; 164559af4e20SLorenzo Bianconi for (i = 0; i < odr_table->odr_len; i++) 1646f8710f03SLorenzo Bianconi len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%03d ", 1647f8710f03SLorenzo Bianconi odr_table->odr_avl[i].milli_hz / 1000, 1648f8710f03SLorenzo Bianconi odr_table->odr_avl[i].milli_hz % 1000); 1649290a6ce1SLorenzo Bianconi buf[len - 1] = '\n'; 1650290a6ce1SLorenzo Bianconi 1651290a6ce1SLorenzo Bianconi return len; 1652290a6ce1SLorenzo Bianconi } 1653290a6ce1SLorenzo Bianconi 1654290a6ce1SLorenzo Bianconi static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev, 1655290a6ce1SLorenzo Bianconi struct device_attribute *attr, 1656290a6ce1SLorenzo Bianconi char *buf) 1657290a6ce1SLorenzo Bianconi { 16586270bf1fSHaibo Chen struct st_lsm6dsx_sensor *sensor = iio_priv(dev_to_iio_dev(dev)); 16590f7e1728SLorenzo Bianconi const struct st_lsm6dsx_fs_table_entry *fs_table; 1660640aca3fSLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1661290a6ce1SLorenzo Bianconi int i, len = 0; 1662290a6ce1SLorenzo Bianconi 166385ae3aeeSLorenzo Bianconi fs_table = &hw->settings->fs_table[sensor->id]; 166485ae3aeeSLorenzo Bianconi for (i = 0; i < fs_table->fs_len; i++) 166544a76de8SMario Tesi len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09u ", 16660f7e1728SLorenzo Bianconi fs_table->fs_avl[i].gain); 1667290a6ce1SLorenzo Bianconi buf[len - 1] = '\n'; 1668290a6ce1SLorenzo Bianconi 1669290a6ce1SLorenzo Bianconi return len; 1670290a6ce1SLorenzo Bianconi } 1671290a6ce1SLorenzo Bianconi 167244a76de8SMario Tesi static int st_lsm6dsx_write_raw_get_fmt(struct iio_dev *indio_dev, 167344a76de8SMario Tesi struct iio_chan_spec const *chan, 167444a76de8SMario Tesi long mask) 167544a76de8SMario Tesi { 167644a76de8SMario Tesi switch (mask) { 167744a76de8SMario Tesi case IIO_CHAN_INFO_SCALE: 167844a76de8SMario Tesi switch (chan->type) { 167944a76de8SMario Tesi case IIO_ANGL_VEL: 168044a76de8SMario Tesi case IIO_ACCEL: 168144a76de8SMario Tesi return IIO_VAL_INT_PLUS_NANO; 168244a76de8SMario Tesi default: 168344a76de8SMario Tesi return IIO_VAL_INT_PLUS_MICRO; 168444a76de8SMario Tesi } 168544a76de8SMario Tesi default: 168644a76de8SMario Tesi return IIO_VAL_INT_PLUS_MICRO; 168744a76de8SMario Tesi } 168844a76de8SMario Tesi } 168944a76de8SMario Tesi 1690290a6ce1SLorenzo Bianconi static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail); 1691290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_accel_scale_available, 0444, 1692290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_scale_avail, NULL, 0); 1693290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444, 1694290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_scale_avail, NULL, 0); 1695290a6ce1SLorenzo Bianconi 1696290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_acc_attributes[] = { 1697290a6ce1SLorenzo Bianconi &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 1698290a6ce1SLorenzo Bianconi &iio_dev_attr_in_accel_scale_available.dev_attr.attr, 1699290a6ce1SLorenzo Bianconi NULL, 1700290a6ce1SLorenzo Bianconi }; 1701290a6ce1SLorenzo Bianconi 1702290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_acc_attribute_group = { 1703290a6ce1SLorenzo Bianconi .attrs = st_lsm6dsx_acc_attributes, 1704290a6ce1SLorenzo Bianconi }; 1705290a6ce1SLorenzo Bianconi 1706290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_acc_info = { 1707290a6ce1SLorenzo Bianconi .attrs = &st_lsm6dsx_acc_attribute_group, 1708290a6ce1SLorenzo Bianconi .read_raw = st_lsm6dsx_read_raw, 1709290a6ce1SLorenzo Bianconi .write_raw = st_lsm6dsx_write_raw, 1710b5969abfSSean Nyekjaer .read_event_value = st_lsm6dsx_read_event, 1711b5969abfSSean Nyekjaer .write_event_value = st_lsm6dsx_write_event, 1712b5969abfSSean Nyekjaer .read_event_config = st_lsm6dsx_read_event_config, 1713b5969abfSSean Nyekjaer .write_event_config = st_lsm6dsx_write_event_config, 1714290a6ce1SLorenzo Bianconi .hwfifo_set_watermark = st_lsm6dsx_set_watermark, 171544a76de8SMario Tesi .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, 1716290a6ce1SLorenzo Bianconi }; 1717290a6ce1SLorenzo Bianconi 1718290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_gyro_attributes[] = { 1719290a6ce1SLorenzo Bianconi &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 1720290a6ce1SLorenzo Bianconi &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr, 1721290a6ce1SLorenzo Bianconi NULL, 1722290a6ce1SLorenzo Bianconi }; 1723290a6ce1SLorenzo Bianconi 1724290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_gyro_attribute_group = { 1725290a6ce1SLorenzo Bianconi .attrs = st_lsm6dsx_gyro_attributes, 1726290a6ce1SLorenzo Bianconi }; 1727290a6ce1SLorenzo Bianconi 1728290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_gyro_info = { 1729290a6ce1SLorenzo Bianconi .attrs = &st_lsm6dsx_gyro_attribute_group, 1730290a6ce1SLorenzo Bianconi .read_raw = st_lsm6dsx_read_raw, 1731290a6ce1SLorenzo Bianconi .write_raw = st_lsm6dsx_write_raw, 1732290a6ce1SLorenzo Bianconi .hwfifo_set_watermark = st_lsm6dsx_set_watermark, 173344a76de8SMario Tesi .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, 1734290a6ce1SLorenzo Bianconi }; 1735290a6ce1SLorenzo Bianconi 173603d4c566SAndy Shevchenko static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) 1737dba32904SLorenzo Bianconi { 173803d4c566SAndy Shevchenko struct device *dev = hw->dev; 1739dba32904SLorenzo Bianconi 174003d4c566SAndy Shevchenko if (!dev_fwnode(dev)) 1741dba32904SLorenzo Bianconi return -EINVAL; 1742dba32904SLorenzo Bianconi 174303d4c566SAndy Shevchenko return device_property_read_u32(dev, "st,drdy-int-pin", drdy_pin); 1744dba32904SLorenzo Bianconi } 1745dba32904SLorenzo Bianconi 17467e906103SLorenzo Bianconi static int 17477e906103SLorenzo Bianconi st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, 17487e906103SLorenzo Bianconi const struct st_lsm6dsx_reg **drdy_reg) 1749dba32904SLorenzo Bianconi { 1750dba32904SLorenzo Bianconi int err = 0, drdy_pin; 1751dba32904SLorenzo Bianconi 175203d4c566SAndy Shevchenko if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) { 1753dba32904SLorenzo Bianconi struct st_sensors_platform_data *pdata; 1754dba32904SLorenzo Bianconi struct device *dev = hw->dev; 1755dba32904SLorenzo Bianconi 1756dba32904SLorenzo Bianconi pdata = (struct st_sensors_platform_data *)dev->platform_data; 1757dba32904SLorenzo Bianconi drdy_pin = pdata ? pdata->drdy_int_pin : 1; 1758dba32904SLorenzo Bianconi } 1759dba32904SLorenzo Bianconi 1760dba32904SLorenzo Bianconi switch (drdy_pin) { 1761dba32904SLorenzo Bianconi case 1: 17627e906103SLorenzo Bianconi hw->irq_routing = &hw->settings->irq_config.irq1_func; 17637e906103SLorenzo Bianconi *drdy_reg = &hw->settings->irq_config.irq1; 1764dba32904SLorenzo Bianconi break; 1765dba32904SLorenzo Bianconi case 2: 17667e906103SLorenzo Bianconi hw->irq_routing = &hw->settings->irq_config.irq2_func; 17677e906103SLorenzo Bianconi *drdy_reg = &hw->settings->irq_config.irq2; 1768dba32904SLorenzo Bianconi break; 1769dba32904SLorenzo Bianconi default: 1770dba32904SLorenzo Bianconi dev_err(hw->dev, "unsupported data ready pin\n"); 1771dba32904SLorenzo Bianconi err = -EINVAL; 1772dba32904SLorenzo Bianconi break; 1773dba32904SLorenzo Bianconi } 1774dba32904SLorenzo Bianconi 1775dba32904SLorenzo Bianconi return err; 1776dba32904SLorenzo Bianconi } 1777dba32904SLorenzo Bianconi 1778c91c1c84SLorenzo Bianconi static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw) 1779c91c1c84SLorenzo Bianconi { 1780c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 1781c91c1c84SLorenzo Bianconi struct st_sensors_platform_data *pdata; 178203d4c566SAndy Shevchenko struct device *dev = hw->dev; 1783c91c1c84SLorenzo Bianconi unsigned int data; 1784c91c1c84SLorenzo Bianconi int err = 0; 1785c91c1c84SLorenzo Bianconi 1786c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 1787c91c1c84SLorenzo Bianconi 178803d4c566SAndy Shevchenko pdata = (struct st_sensors_platform_data *)dev->platform_data; 178903d4c566SAndy Shevchenko if ((dev_fwnode(dev) && device_property_read_bool(dev, "st,pullups")) || 1790c91c1c84SLorenzo Bianconi (pdata && pdata->pullups)) { 17913a431957SLorenzo Bianconi if (hub_settings->pullup_en.sec_page) { 1792c91c1c84SLorenzo Bianconi err = st_lsm6dsx_set_page(hw, true); 1793c91c1c84SLorenzo Bianconi if (err < 0) 1794c91c1c84SLorenzo Bianconi return err; 17953a431957SLorenzo Bianconi } 1796c91c1c84SLorenzo Bianconi 1797c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask); 1798c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 1799c91c1c84SLorenzo Bianconi hub_settings->pullup_en.addr, 1800c91c1c84SLorenzo Bianconi hub_settings->pullup_en.mask, data); 1801c91c1c84SLorenzo Bianconi 18023a431957SLorenzo Bianconi if (hub_settings->pullup_en.sec_page) 1803c91c1c84SLorenzo Bianconi st_lsm6dsx_set_page(hw, false); 1804c91c1c84SLorenzo Bianconi 1805c91c1c84SLorenzo Bianconi if (err < 0) 1806c91c1c84SLorenzo Bianconi return err; 1807c91c1c84SLorenzo Bianconi } 1808c91c1c84SLorenzo Bianconi 1809c91c1c84SLorenzo Bianconi if (hub_settings->aux_sens.addr) { 1810c91c1c84SLorenzo Bianconi /* configure aux sensors */ 1811c91c1c84SLorenzo Bianconi err = st_lsm6dsx_set_page(hw, true); 1812c91c1c84SLorenzo Bianconi if (err < 0) 1813c91c1c84SLorenzo Bianconi return err; 1814c91c1c84SLorenzo Bianconi 1815c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask); 1816c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 1817c91c1c84SLorenzo Bianconi hub_settings->aux_sens.addr, 1818c91c1c84SLorenzo Bianconi hub_settings->aux_sens.mask, data); 1819c91c1c84SLorenzo Bianconi 1820c91c1c84SLorenzo Bianconi st_lsm6dsx_set_page(hw, false); 1821e485e2a2SLorenzo Bianconi 1822e485e2a2SLorenzo Bianconi if (err < 0) 1823e485e2a2SLorenzo Bianconi return err; 1824e485e2a2SLorenzo Bianconi } 1825e485e2a2SLorenzo Bianconi 1826e485e2a2SLorenzo Bianconi if (hub_settings->emb_func.addr) { 1827e485e2a2SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->emb_func.mask); 1828e485e2a2SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 1829e485e2a2SLorenzo Bianconi hub_settings->emb_func.addr, 1830e485e2a2SLorenzo Bianconi hub_settings->emb_func.mask, data); 1831c91c1c84SLorenzo Bianconi } 1832c91c1c84SLorenzo Bianconi 1833c91c1c84SLorenzo Bianconi return err; 1834c91c1c84SLorenzo Bianconi } 1835c91c1c84SLorenzo Bianconi 183621345107SLorenzo Bianconi static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw) 183721345107SLorenzo Bianconi { 183821345107SLorenzo Bianconi const struct st_lsm6dsx_hw_ts_settings *ts_settings; 183921345107SLorenzo Bianconi int err, val; 184021345107SLorenzo Bianconi 184121345107SLorenzo Bianconi ts_settings = &hw->settings->ts_settings; 184221345107SLorenzo Bianconi /* enable hw timestamp generation if necessary */ 184321345107SLorenzo Bianconi if (ts_settings->timer_en.addr) { 184421345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask); 184521345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 184621345107SLorenzo Bianconi ts_settings->timer_en.addr, 184721345107SLorenzo Bianconi ts_settings->timer_en.mask, val); 184821345107SLorenzo Bianconi if (err < 0) 184921345107SLorenzo Bianconi return err; 185021345107SLorenzo Bianconi } 185121345107SLorenzo Bianconi 185221345107SLorenzo Bianconi /* enable high resolution for hw ts timer if necessary */ 185321345107SLorenzo Bianconi if (ts_settings->hr_timer.addr) { 185421345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask); 185521345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 185621345107SLorenzo Bianconi ts_settings->hr_timer.addr, 185721345107SLorenzo Bianconi ts_settings->hr_timer.mask, val); 185821345107SLorenzo Bianconi if (err < 0) 185921345107SLorenzo Bianconi return err; 186021345107SLorenzo Bianconi } 186121345107SLorenzo Bianconi 186221345107SLorenzo Bianconi /* enable ts queueing in FIFO if necessary */ 186321345107SLorenzo Bianconi if (ts_settings->fifo_en.addr) { 186421345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask); 186521345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 186621345107SLorenzo Bianconi ts_settings->fifo_en.addr, 186721345107SLorenzo Bianconi ts_settings->fifo_en.mask, val); 186821345107SLorenzo Bianconi if (err < 0) 186921345107SLorenzo Bianconi return err; 187021345107SLorenzo Bianconi } 1871cb3b6b8eSMario Tesi 1872cb3b6b8eSMario Tesi /* calibrate timestamp sensitivity */ 1873cb3b6b8eSMario Tesi hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY; 1874cb3b6b8eSMario Tesi if (ts_settings->freq_fine) { 1875cb3b6b8eSMario Tesi err = regmap_read(hw->regmap, ts_settings->freq_fine, &val); 1876cb3b6b8eSMario Tesi if (err < 0) 1877cb3b6b8eSMario Tesi return err; 1878cb3b6b8eSMario Tesi 1879cb3b6b8eSMario Tesi /* 1880cb3b6b8eSMario Tesi * linearize the AN5192 formula: 1881cb3b6b8eSMario Tesi * 1 / (1 + x) ~= 1 - x (Taylor’s Series) 1882cb3b6b8eSMario Tesi * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val)) 1883cb3b6b8eSMario Tesi * ttrim[ns] ~= 25000 - 37.5 * val 1884cb3b6b8eSMario Tesi * ttrim[ns] ~= 25000 - (37500 * val) / 1000 1885cb3b6b8eSMario Tesi */ 1886cb3b6b8eSMario Tesi hw->ts_gain -= ((s8)val * 37500) / 1000; 1887cb3b6b8eSMario Tesi } 1888cb3b6b8eSMario Tesi 188921345107SLorenzo Bianconi return 0; 189021345107SLorenzo Bianconi } 189121345107SLorenzo Bianconi 18923a63da26SLorenzo Bianconi static int st_lsm6dsx_reset_device(struct st_lsm6dsx_hw *hw) 1893290a6ce1SLorenzo Bianconi { 18947e906103SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 1895290a6ce1SLorenzo Bianconi int err; 1896290a6ce1SLorenzo Bianconi 18973a63da26SLorenzo Bianconi /* 18983a63da26SLorenzo Bianconi * flush hw FIFO before device reset in order to avoid 18993a63da26SLorenzo Bianconi * possible races on interrupt line 1. If the first interrupt 19003a63da26SLorenzo Bianconi * line is asserted during hw reset the device will work in 19013a63da26SLorenzo Bianconi * I3C-only mode (if it is supported) 19023a63da26SLorenzo Bianconi */ 19033a63da26SLorenzo Bianconi err = st_lsm6dsx_flush_fifo(hw); 19043a63da26SLorenzo Bianconi if (err < 0 && err != -ENOTSUPP) 19053a63da26SLorenzo Bianconi return err; 19063a63da26SLorenzo Bianconi 190719435425SLorenzo Bianconi /* device sw reset */ 190866b662a1SLorenzo Bianconi reg = &hw->settings->reset; 190966b662a1SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 191066b662a1SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 1911290a6ce1SLorenzo Bianconi if (err < 0) 1912290a6ce1SLorenzo Bianconi return err; 1913290a6ce1SLorenzo Bianconi 191419435425SLorenzo Bianconi msleep(50); 191519435425SLorenzo Bianconi 191619435425SLorenzo Bianconi /* reload trimming parameter */ 191766b662a1SLorenzo Bianconi reg = &hw->settings->boot; 191866b662a1SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 191966b662a1SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 192019435425SLorenzo Bianconi if (err < 0) 192119435425SLorenzo Bianconi return err; 192219435425SLorenzo Bianconi 192319435425SLorenzo Bianconi msleep(50); 1924290a6ce1SLorenzo Bianconi 19253a63da26SLorenzo Bianconi return 0; 19263a63da26SLorenzo Bianconi } 19273a63da26SLorenzo Bianconi 19283a63da26SLorenzo Bianconi static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) 19293a63da26SLorenzo Bianconi { 19303a63da26SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 19313a63da26SLorenzo Bianconi int err; 19323a63da26SLorenzo Bianconi 19333a63da26SLorenzo Bianconi err = st_lsm6dsx_reset_device(hw); 19343a63da26SLorenzo Bianconi if (err < 0) 19353a63da26SLorenzo Bianconi return err; 19363a63da26SLorenzo Bianconi 1937290a6ce1SLorenzo Bianconi /* enable Block Data Update */ 193866b662a1SLorenzo Bianconi reg = &hw->settings->bdu; 193966b662a1SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 194066b662a1SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 1941290a6ce1SLorenzo Bianconi if (err < 0) 1942290a6ce1SLorenzo Bianconi return err; 1943290a6ce1SLorenzo Bianconi 1944290a6ce1SLorenzo Bianconi /* enable FIFO watermak interrupt */ 19457e906103SLorenzo Bianconi err = st_lsm6dsx_get_drdy_reg(hw, ®); 1946290a6ce1SLorenzo Bianconi if (err < 0) 1947290a6ce1SLorenzo Bianconi return err; 1948290a6ce1SLorenzo Bianconi 19497e906103SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 19507e906103SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 195121345107SLorenzo Bianconi if (err < 0) 195221345107SLorenzo Bianconi return err; 195321345107SLorenzo Bianconi 19549db02d32SLorenzo Bianconi /* enable Latched interrupts for device events */ 19557e906103SLorenzo Bianconi if (hw->settings->irq_config.lir.addr) { 19567e906103SLorenzo Bianconi reg = &hw->settings->irq_config.lir; 19577e906103SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 19587e906103SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 19599db02d32SLorenzo Bianconi if (err < 0) 19609db02d32SLorenzo Bianconi return err; 196122ea5651SLorenzo Bianconi 196222ea5651SLorenzo Bianconi /* enable clear on read for latched interrupts */ 19637e906103SLorenzo Bianconi if (hw->settings->irq_config.clear_on_read.addr) { 19647e906103SLorenzo Bianconi reg = &hw->settings->irq_config.clear_on_read; 196522ea5651SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 19667e906103SLorenzo Bianconi reg->addr, reg->mask, 19677e906103SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 196822ea5651SLorenzo Bianconi if (err < 0) 196922ea5651SLorenzo Bianconi return err; 197022ea5651SLorenzo Bianconi } 19719db02d32SLorenzo Bianconi } 19729db02d32SLorenzo Bianconi 1973960506edSLorenzo Bianconi /* enable drdy-mas if available */ 1974960506edSLorenzo Bianconi if (hw->settings->drdy_mask.addr) { 1975960506edSLorenzo Bianconi reg = &hw->settings->drdy_mask; 1976960506edSLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 1977960506edSLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 1978960506edSLorenzo Bianconi if (err < 0) 1979960506edSLorenzo Bianconi return err; 1980960506edSLorenzo Bianconi } 1981960506edSLorenzo Bianconi 1982c91c1c84SLorenzo Bianconi err = st_lsm6dsx_init_shub(hw); 1983c91c1c84SLorenzo Bianconi if (err < 0) 1984c91c1c84SLorenzo Bianconi return err; 1985c91c1c84SLorenzo Bianconi 198621345107SLorenzo Bianconi return st_lsm6dsx_init_hw_timer(hw); 1987290a6ce1SLorenzo Bianconi } 1988290a6ce1SLorenzo Bianconi 1989290a6ce1SLorenzo Bianconi static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, 1990510c0106SLorenzo Bianconi enum st_lsm6dsx_sensor_id id, 1991510c0106SLorenzo Bianconi const char *name) 1992290a6ce1SLorenzo Bianconi { 1993290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 1994290a6ce1SLorenzo Bianconi struct iio_dev *iio_dev; 1995290a6ce1SLorenzo Bianconi 1996290a6ce1SLorenzo Bianconi iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor)); 1997290a6ce1SLorenzo Bianconi if (!iio_dev) 1998290a6ce1SLorenzo Bianconi return NULL; 1999290a6ce1SLorenzo Bianconi 2000290a6ce1SLorenzo Bianconi iio_dev->modes = INDIO_DIRECT_MODE; 2001290a6ce1SLorenzo Bianconi iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks; 2002f48bc49bSLorenzo Bianconi iio_dev->channels = hw->settings->channels[id].chan; 2003f48bc49bSLorenzo Bianconi iio_dev->num_channels = hw->settings->channels[id].len; 2004290a6ce1SLorenzo Bianconi 2005290a6ce1SLorenzo Bianconi sensor = iio_priv(iio_dev); 2006290a6ce1SLorenzo Bianconi sensor->id = id; 2007290a6ce1SLorenzo Bianconi sensor->hw = hw; 2008f8710f03SLorenzo Bianconi sensor->odr = hw->settings->odr_table[id].odr_avl[0].milli_hz; 2009640aca3fSLorenzo Bianconi sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain; 2010290a6ce1SLorenzo Bianconi sensor->watermark = 1; 2011290a6ce1SLorenzo Bianconi 2012290a6ce1SLorenzo Bianconi switch (id) { 2013290a6ce1SLorenzo Bianconi case ST_LSM6DSX_ID_ACC: 2014290a6ce1SLorenzo Bianconi iio_dev->info = &st_lsm6dsx_acc_info; 2015510c0106SLorenzo Bianconi scnprintf(sensor->name, sizeof(sensor->name), "%s_accel", 2016510c0106SLorenzo Bianconi name); 2017290a6ce1SLorenzo Bianconi break; 2018290a6ce1SLorenzo Bianconi case ST_LSM6DSX_ID_GYRO: 2019290a6ce1SLorenzo Bianconi iio_dev->info = &st_lsm6dsx_gyro_info; 2020510c0106SLorenzo Bianconi scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro", 2021510c0106SLorenzo Bianconi name); 2022290a6ce1SLorenzo Bianconi break; 2023290a6ce1SLorenzo Bianconi default: 2024290a6ce1SLorenzo Bianconi return NULL; 2025290a6ce1SLorenzo Bianconi } 2026510c0106SLorenzo Bianconi iio_dev->name = sensor->name; 2027290a6ce1SLorenzo Bianconi 2028290a6ce1SLorenzo Bianconi return iio_dev; 2029290a6ce1SLorenzo Bianconi } 2030290a6ce1SLorenzo Bianconi 2031615bd378SLorenzo Bianconi static bool 2032615bd378SLorenzo Bianconi st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw) 20331aabad1fSSean Nyekjaer { 2034615bd378SLorenzo Bianconi const struct st_lsm6dsx_event_settings *event_settings; 2035615bd378SLorenzo Bianconi int err, data; 2036615bd378SLorenzo Bianconi s64 timestamp; 20371aabad1fSSean Nyekjaer 2038615bd378SLorenzo Bianconi if (!hw->enable_event) 2039615bd378SLorenzo Bianconi return false; 2040615bd378SLorenzo Bianconi 2041615bd378SLorenzo Bianconi event_settings = &hw->settings->event_settings; 2042615bd378SLorenzo Bianconi err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg, 2043615bd378SLorenzo Bianconi &data, sizeof(data)); 2044615bd378SLorenzo Bianconi if (err < 0) 2045615bd378SLorenzo Bianconi return false; 2046615bd378SLorenzo Bianconi 2047615bd378SLorenzo Bianconi timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]); 20481aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_z_mask) && 20491aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_Z))) 20501aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 20511aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 20521aabad1fSSean Nyekjaer 0, 20531aabad1fSSean Nyekjaer IIO_MOD_Z, 20541aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 20551aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 20561aabad1fSSean Nyekjaer timestamp); 20571aabad1fSSean Nyekjaer 20581aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_y_mask) && 20591aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_Y))) 20601aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 20611aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 20621aabad1fSSean Nyekjaer 0, 20631aabad1fSSean Nyekjaer IIO_MOD_Y, 20641aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 20651aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 20661aabad1fSSean Nyekjaer timestamp); 20671aabad1fSSean Nyekjaer 20681aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_x_mask) && 20691aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_X))) 20701aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 20711aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 20721aabad1fSSean Nyekjaer 0, 20731aabad1fSSean Nyekjaer IIO_MOD_X, 20741aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 20751aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 20761aabad1fSSean Nyekjaer timestamp); 2077615bd378SLorenzo Bianconi 2078615bd378SLorenzo Bianconi return data & event_settings->wakeup_src_status_mask; 20791aabad1fSSean Nyekjaer } 20801aabad1fSSean Nyekjaer 20816ee6a368SSean Nyekjaer static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) 20826ee6a368SSean Nyekjaer { 20836ee6a368SSean Nyekjaer struct st_lsm6dsx_hw *hw = private; 20843f9bce7aSLorenzo Bianconi int fifo_len = 0, len; 2085615bd378SLorenzo Bianconi bool event; 20861aabad1fSSean Nyekjaer 2087615bd378SLorenzo Bianconi event = st_lsm6dsx_report_motion_event(hw); 20886ee6a368SSean Nyekjaer 2089a912ee4cSLorenzo Bianconi if (!hw->settings->fifo_ops.read_fifo) 2090a912ee4cSLorenzo Bianconi return event ? IRQ_HANDLED : IRQ_NONE; 2091a912ee4cSLorenzo Bianconi 20923f9bce7aSLorenzo Bianconi /* 20933f9bce7aSLorenzo Bianconi * If we are using edge IRQs, new samples can arrive while 20943f9bce7aSLorenzo Bianconi * processing current interrupt since there are no hw 20953f9bce7aSLorenzo Bianconi * guarantees the irq line stays "low" long enough to properly 20963f9bce7aSLorenzo Bianconi * detect the new interrupt. In this case the new sample will 20973f9bce7aSLorenzo Bianconi * be missed. 20983f9bce7aSLorenzo Bianconi * Polling FIFO status register allow us to read new 20993f9bce7aSLorenzo Bianconi * samples even if the interrupt arrives while processing 21003f9bce7aSLorenzo Bianconi * previous data and the timeslot where the line is "low" is 21013f9bce7aSLorenzo Bianconi * too short to be properly detected. 21023f9bce7aSLorenzo Bianconi */ 21033f9bce7aSLorenzo Bianconi do { 21046ee6a368SSean Nyekjaer mutex_lock(&hw->fifo_lock); 21053f9bce7aSLorenzo Bianconi len = hw->settings->fifo_ops.read_fifo(hw); 21066ee6a368SSean Nyekjaer mutex_unlock(&hw->fifo_lock); 21076ee6a368SSean Nyekjaer 21083f9bce7aSLorenzo Bianconi if (len > 0) 21093f9bce7aSLorenzo Bianconi fifo_len += len; 21103f9bce7aSLorenzo Bianconi } while (len > 0); 21113f9bce7aSLorenzo Bianconi 21123f9bce7aSLorenzo Bianconi return fifo_len || event ? IRQ_HANDLED : IRQ_NONE; 21136ee6a368SSean Nyekjaer } 21146ee6a368SSean Nyekjaer 21156ee6a368SSean Nyekjaer static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) 21166ee6a368SSean Nyekjaer { 211731fe8d4eSLorenzo Bianconi struct st_sensors_platform_data *pdata; 211831fe8d4eSLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 211903d4c566SAndy Shevchenko struct device *dev = hw->dev; 21206ee6a368SSean Nyekjaer unsigned long irq_type; 21216ee6a368SSean Nyekjaer bool irq_active_low; 21226ee6a368SSean Nyekjaer int err; 21236ee6a368SSean Nyekjaer 21246ee6a368SSean Nyekjaer irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq)); 21256ee6a368SSean Nyekjaer 21266ee6a368SSean Nyekjaer switch (irq_type) { 21276ee6a368SSean Nyekjaer case IRQF_TRIGGER_HIGH: 21286ee6a368SSean Nyekjaer case IRQF_TRIGGER_RISING: 21296ee6a368SSean Nyekjaer irq_active_low = false; 21306ee6a368SSean Nyekjaer break; 21316ee6a368SSean Nyekjaer case IRQF_TRIGGER_LOW: 21326ee6a368SSean Nyekjaer case IRQF_TRIGGER_FALLING: 21336ee6a368SSean Nyekjaer irq_active_low = true; 21346ee6a368SSean Nyekjaer break; 21356ee6a368SSean Nyekjaer default: 21366ee6a368SSean Nyekjaer dev_info(hw->dev, "mode %lx unsupported\n", irq_type); 21376ee6a368SSean Nyekjaer return -EINVAL; 21386ee6a368SSean Nyekjaer } 21396ee6a368SSean Nyekjaer 214031fe8d4eSLorenzo Bianconi reg = &hw->settings->irq_config.hla; 214131fe8d4eSLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 214231fe8d4eSLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(irq_active_low, 214331fe8d4eSLorenzo Bianconi reg->mask)); 21446ee6a368SSean Nyekjaer if (err < 0) 21456ee6a368SSean Nyekjaer return err; 21466ee6a368SSean Nyekjaer 214703d4c566SAndy Shevchenko pdata = (struct st_sensors_platform_data *)dev->platform_data; 214803d4c566SAndy Shevchenko if ((dev_fwnode(dev) && device_property_read_bool(dev, "drive-open-drain")) || 21496ee6a368SSean Nyekjaer (pdata && pdata->open_drain)) { 215031fe8d4eSLorenzo Bianconi reg = &hw->settings->irq_config.od; 215131fe8d4eSLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 215231fe8d4eSLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 21536ee6a368SSean Nyekjaer if (err < 0) 21546ee6a368SSean Nyekjaer return err; 21556ee6a368SSean Nyekjaer 21566ee6a368SSean Nyekjaer irq_type |= IRQF_SHARED; 21576ee6a368SSean Nyekjaer } 21586ee6a368SSean Nyekjaer 21596ee6a368SSean Nyekjaer err = devm_request_threaded_irq(hw->dev, hw->irq, 2160a3aa17d4SSean Nyekjaer NULL, 21616ee6a368SSean Nyekjaer st_lsm6dsx_handler_thread, 21626ee6a368SSean Nyekjaer irq_type | IRQF_ONESHOT, 21636ee6a368SSean Nyekjaer "lsm6dsx", hw); 21646ee6a368SSean Nyekjaer if (err) { 21656ee6a368SSean Nyekjaer dev_err(hw->dev, "failed to request trigger irq %d\n", 21666ee6a368SSean Nyekjaer hw->irq); 21676ee6a368SSean Nyekjaer return err; 21686ee6a368SSean Nyekjaer } 21696ee6a368SSean Nyekjaer 21706ee6a368SSean Nyekjaer return 0; 21716ee6a368SSean Nyekjaer } 21726ee6a368SSean Nyekjaer 2173f346b16fSLorenzo Bianconi static int st_lsm6dsx_init_regulators(struct device *dev) 2174f346b16fSLorenzo Bianconi { 2175f346b16fSLorenzo Bianconi struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); 2176f346b16fSLorenzo Bianconi int err; 2177f346b16fSLorenzo Bianconi 2178f346b16fSLorenzo Bianconi /* vdd-vddio power regulators */ 2179f346b16fSLorenzo Bianconi hw->regulators[0].supply = "vdd"; 2180f346b16fSLorenzo Bianconi hw->regulators[1].supply = "vddio"; 2181f346b16fSLorenzo Bianconi err = devm_regulator_bulk_get(dev, ARRAY_SIZE(hw->regulators), 2182f346b16fSLorenzo Bianconi hw->regulators); 2183f346b16fSLorenzo Bianconi if (err) 2184f346b16fSLorenzo Bianconi return dev_err_probe(dev, err, "failed to get regulators\n"); 2185f346b16fSLorenzo Bianconi 2186f346b16fSLorenzo Bianconi err = regulator_bulk_enable(ARRAY_SIZE(hw->regulators), 2187f346b16fSLorenzo Bianconi hw->regulators); 2188f346b16fSLorenzo Bianconi if (err) { 2189f346b16fSLorenzo Bianconi dev_err(dev, "failed to enable regulators: %d\n", err); 2190f346b16fSLorenzo Bianconi return err; 2191f346b16fSLorenzo Bianconi } 2192f346b16fSLorenzo Bianconi 2193f346b16fSLorenzo Bianconi msleep(50); 2194f346b16fSLorenzo Bianconi 2195f346b16fSLorenzo Bianconi return 0; 2196f346b16fSLorenzo Bianconi } 2197f346b16fSLorenzo Bianconi 2198f346b16fSLorenzo Bianconi static void st_lsm6dsx_chip_uninit(void *data) 2199f346b16fSLorenzo Bianconi { 2200f346b16fSLorenzo Bianconi struct st_lsm6dsx_hw *hw = data; 2201f346b16fSLorenzo Bianconi 2202f346b16fSLorenzo Bianconi regulator_bulk_disable(ARRAY_SIZE(hw->regulators), hw->regulators); 2203f346b16fSLorenzo Bianconi } 2204f346b16fSLorenzo Bianconi 220581956a93SLorenzo Bianconi int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, 220651a8b707SLorenzo Bianconi struct regmap *regmap) 2207290a6ce1SLorenzo Bianconi { 2208b7a73b33SLorenzo Bianconi struct st_sensors_platform_data *pdata = dev->platform_data; 2209c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 2210290a6ce1SLorenzo Bianconi struct st_lsm6dsx_hw *hw; 221181956a93SLorenzo Bianconi const char *name = NULL; 2212290a6ce1SLorenzo Bianconi int i, err; 2213290a6ce1SLorenzo Bianconi 2214290a6ce1SLorenzo Bianconi hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); 2215290a6ce1SLorenzo Bianconi if (!hw) 2216290a6ce1SLorenzo Bianconi return -ENOMEM; 2217290a6ce1SLorenzo Bianconi 2218290a6ce1SLorenzo Bianconi dev_set_drvdata(dev, (void *)hw); 2219290a6ce1SLorenzo Bianconi 2220290a6ce1SLorenzo Bianconi mutex_init(&hw->fifo_lock); 2221335eaedcSLorenzo Bianconi mutex_init(&hw->conf_lock); 2222739aff87SLorenzo Bianconi mutex_init(&hw->page_lock); 2223290a6ce1SLorenzo Bianconi 2224f346b16fSLorenzo Bianconi err = st_lsm6dsx_init_regulators(dev); 2225f346b16fSLorenzo Bianconi if (err) 2226f346b16fSLorenzo Bianconi return err; 2227f346b16fSLorenzo Bianconi 2228f346b16fSLorenzo Bianconi err = devm_add_action_or_reset(dev, st_lsm6dsx_chip_uninit, hw); 2229f346b16fSLorenzo Bianconi if (err) 2230f346b16fSLorenzo Bianconi return err; 2231f346b16fSLorenzo Bianconi 223291a6b841SLorenzo Bianconi hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL); 223391a6b841SLorenzo Bianconi if (!hw->buff) 223491a6b841SLorenzo Bianconi return -ENOMEM; 223591a6b841SLorenzo Bianconi 2236290a6ce1SLorenzo Bianconi hw->dev = dev; 2237290a6ce1SLorenzo Bianconi hw->irq = irq; 223851a8b707SLorenzo Bianconi hw->regmap = regmap; 2239290a6ce1SLorenzo Bianconi 224081956a93SLorenzo Bianconi err = st_lsm6dsx_check_whoami(hw, hw_id, &name); 2241290a6ce1SLorenzo Bianconi if (err < 0) 2242290a6ce1SLorenzo Bianconi return err; 2243290a6ce1SLorenzo Bianconi 22446ffb55e5SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) { 2245510c0106SLorenzo Bianconi hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name); 2246290a6ce1SLorenzo Bianconi if (!hw->iio_devs[i]) 2247290a6ce1SLorenzo Bianconi return -ENOMEM; 2248290a6ce1SLorenzo Bianconi } 2249290a6ce1SLorenzo Bianconi 2250290a6ce1SLorenzo Bianconi err = st_lsm6dsx_init_device(hw); 2251290a6ce1SLorenzo Bianconi if (err < 0) 2252290a6ce1SLorenzo Bianconi return err; 2253290a6ce1SLorenzo Bianconi 2254c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 225535619155SLorenzo Bianconi if (hub_settings->master_en.addr && 225635619155SLorenzo Bianconi (!dev_fwnode(dev) || 225735619155SLorenzo Bianconi !device_property_read_bool(dev, "st,disable-sensor-hub"))) { 2258c91c1c84SLorenzo Bianconi err = st_lsm6dsx_shub_probe(hw, name); 2259c91c1c84SLorenzo Bianconi if (err < 0) 2260c91c1c84SLorenzo Bianconi return err; 2261c91c1c84SLorenzo Bianconi } 2262c91c1c84SLorenzo Bianconi 2263290a6ce1SLorenzo Bianconi if (hw->irq > 0) { 22646ee6a368SSean Nyekjaer err = st_lsm6dsx_irq_setup(hw); 22656ee6a368SSean Nyekjaer if (err < 0) 22666ee6a368SSean Nyekjaer return err; 22676ee6a368SSean Nyekjaer 2268290a6ce1SLorenzo Bianconi err = st_lsm6dsx_fifo_setup(hw); 2269290a6ce1SLorenzo Bianconi if (err < 0) 2270290a6ce1SLorenzo Bianconi return err; 2271290a6ce1SLorenzo Bianconi } 2272290a6ce1SLorenzo Bianconi 2273b892770aSAndy Shevchenko err = iio_read_mount_matrix(hw->dev, &hw->orientation); 227404e6fedbSMartin Kepplinger if (err) 227504e6fedbSMartin Kepplinger return err; 227604e6fedbSMartin Kepplinger 2277290a6ce1SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 22786ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 22796ffb55e5SLorenzo Bianconi continue; 22806ffb55e5SLorenzo Bianconi 2281290a6ce1SLorenzo Bianconi err = devm_iio_device_register(hw->dev, hw->iio_devs[i]); 2282290a6ce1SLorenzo Bianconi if (err) 2283290a6ce1SLorenzo Bianconi return err; 2284290a6ce1SLorenzo Bianconi } 2285290a6ce1SLorenzo Bianconi 228603d4c566SAndy Shevchenko if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) || 2287b7a73b33SLorenzo Bianconi (pdata && pdata->wakeup_source)) 22884c997dfaSSean Nyekjaer device_init_wakeup(dev, true); 22894c997dfaSSean Nyekjaer 2290290a6ce1SLorenzo Bianconi return 0; 2291290a6ce1SLorenzo Bianconi } 2292290a6ce1SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_probe); 2293290a6ce1SLorenzo Bianconi 22943cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_suspend(struct device *dev) 2295d3f77058SLorenzo Bianconi { 2296d3f77058SLorenzo Bianconi struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); 2297d3f77058SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 2298d3f77058SLorenzo Bianconi int i, err = 0; 2299d3f77058SLorenzo Bianconi 2300d3f77058SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 23016ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 23026ffb55e5SLorenzo Bianconi continue; 23036ffb55e5SLorenzo Bianconi 2304d3f77058SLorenzo Bianconi sensor = iio_priv(hw->iio_devs[i]); 2305d3f77058SLorenzo Bianconi if (!(hw->enable_mask & BIT(sensor->id))) 2306d3f77058SLorenzo Bianconi continue; 2307d3f77058SLorenzo Bianconi 23084c997dfaSSean Nyekjaer if (device_may_wakeup(dev) && 23094c997dfaSSean Nyekjaer sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) { 23104c997dfaSSean Nyekjaer /* Enable wake from IRQ */ 23114c997dfaSSean Nyekjaer enable_irq_wake(hw->irq); 23124c997dfaSSean Nyekjaer continue; 23134c997dfaSSean Nyekjaer } 23144c997dfaSSean Nyekjaer 2315bce0d57dSLorenzo Bianconi if (sensor->id == ST_LSM6DSX_ID_EXT0 || 2316bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT1 || 2317bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT2) 2318bce0d57dSLorenzo Bianconi err = st_lsm6dsx_shub_set_enable(sensor, false); 2319bce0d57dSLorenzo Bianconi else 2320bce0d57dSLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, false); 2321d3f77058SLorenzo Bianconi if (err < 0) 2322d3f77058SLorenzo Bianconi return err; 2323bce0d57dSLorenzo Bianconi 2324bce0d57dSLorenzo Bianconi hw->suspend_mask |= BIT(sensor->id); 2325d3f77058SLorenzo Bianconi } 2326d3f77058SLorenzo Bianconi 2327c2686eb2SLorenzo Bianconi if (hw->fifo_mask) 2328d3f77058SLorenzo Bianconi err = st_lsm6dsx_flush_fifo(hw); 2329d3f77058SLorenzo Bianconi 2330d3f77058SLorenzo Bianconi return err; 2331d3f77058SLorenzo Bianconi } 2332d3f77058SLorenzo Bianconi 23333cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_resume(struct device *dev) 2334d3f77058SLorenzo Bianconi { 2335d3f77058SLorenzo Bianconi struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); 2336d3f77058SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 2337d3f77058SLorenzo Bianconi int i, err = 0; 2338d3f77058SLorenzo Bianconi 2339d3f77058SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 23406ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 23416ffb55e5SLorenzo Bianconi continue; 23426ffb55e5SLorenzo Bianconi 2343d3f77058SLorenzo Bianconi sensor = iio_priv(hw->iio_devs[i]); 23444c997dfaSSean Nyekjaer if (device_may_wakeup(dev) && 23454c997dfaSSean Nyekjaer sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) 23464c997dfaSSean Nyekjaer disable_irq_wake(hw->irq); 23474c997dfaSSean Nyekjaer 2348bce0d57dSLorenzo Bianconi if (!(hw->suspend_mask & BIT(sensor->id))) 2349d3f77058SLorenzo Bianconi continue; 2350d3f77058SLorenzo Bianconi 2351bce0d57dSLorenzo Bianconi if (sensor->id == ST_LSM6DSX_ID_EXT0 || 2352bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT1 || 2353bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT2) 2354bce0d57dSLorenzo Bianconi err = st_lsm6dsx_shub_set_enable(sensor, true); 2355bce0d57dSLorenzo Bianconi else 2356bce0d57dSLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, true); 2357d3f77058SLorenzo Bianconi if (err < 0) 2358d3f77058SLorenzo Bianconi return err; 2359bce0d57dSLorenzo Bianconi 2360bce0d57dSLorenzo Bianconi hw->suspend_mask &= ~BIT(sensor->id); 2361d3f77058SLorenzo Bianconi } 2362d3f77058SLorenzo Bianconi 2363c2686eb2SLorenzo Bianconi if (hw->fifo_mask) 2364a1bab939SLorenzo Bianconi err = st_lsm6dsx_resume_fifo(hw); 2365d3f77058SLorenzo Bianconi 2366d3f77058SLorenzo Bianconi return err; 2367d3f77058SLorenzo Bianconi } 2368d3f77058SLorenzo Bianconi 2369d3f77058SLorenzo Bianconi const struct dev_pm_ops st_lsm6dsx_pm_ops = { 2370d3f77058SLorenzo Bianconi SET_SYSTEM_SLEEP_PM_OPS(st_lsm6dsx_suspend, st_lsm6dsx_resume) 2371d3f77058SLorenzo Bianconi }; 2372d3f77058SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_pm_ops); 2373d3f77058SLorenzo Bianconi 2374290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>"); 2375290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 2376290a6ce1SLorenzo Bianconi MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver"); 2377290a6ce1SLorenzo Bianconi MODULE_LICENSE("GPL v2"); 2378