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 * 29186b9e38SLorenzo Bianconi * - LSM6DSO/LSM6DSOX/ASM330LHH/ASM330LHHX/LSM6DSR/ISM330DHCX/LSM6DST/LSM6DSOP/ 30*f35e1ee9SLorenzo Bianconi * LSM6DSTX/LSM6DSO16IS: 31f7d5c18aSSean Nyekjaer * - Accelerometer/Gyroscope supported ODR [Hz]: 12.5, 26, 52, 104, 208, 416, 328f9a5249SLorenzo Bianconi * 833 33801a6e0aSLorenzo Bianconi * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 34801a6e0aSLorenzo Bianconi * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 35801a6e0aSLorenzo Bianconi * - FIFO size: 3KB 36801a6e0aSLorenzo Bianconi * 37d94fbd92SLorenzo Bianconi * - LSM6DSV/LSM6DSV16X: 38d94fbd92SLorenzo Bianconi * - Accelerometer/Gyroscope supported ODR [Hz]: 7.5, 15, 30, 60, 120, 240, 39d94fbd92SLorenzo Bianconi * 480, 960 40d94fbd92SLorenzo Bianconi * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 41d94fbd92SLorenzo Bianconi * - Gyroscope supported full-scale [dps]: +-125/+-250/+-500/+-1000/+-2000 42d94fbd92SLorenzo Bianconi * - FIFO size: 3KB 43d94fbd92SLorenzo Bianconi * 44fa060a3dSLorenzo Bianconi * - LSM9DS1/LSM6DS0: 4552f4b1f1SMartin Kepplinger * - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952 4652f4b1f1SMartin Kepplinger * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 4752f4b1f1SMartin Kepplinger * - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952 4852f4b1f1SMartin Kepplinger * - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000 4952f4b1f1SMartin Kepplinger * - FIFO size: 32 5052f4b1f1SMartin Kepplinger * 51290a6ce1SLorenzo Bianconi * Copyright 2016 STMicroelectronics Inc. 52290a6ce1SLorenzo Bianconi * 53290a6ce1SLorenzo Bianconi * Lorenzo Bianconi <lorenzo.bianconi@st.com> 54290a6ce1SLorenzo Bianconi * Denis Ciocca <denis.ciocca@st.com> 55290a6ce1SLorenzo Bianconi */ 56290a6ce1SLorenzo Bianconi 57290a6ce1SLorenzo Bianconi #include <linux/kernel.h> 58290a6ce1SLorenzo Bianconi #include <linux/module.h> 59290a6ce1SLorenzo Bianconi #include <linux/delay.h> 601aabad1fSSean Nyekjaer #include <linux/iio/events.h> 61290a6ce1SLorenzo Bianconi #include <linux/iio/iio.h> 62290a6ce1SLorenzo Bianconi #include <linux/iio/sysfs.h> 632cfb2180SLorenzo Bianconi #include <linux/iio/triggered_buffer.h> 642cfb2180SLorenzo Bianconi #include <linux/iio/trigger_consumer.h> 656ee6a368SSean Nyekjaer #include <linux/interrupt.h> 666ee6a368SSean Nyekjaer #include <linux/irq.h> 679e5b4cd2SPaul Cercueil #include <linux/minmax.h> 68d3f77058SLorenzo Bianconi #include <linux/pm.h> 6903d4c566SAndy Shevchenko #include <linux/property.h> 7051a8b707SLorenzo Bianconi #include <linux/regmap.h> 7151a8b707SLorenzo Bianconi #include <linux/bitfield.h> 72290a6ce1SLorenzo Bianconi 73dba32904SLorenzo Bianconi #include <linux/platform_data/st_sensors_pdata.h> 74dba32904SLorenzo Bianconi 75290a6ce1SLorenzo Bianconi #include "st_lsm6dsx.h" 76290a6ce1SLorenzo Bianconi 77290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f 78290a6ce1SLorenzo Bianconi 79cb3b6b8eSMario Tesi #define ST_LSM6DSX_TS_SENSITIVITY 25000UL /* 25us */ 80cb3b6b8eSMario Tesi 81f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { 82b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0), 83b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1), 84b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2), 85f48bc49bSLorenzo Bianconi IIO_CHAN_SOFT_TIMESTAMP(3), 86f48bc49bSLorenzo Bianconi }; 87f48bc49bSLorenzo Bianconi 88f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = { 89f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0), 90f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1), 91f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2), 92f48bc49bSLorenzo Bianconi IIO_CHAN_SOFT_TIMESTAMP(3), 93f48bc49bSLorenzo Bianconi }; 94f48bc49bSLorenzo Bianconi 9552f4b1f1SMartin Kepplinger static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = { 9652f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0), 9752f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1), 9852f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2), 9952f4b1f1SMartin Kepplinger IIO_CHAN_SOFT_TIMESTAMP(3), 10052f4b1f1SMartin Kepplinger }; 10152f4b1f1SMartin Kepplinger 102290a6ce1SLorenzo Bianconi static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { 103290a6ce1SLorenzo Bianconi { 10466b662a1SLorenzo Bianconi .reset = { 10566b662a1SLorenzo Bianconi .addr = 0x22, 10666b662a1SLorenzo Bianconi .mask = BIT(0), 10766b662a1SLorenzo Bianconi }, 10866b662a1SLorenzo Bianconi .boot = { 10966b662a1SLorenzo Bianconi .addr = 0x22, 11066b662a1SLorenzo Bianconi .mask = BIT(7), 11166b662a1SLorenzo Bianconi }, 11266b662a1SLorenzo Bianconi .bdu = { 11366b662a1SLorenzo Bianconi .addr = 0x22, 11466b662a1SLorenzo Bianconi .mask = BIT(6), 11566b662a1SLorenzo Bianconi }, 11652f4b1f1SMartin Kepplinger .id = { 11752f4b1f1SMartin Kepplinger { 11852f4b1f1SMartin Kepplinger .hw_id = ST_LSM9DS1_ID, 11952f4b1f1SMartin Kepplinger .name = ST_LSM9DS1_DEV_NAME, 12098c3544aSLorenzo Bianconi .wai = 0x68, 121fa060a3dSLorenzo Bianconi }, { 122fa060a3dSLorenzo Bianconi .hw_id = ST_LSM6DS0_ID, 123fa060a3dSLorenzo Bianconi .name = ST_LSM6DS0_DEV_NAME, 12498c3544aSLorenzo Bianconi .wai = 0x68, 12552f4b1f1SMartin Kepplinger }, 12652f4b1f1SMartin Kepplinger }, 12752f4b1f1SMartin Kepplinger .channels = { 12852f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 12952f4b1f1SMartin Kepplinger .chan = st_lsm6dsx_acc_channels, 13052f4b1f1SMartin Kepplinger .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 13152f4b1f1SMartin Kepplinger }, 13252f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 13352f4b1f1SMartin Kepplinger .chan = st_lsm6ds0_gyro_channels, 13452f4b1f1SMartin Kepplinger .len = ARRAY_SIZE(st_lsm6ds0_gyro_channels), 13552f4b1f1SMartin Kepplinger }, 13652f4b1f1SMartin Kepplinger }, 13752f4b1f1SMartin Kepplinger .odr_table = { 13852f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 13952f4b1f1SMartin Kepplinger .reg = { 14052f4b1f1SMartin Kepplinger .addr = 0x20, 14152f4b1f1SMartin Kepplinger .mask = GENMASK(7, 5), 14252f4b1f1SMartin Kepplinger }, 143f8710f03SLorenzo Bianconi .odr_avl[0] = { 10000, 0x01 }, 144f8710f03SLorenzo Bianconi .odr_avl[1] = { 50000, 0x02 }, 145f8710f03SLorenzo Bianconi .odr_avl[2] = { 119000, 0x03 }, 146f8710f03SLorenzo Bianconi .odr_avl[3] = { 238000, 0x04 }, 147f8710f03SLorenzo Bianconi .odr_avl[4] = { 476000, 0x05 }, 148f8710f03SLorenzo Bianconi .odr_avl[5] = { 952000, 0x06 }, 14959af4e20SLorenzo Bianconi .odr_len = 6, 15052f4b1f1SMartin Kepplinger }, 15152f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 15252f4b1f1SMartin Kepplinger .reg = { 15352f4b1f1SMartin Kepplinger .addr = 0x10, 15452f4b1f1SMartin Kepplinger .mask = GENMASK(7, 5), 15552f4b1f1SMartin Kepplinger }, 156f8710f03SLorenzo Bianconi .odr_avl[0] = { 14900, 0x01 }, 157f8710f03SLorenzo Bianconi .odr_avl[1] = { 59500, 0x02 }, 158f8710f03SLorenzo Bianconi .odr_avl[2] = { 119000, 0x03 }, 159f8710f03SLorenzo Bianconi .odr_avl[3] = { 238000, 0x04 }, 160f8710f03SLorenzo Bianconi .odr_avl[4] = { 476000, 0x05 }, 161f8710f03SLorenzo Bianconi .odr_avl[5] = { 952000, 0x06 }, 16259af4e20SLorenzo Bianconi .odr_len = 6, 16352f4b1f1SMartin Kepplinger }, 16452f4b1f1SMartin Kepplinger }, 16552f4b1f1SMartin Kepplinger .fs_table = { 16652f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 16752f4b1f1SMartin Kepplinger .reg = { 16852f4b1f1SMartin Kepplinger .addr = 0x20, 16952f4b1f1SMartin Kepplinger .mask = GENMASK(4, 3), 17052f4b1f1SMartin Kepplinger }, 17144a76de8SMario Tesi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 17244a76de8SMario Tesi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 17344a76de8SMario Tesi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 17444a76de8SMario Tesi .fs_avl[3] = { IIO_G_TO_M_S_2(732000), 0x1 }, 17585ae3aeeSLorenzo Bianconi .fs_len = 4, 17652f4b1f1SMartin Kepplinger }, 17752f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 17852f4b1f1SMartin Kepplinger .reg = { 17952f4b1f1SMartin Kepplinger .addr = 0x10, 18052f4b1f1SMartin Kepplinger .mask = GENMASK(4, 3), 18152f4b1f1SMartin Kepplinger }, 1821b375101SLorenzo Bianconi 18344a76de8SMario Tesi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 18444a76de8SMario Tesi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 18544a76de8SMario Tesi .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 18685ae3aeeSLorenzo Bianconi .fs_len = 3, 18752f4b1f1SMartin Kepplinger }, 18852f4b1f1SMartin Kepplinger }, 1897e906103SLorenzo Bianconi .irq_config = { 1907e906103SLorenzo Bianconi .irq1 = { 1917e906103SLorenzo Bianconi .addr = 0x0c, 1927e906103SLorenzo Bianconi .mask = BIT(3), 1937e906103SLorenzo Bianconi }, 1947e906103SLorenzo Bianconi .irq2 = { 1957e906103SLorenzo Bianconi .addr = 0x0d, 1967e906103SLorenzo Bianconi .mask = BIT(3), 1977e906103SLorenzo Bianconi }, 19831fe8d4eSLorenzo Bianconi .hla = { 19931fe8d4eSLorenzo Bianconi .addr = 0x22, 20031fe8d4eSLorenzo Bianconi .mask = BIT(5), 20131fe8d4eSLorenzo Bianconi }, 20231fe8d4eSLorenzo Bianconi .od = { 20331fe8d4eSLorenzo Bianconi .addr = 0x22, 20431fe8d4eSLorenzo Bianconi .mask = BIT(4), 20531fe8d4eSLorenzo Bianconi }, 2067e906103SLorenzo Bianconi }, 2071b7da2faSLorenzo Bianconi .fifo_ops = { 2081b7da2faSLorenzo Bianconi .max_size = 32, 2091b7da2faSLorenzo Bianconi }, 21052f4b1f1SMartin Kepplinger }, 21152f4b1f1SMartin Kepplinger { 21266b662a1SLorenzo Bianconi .reset = { 21366b662a1SLorenzo Bianconi .addr = 0x12, 21466b662a1SLorenzo Bianconi .mask = BIT(0), 21566b662a1SLorenzo Bianconi }, 21666b662a1SLorenzo Bianconi .boot = { 21766b662a1SLorenzo Bianconi .addr = 0x12, 21866b662a1SLorenzo Bianconi .mask = BIT(7), 21966b662a1SLorenzo Bianconi }, 22066b662a1SLorenzo Bianconi .bdu = { 22166b662a1SLorenzo Bianconi .addr = 0x12, 22266b662a1SLorenzo Bianconi .mask = BIT(6), 22366b662a1SLorenzo Bianconi }, 224d068e4a0SLorenzo Bianconi .id = { 22581956a93SLorenzo Bianconi { 22681956a93SLorenzo Bianconi .hw_id = ST_LSM6DS3_ID, 22781956a93SLorenzo Bianconi .name = ST_LSM6DS3_DEV_NAME, 22898c3544aSLorenzo Bianconi .wai = 0x69, 22981956a93SLorenzo Bianconi }, 230d068e4a0SLorenzo Bianconi }, 231f48bc49bSLorenzo Bianconi .channels = { 232f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 233f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 234f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 235f48bc49bSLorenzo Bianconi }, 236f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 237f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 238f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 239f48bc49bSLorenzo Bianconi }, 240f48bc49bSLorenzo Bianconi }, 24140dd7343SLorenzo Bianconi .odr_table = { 24240dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 24340dd7343SLorenzo Bianconi .reg = { 24440dd7343SLorenzo Bianconi .addr = 0x10, 24540dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 24640dd7343SLorenzo Bianconi }, 247f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 248f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 249f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 250f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 251f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 252f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 25359af4e20SLorenzo Bianconi .odr_len = 6, 25440dd7343SLorenzo Bianconi }, 25540dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 25640dd7343SLorenzo Bianconi .reg = { 25740dd7343SLorenzo Bianconi .addr = 0x11, 25840dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 25940dd7343SLorenzo Bianconi }, 260f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 261f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 262f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 263f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 264f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 265f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 26659af4e20SLorenzo Bianconi .odr_len = 6, 26740dd7343SLorenzo Bianconi }, 26840dd7343SLorenzo Bianconi }, 269640aca3fSLorenzo Bianconi .fs_table = { 270640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 271640aca3fSLorenzo Bianconi .reg = { 272640aca3fSLorenzo Bianconi .addr = 0x10, 273640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 274640aca3fSLorenzo Bianconi }, 27544a76de8SMario Tesi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 27644a76de8SMario Tesi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 27744a76de8SMario Tesi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 27844a76de8SMario Tesi .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, 27985ae3aeeSLorenzo Bianconi .fs_len = 4, 280640aca3fSLorenzo Bianconi }, 281640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 282640aca3fSLorenzo Bianconi .reg = { 283640aca3fSLorenzo Bianconi .addr = 0x11, 284640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 285640aca3fSLorenzo Bianconi }, 28644a76de8SMario Tesi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 28744a76de8SMario Tesi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 28844a76de8SMario Tesi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, 28944a76de8SMario Tesi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 29085ae3aeeSLorenzo Bianconi .fs_len = 4, 291640aca3fSLorenzo Bianconi }, 292640aca3fSLorenzo Bianconi }, 2937e906103SLorenzo Bianconi .irq_config = { 2947e906103SLorenzo Bianconi .irq1 = { 2957e906103SLorenzo Bianconi .addr = 0x0d, 2967e906103SLorenzo Bianconi .mask = BIT(3), 2977e906103SLorenzo Bianconi }, 2987e906103SLorenzo Bianconi .irq2 = { 2997e906103SLorenzo Bianconi .addr = 0x0e, 3007e906103SLorenzo Bianconi .mask = BIT(3), 3017e906103SLorenzo Bianconi }, 3027e906103SLorenzo Bianconi .lir = { 3037e906103SLorenzo Bianconi .addr = 0x58, 3047e906103SLorenzo Bianconi .mask = BIT(0), 3057e906103SLorenzo Bianconi }, 3067e906103SLorenzo Bianconi .irq1_func = { 3077e906103SLorenzo Bianconi .addr = 0x5e, 3087e906103SLorenzo Bianconi .mask = BIT(5), 3097e906103SLorenzo Bianconi }, 3107e906103SLorenzo Bianconi .irq2_func = { 3117e906103SLorenzo Bianconi .addr = 0x5f, 3127e906103SLorenzo Bianconi .mask = BIT(5), 3137e906103SLorenzo Bianconi }, 31431fe8d4eSLorenzo Bianconi .hla = { 31531fe8d4eSLorenzo Bianconi .addr = 0x12, 31631fe8d4eSLorenzo Bianconi .mask = BIT(5), 31731fe8d4eSLorenzo Bianconi }, 31831fe8d4eSLorenzo Bianconi .od = { 31931fe8d4eSLorenzo Bianconi .addr = 0x12, 32031fe8d4eSLorenzo Bianconi .mask = BIT(4), 32131fe8d4eSLorenzo Bianconi }, 3227e906103SLorenzo Bianconi }, 3237ca3ac9eSLorenzo Bianconi .decimator = { 3247ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 3257ca3ac9eSLorenzo Bianconi .addr = 0x08, 3267ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 3277ca3ac9eSLorenzo Bianconi }, 3287ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 3297ca3ac9eSLorenzo Bianconi .addr = 0x08, 3307ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 3317ca3ac9eSLorenzo Bianconi }, 3327ca3ac9eSLorenzo Bianconi }, 33392617c15SLorenzo Bianconi .fifo_ops = { 3343b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 33550ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 33692617c15SLorenzo Bianconi .fifo_th = { 33792617c15SLorenzo Bianconi .addr = 0x06, 33892617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 33992617c15SLorenzo Bianconi }, 34092617c15SLorenzo Bianconi .fifo_diff = { 34192617c15SLorenzo Bianconi .addr = 0x3a, 34292617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 34392617c15SLorenzo Bianconi }, 3441b7da2faSLorenzo Bianconi .max_size = 1365, 34592617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 34692617c15SLorenzo Bianconi }, 34721345107SLorenzo Bianconi .ts_settings = { 34821345107SLorenzo Bianconi .timer_en = { 34921345107SLorenzo Bianconi .addr = 0x58, 35021345107SLorenzo Bianconi .mask = BIT(7), 35121345107SLorenzo Bianconi }, 35221345107SLorenzo Bianconi .hr_timer = { 35321345107SLorenzo Bianconi .addr = 0x5c, 35421345107SLorenzo Bianconi .mask = BIT(4), 35521345107SLorenzo Bianconi }, 35621345107SLorenzo Bianconi .fifo_en = { 35721345107SLorenzo Bianconi .addr = 0x07, 35821345107SLorenzo Bianconi .mask = BIT(7), 35921345107SLorenzo Bianconi }, 36021345107SLorenzo Bianconi .decimator = { 36121345107SLorenzo Bianconi .addr = 0x09, 36221345107SLorenzo Bianconi .mask = GENMASK(5, 3), 36321345107SLorenzo Bianconi }, 36421345107SLorenzo Bianconi }, 365b5969abfSSean Nyekjaer .event_settings = { 366b5969abfSSean Nyekjaer .wakeup_reg = { 367b5969abfSSean Nyekjaer .addr = 0x5B, 368b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 369b5969abfSSean Nyekjaer }, 3701aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 3711aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 3721aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 3731aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 3741aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 375b5969abfSSean Nyekjaer }, 376290a6ce1SLorenzo Bianconi }, 377290a6ce1SLorenzo Bianconi { 37866b662a1SLorenzo Bianconi .reset = { 37966b662a1SLorenzo Bianconi .addr = 0x12, 38066b662a1SLorenzo Bianconi .mask = BIT(0), 38166b662a1SLorenzo Bianconi }, 38266b662a1SLorenzo Bianconi .boot = { 38366b662a1SLorenzo Bianconi .addr = 0x12, 38466b662a1SLorenzo Bianconi .mask = BIT(7), 38566b662a1SLorenzo Bianconi }, 38666b662a1SLorenzo Bianconi .bdu = { 38766b662a1SLorenzo Bianconi .addr = 0x12, 38866b662a1SLorenzo Bianconi .mask = BIT(6), 38966b662a1SLorenzo Bianconi }, 390df47710aSLorenzo Bianconi .id = { 39181956a93SLorenzo Bianconi { 39281956a93SLorenzo Bianconi .hw_id = ST_LSM6DS3H_ID, 39381956a93SLorenzo Bianconi .name = ST_LSM6DS3H_DEV_NAME, 39498c3544aSLorenzo Bianconi .wai = 0x69, 39581956a93SLorenzo Bianconi }, 396df47710aSLorenzo Bianconi }, 397f48bc49bSLorenzo Bianconi .channels = { 398f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 399f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 400f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 401f48bc49bSLorenzo Bianconi }, 402f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 403f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 404f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 405f48bc49bSLorenzo Bianconi }, 406f48bc49bSLorenzo Bianconi }, 40740dd7343SLorenzo Bianconi .odr_table = { 40840dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 40940dd7343SLorenzo Bianconi .reg = { 41040dd7343SLorenzo Bianconi .addr = 0x10, 41140dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 41240dd7343SLorenzo Bianconi }, 413f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 414f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 415f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 416f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 417f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 418f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 41959af4e20SLorenzo Bianconi .odr_len = 6, 42040dd7343SLorenzo Bianconi }, 42140dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 42240dd7343SLorenzo Bianconi .reg = { 42340dd7343SLorenzo Bianconi .addr = 0x11, 42440dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 42540dd7343SLorenzo Bianconi }, 426f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 427f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 428f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 429f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 430f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 431f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 43259af4e20SLorenzo Bianconi .odr_len = 6, 43340dd7343SLorenzo Bianconi }, 43440dd7343SLorenzo Bianconi }, 435640aca3fSLorenzo Bianconi .fs_table = { 436640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 437640aca3fSLorenzo Bianconi .reg = { 438640aca3fSLorenzo Bianconi .addr = 0x10, 439640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 440640aca3fSLorenzo Bianconi }, 44144a76de8SMario Tesi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 44244a76de8SMario Tesi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 44344a76de8SMario Tesi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 44444a76de8SMario Tesi .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, 44585ae3aeeSLorenzo Bianconi .fs_len = 4, 446640aca3fSLorenzo Bianconi }, 447640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 448640aca3fSLorenzo Bianconi .reg = { 449640aca3fSLorenzo Bianconi .addr = 0x11, 450640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 451640aca3fSLorenzo Bianconi }, 45244a76de8SMario Tesi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 45344a76de8SMario Tesi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 45444a76de8SMario Tesi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, 45544a76de8SMario Tesi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 45685ae3aeeSLorenzo Bianconi .fs_len = 4, 457640aca3fSLorenzo Bianconi }, 458640aca3fSLorenzo Bianconi }, 4597e906103SLorenzo Bianconi .irq_config = { 4607e906103SLorenzo Bianconi .irq1 = { 4617e906103SLorenzo Bianconi .addr = 0x0d, 4627e906103SLorenzo Bianconi .mask = BIT(3), 4637e906103SLorenzo Bianconi }, 4647e906103SLorenzo Bianconi .irq2 = { 4657e906103SLorenzo Bianconi .addr = 0x0e, 4667e906103SLorenzo Bianconi .mask = BIT(3), 4677e906103SLorenzo Bianconi }, 4687e906103SLorenzo Bianconi .lir = { 4697e906103SLorenzo Bianconi .addr = 0x58, 4707e906103SLorenzo Bianconi .mask = BIT(0), 4717e906103SLorenzo Bianconi }, 4727e906103SLorenzo Bianconi .irq1_func = { 4737e906103SLorenzo Bianconi .addr = 0x5e, 4747e906103SLorenzo Bianconi .mask = BIT(5), 4757e906103SLorenzo Bianconi }, 4767e906103SLorenzo Bianconi .irq2_func = { 4777e906103SLorenzo Bianconi .addr = 0x5f, 4787e906103SLorenzo Bianconi .mask = BIT(5), 4797e906103SLorenzo Bianconi }, 48031fe8d4eSLorenzo Bianconi .hla = { 48131fe8d4eSLorenzo Bianconi .addr = 0x12, 48231fe8d4eSLorenzo Bianconi .mask = BIT(5), 48331fe8d4eSLorenzo Bianconi }, 48431fe8d4eSLorenzo Bianconi .od = { 48531fe8d4eSLorenzo Bianconi .addr = 0x12, 48631fe8d4eSLorenzo Bianconi .mask = BIT(4), 48731fe8d4eSLorenzo Bianconi }, 4887e906103SLorenzo Bianconi }, 4897ca3ac9eSLorenzo Bianconi .decimator = { 4907ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 4917ca3ac9eSLorenzo Bianconi .addr = 0x08, 4927ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 4937ca3ac9eSLorenzo Bianconi }, 4947ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 4957ca3ac9eSLorenzo Bianconi .addr = 0x08, 4967ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 4977ca3ac9eSLorenzo Bianconi }, 4987ca3ac9eSLorenzo Bianconi }, 49992617c15SLorenzo Bianconi .fifo_ops = { 5003b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 50150ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 50292617c15SLorenzo Bianconi .fifo_th = { 50392617c15SLorenzo Bianconi .addr = 0x06, 50492617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 50592617c15SLorenzo Bianconi }, 50692617c15SLorenzo Bianconi .fifo_diff = { 50792617c15SLorenzo Bianconi .addr = 0x3a, 50892617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 50992617c15SLorenzo Bianconi }, 5101b7da2faSLorenzo Bianconi .max_size = 682, 51192617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 51292617c15SLorenzo Bianconi }, 51321345107SLorenzo Bianconi .ts_settings = { 51421345107SLorenzo Bianconi .timer_en = { 51521345107SLorenzo Bianconi .addr = 0x58, 51621345107SLorenzo Bianconi .mask = BIT(7), 51721345107SLorenzo Bianconi }, 51821345107SLorenzo Bianconi .hr_timer = { 51921345107SLorenzo Bianconi .addr = 0x5c, 52021345107SLorenzo Bianconi .mask = BIT(4), 52121345107SLorenzo Bianconi }, 52221345107SLorenzo Bianconi .fifo_en = { 52321345107SLorenzo Bianconi .addr = 0x07, 52421345107SLorenzo Bianconi .mask = BIT(7), 52521345107SLorenzo Bianconi }, 52621345107SLorenzo Bianconi .decimator = { 52721345107SLorenzo Bianconi .addr = 0x09, 52821345107SLorenzo Bianconi .mask = GENMASK(5, 3), 52921345107SLorenzo Bianconi }, 53021345107SLorenzo Bianconi }, 531b5969abfSSean Nyekjaer .event_settings = { 532b5969abfSSean Nyekjaer .wakeup_reg = { 533b5969abfSSean Nyekjaer .addr = 0x5B, 534b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 535b5969abfSSean Nyekjaer }, 5361aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 5371aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 5381aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 5391aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 5401aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 541b5969abfSSean Nyekjaer }, 542df47710aSLorenzo Bianconi }, 543df47710aSLorenzo Bianconi { 54466b662a1SLorenzo Bianconi .reset = { 54566b662a1SLorenzo Bianconi .addr = 0x12, 54666b662a1SLorenzo Bianconi .mask = BIT(0), 54766b662a1SLorenzo Bianconi }, 54866b662a1SLorenzo Bianconi .boot = { 54966b662a1SLorenzo Bianconi .addr = 0x12, 55066b662a1SLorenzo Bianconi .mask = BIT(7), 55166b662a1SLorenzo Bianconi }, 55266b662a1SLorenzo Bianconi .bdu = { 55366b662a1SLorenzo Bianconi .addr = 0x12, 55466b662a1SLorenzo Bianconi .mask = BIT(6), 55566b662a1SLorenzo Bianconi }, 556d068e4a0SLorenzo Bianconi .id = { 55781956a93SLorenzo Bianconi { 55881956a93SLorenzo Bianconi .hw_id = ST_LSM6DSL_ID, 55981956a93SLorenzo Bianconi .name = ST_LSM6DSL_DEV_NAME, 56098c3544aSLorenzo Bianconi .wai = 0x6a, 56181956a93SLorenzo Bianconi }, { 56281956a93SLorenzo Bianconi .hw_id = ST_LSM6DSM_ID, 56381956a93SLorenzo Bianconi .name = ST_LSM6DSM_DEV_NAME, 56498c3544aSLorenzo Bianconi .wai = 0x6a, 56581956a93SLorenzo Bianconi }, { 56681956a93SLorenzo Bianconi .hw_id = ST_ISM330DLC_ID, 56781956a93SLorenzo Bianconi .name = ST_ISM330DLC_DEV_NAME, 56898c3544aSLorenzo Bianconi .wai = 0x6a, 569dbcd2088SLorenzo Bianconi }, { 570dbcd2088SLorenzo Bianconi .hw_id = ST_LSM6DS3TRC_ID, 571dbcd2088SLorenzo Bianconi .name = ST_LSM6DS3TRC_DEV_NAME, 57298c3544aSLorenzo Bianconi .wai = 0x6a, 57381956a93SLorenzo Bianconi }, 574d068e4a0SLorenzo Bianconi }, 575f48bc49bSLorenzo Bianconi .channels = { 576f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 577f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 578f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 579f48bc49bSLorenzo Bianconi }, 580f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 581f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 582f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 583f48bc49bSLorenzo Bianconi }, 584f48bc49bSLorenzo Bianconi }, 58540dd7343SLorenzo Bianconi .odr_table = { 58640dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 58740dd7343SLorenzo Bianconi .reg = { 58840dd7343SLorenzo Bianconi .addr = 0x10, 58940dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 59040dd7343SLorenzo Bianconi }, 591f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 592f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 593f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 594f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 595f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 596f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 59759af4e20SLorenzo Bianconi .odr_len = 6, 59840dd7343SLorenzo Bianconi }, 59940dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 60040dd7343SLorenzo Bianconi .reg = { 60140dd7343SLorenzo Bianconi .addr = 0x11, 60240dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 60340dd7343SLorenzo Bianconi }, 604f8710f03SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 605f8710f03SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 606f8710f03SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 607f8710f03SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 608f8710f03SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 609f8710f03SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 61059af4e20SLorenzo Bianconi .odr_len = 6, 61140dd7343SLorenzo Bianconi }, 61240dd7343SLorenzo Bianconi }, 613640aca3fSLorenzo Bianconi .fs_table = { 614640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 615640aca3fSLorenzo Bianconi .reg = { 616640aca3fSLorenzo Bianconi .addr = 0x10, 617640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 618640aca3fSLorenzo Bianconi }, 61944a76de8SMario Tesi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 62044a76de8SMario Tesi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 62144a76de8SMario Tesi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 62244a76de8SMario Tesi .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, 62385ae3aeeSLorenzo Bianconi .fs_len = 4, 624640aca3fSLorenzo Bianconi }, 625640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 626640aca3fSLorenzo Bianconi .reg = { 627640aca3fSLorenzo Bianconi .addr = 0x11, 628640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 629640aca3fSLorenzo Bianconi }, 63044a76de8SMario Tesi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 63144a76de8SMario Tesi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 63244a76de8SMario Tesi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, 63344a76de8SMario Tesi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 63485ae3aeeSLorenzo Bianconi .fs_len = 4, 635640aca3fSLorenzo Bianconi }, 636640aca3fSLorenzo Bianconi }, 6377e906103SLorenzo Bianconi .irq_config = { 6387e906103SLorenzo Bianconi .irq1 = { 6397e906103SLorenzo Bianconi .addr = 0x0d, 6407e906103SLorenzo Bianconi .mask = BIT(3), 6417e906103SLorenzo Bianconi }, 6427e906103SLorenzo Bianconi .irq2 = { 6437e906103SLorenzo Bianconi .addr = 0x0e, 6447e906103SLorenzo Bianconi .mask = BIT(3), 6457e906103SLorenzo Bianconi }, 6467e906103SLorenzo Bianconi .lir = { 6477e906103SLorenzo Bianconi .addr = 0x58, 6487e906103SLorenzo Bianconi .mask = BIT(0), 6497e906103SLorenzo Bianconi }, 6507e906103SLorenzo Bianconi .irq1_func = { 6517e906103SLorenzo Bianconi .addr = 0x5e, 6527e906103SLorenzo Bianconi .mask = BIT(5), 6537e906103SLorenzo Bianconi }, 6547e906103SLorenzo Bianconi .irq2_func = { 6557e906103SLorenzo Bianconi .addr = 0x5f, 6567e906103SLorenzo Bianconi .mask = BIT(5), 6577e906103SLorenzo Bianconi }, 65831fe8d4eSLorenzo Bianconi .hla = { 65931fe8d4eSLorenzo Bianconi .addr = 0x12, 66031fe8d4eSLorenzo Bianconi .mask = BIT(5), 66131fe8d4eSLorenzo Bianconi }, 66231fe8d4eSLorenzo Bianconi .od = { 66331fe8d4eSLorenzo Bianconi .addr = 0x12, 66431fe8d4eSLorenzo Bianconi .mask = BIT(4), 66531fe8d4eSLorenzo Bianconi }, 6667e906103SLorenzo Bianconi }, 6677ca3ac9eSLorenzo Bianconi .decimator = { 6687ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 6697ca3ac9eSLorenzo Bianconi .addr = 0x08, 6707ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 6717ca3ac9eSLorenzo Bianconi }, 6727ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 6737ca3ac9eSLorenzo Bianconi .addr = 0x08, 6747ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 6757ca3ac9eSLorenzo Bianconi }, 676e485e2a2SLorenzo Bianconi [ST_LSM6DSX_ID_EXT0] = { 677e485e2a2SLorenzo Bianconi .addr = 0x09, 678e485e2a2SLorenzo Bianconi .mask = GENMASK(2, 0), 679e485e2a2SLorenzo Bianconi }, 6807ca3ac9eSLorenzo Bianconi }, 68192617c15SLorenzo Bianconi .fifo_ops = { 6823b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 68350ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 68492617c15SLorenzo Bianconi .fifo_th = { 68592617c15SLorenzo Bianconi .addr = 0x06, 686be75eb86SLorenzo Bianconi .mask = GENMASK(10, 0), 68792617c15SLorenzo Bianconi }, 68892617c15SLorenzo Bianconi .fifo_diff = { 68992617c15SLorenzo Bianconi .addr = 0x3a, 690be75eb86SLorenzo Bianconi .mask = GENMASK(10, 0), 69192617c15SLorenzo Bianconi }, 6921b7da2faSLorenzo Bianconi .max_size = 682, 69392617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 69492617c15SLorenzo Bianconi }, 69521345107SLorenzo Bianconi .ts_settings = { 69621345107SLorenzo Bianconi .timer_en = { 69721345107SLorenzo Bianconi .addr = 0x19, 69821345107SLorenzo Bianconi .mask = BIT(5), 69921345107SLorenzo Bianconi }, 70021345107SLorenzo Bianconi .hr_timer = { 70121345107SLorenzo Bianconi .addr = 0x5c, 70221345107SLorenzo Bianconi .mask = BIT(4), 70321345107SLorenzo Bianconi }, 70421345107SLorenzo Bianconi .fifo_en = { 70521345107SLorenzo Bianconi .addr = 0x07, 70621345107SLorenzo Bianconi .mask = BIT(7), 70721345107SLorenzo Bianconi }, 70821345107SLorenzo Bianconi .decimator = { 70921345107SLorenzo Bianconi .addr = 0x09, 71021345107SLorenzo Bianconi .mask = GENMASK(5, 3), 71121345107SLorenzo Bianconi }, 71221345107SLorenzo Bianconi }, 713e485e2a2SLorenzo Bianconi .shub_settings = { 714e485e2a2SLorenzo Bianconi .page_mux = { 715e485e2a2SLorenzo Bianconi .addr = 0x01, 716e485e2a2SLorenzo Bianconi .mask = BIT(7), 717e485e2a2SLorenzo Bianconi }, 718e485e2a2SLorenzo Bianconi .master_en = { 719e485e2a2SLorenzo Bianconi .addr = 0x1a, 720e485e2a2SLorenzo Bianconi .mask = BIT(0), 721e485e2a2SLorenzo Bianconi }, 722e485e2a2SLorenzo Bianconi .pullup_en = { 723e485e2a2SLorenzo Bianconi .addr = 0x1a, 724e485e2a2SLorenzo Bianconi .mask = BIT(3), 725e485e2a2SLorenzo Bianconi }, 726e485e2a2SLorenzo Bianconi .aux_sens = { 727e485e2a2SLorenzo Bianconi .addr = 0x04, 728e485e2a2SLorenzo Bianconi .mask = GENMASK(5, 4), 729e485e2a2SLorenzo Bianconi }, 730e485e2a2SLorenzo Bianconi .wr_once = { 731e485e2a2SLorenzo Bianconi .addr = 0x07, 732e485e2a2SLorenzo Bianconi .mask = BIT(5), 733e485e2a2SLorenzo Bianconi }, 734e485e2a2SLorenzo Bianconi .emb_func = { 735e485e2a2SLorenzo Bianconi .addr = 0x19, 736e485e2a2SLorenzo Bianconi .mask = BIT(2), 737e485e2a2SLorenzo Bianconi }, 738e485e2a2SLorenzo Bianconi .num_ext_dev = 1, 739e485e2a2SLorenzo Bianconi .shub_out = { 740e485e2a2SLorenzo Bianconi .addr = 0x2e, 741e485e2a2SLorenzo Bianconi }, 742e485e2a2SLorenzo Bianconi .slv0_addr = 0x02, 743e485e2a2SLorenzo Bianconi .dw_slv0_addr = 0x0e, 744e485e2a2SLorenzo Bianconi .pause = 0x7, 745e485e2a2SLorenzo Bianconi }, 746b5969abfSSean Nyekjaer .event_settings = { 747b5969abfSSean Nyekjaer .enable_reg = { 748b5969abfSSean Nyekjaer .addr = 0x58, 749b5969abfSSean Nyekjaer .mask = BIT(7), 750b5969abfSSean Nyekjaer }, 751b5969abfSSean Nyekjaer .wakeup_reg = { 752b5969abfSSean Nyekjaer .addr = 0x5B, 753b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 754b5969abfSSean Nyekjaer }, 7551aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 7561aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 7571aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 7581aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 7591aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 760b5969abfSSean Nyekjaer }, 761290a6ce1SLorenzo Bianconi }, 762801a6e0aSLorenzo Bianconi { 76366b662a1SLorenzo Bianconi .reset = { 76466b662a1SLorenzo Bianconi .addr = 0x12, 76566b662a1SLorenzo Bianconi .mask = BIT(0), 76666b662a1SLorenzo Bianconi }, 76766b662a1SLorenzo Bianconi .boot = { 76866b662a1SLorenzo Bianconi .addr = 0x12, 76966b662a1SLorenzo Bianconi .mask = BIT(7), 77066b662a1SLorenzo Bianconi }, 77166b662a1SLorenzo Bianconi .bdu = { 77266b662a1SLorenzo Bianconi .addr = 0x12, 77366b662a1SLorenzo Bianconi .mask = BIT(6), 77466b662a1SLorenzo Bianconi }, 77543901008SLorenzo Bianconi .id = { 77681956a93SLorenzo Bianconi { 77781956a93SLorenzo Bianconi .hw_id = ST_LSM6DSR_ID, 77881956a93SLorenzo Bianconi .name = ST_LSM6DSR_DEV_NAME, 77998c3544aSLorenzo Bianconi .wai = 0x6b, 780db947a79SLorenzo Bianconi }, { 781db947a79SLorenzo Bianconi .hw_id = ST_ISM330DHCX_ID, 782db947a79SLorenzo Bianconi .name = ST_ISM330DHCX_DEV_NAME, 78398c3544aSLorenzo Bianconi .wai = 0x6b, 784cf9c71b3SLorenzo Bianconi }, { 785cf9c71b3SLorenzo Bianconi .hw_id = ST_LSM6DSRX_ID, 786cf9c71b3SLorenzo Bianconi .name = ST_LSM6DSRX_DEV_NAME, 78798c3544aSLorenzo Bianconi .wai = 0x6b, 78898c3544aSLorenzo Bianconi }, { 78998c3544aSLorenzo Bianconi .hw_id = ST_LSM6DSO_ID, 79098c3544aSLorenzo Bianconi .name = ST_LSM6DSO_DEV_NAME, 79198c3544aSLorenzo Bianconi .wai = 0x6c, 79298c3544aSLorenzo Bianconi }, { 79398c3544aSLorenzo Bianconi .hw_id = ST_LSM6DSOX_ID, 79498c3544aSLorenzo Bianconi .name = ST_LSM6DSOX_DEV_NAME, 79598c3544aSLorenzo Bianconi .wai = 0x6c, 79698c3544aSLorenzo Bianconi }, { 7974393e4c5SLorenzo Bianconi .hw_id = ST_LSM6DST_ID, 7984393e4c5SLorenzo Bianconi .name = ST_LSM6DST_DEV_NAME, 79998c3544aSLorenzo Bianconi .wai = 0x6d, 800fdd70d7aSLorenzo Bianconi }, { 801fdd70d7aSLorenzo Bianconi .hw_id = ST_ASM330LHHX_ID, 802fdd70d7aSLorenzo Bianconi .name = ST_ASM330LHHX_DEV_NAME, 803fdd70d7aSLorenzo Bianconi .wai = 0x6b, 804186b9e38SLorenzo Bianconi }, { 805186b9e38SLorenzo Bianconi .hw_id = ST_LSM6DSTX_ID, 806186b9e38SLorenzo Bianconi .name = ST_LSM6DSTX_DEV_NAME, 807186b9e38SLorenzo Bianconi .wai = 0x6d, 8084393e4c5SLorenzo Bianconi }, 8094393e4c5SLorenzo Bianconi }, 8104393e4c5SLorenzo Bianconi .channels = { 8114393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 8124393e4c5SLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 8134393e4c5SLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 8144393e4c5SLorenzo Bianconi }, 8154393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 8164393e4c5SLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 8174393e4c5SLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 8184393e4c5SLorenzo Bianconi }, 8194393e4c5SLorenzo Bianconi }, 8204393e4c5SLorenzo Bianconi .drdy_mask = { 8214393e4c5SLorenzo Bianconi .addr = 0x13, 8224393e4c5SLorenzo Bianconi .mask = BIT(3), 8234393e4c5SLorenzo Bianconi }, 8244393e4c5SLorenzo Bianconi .odr_table = { 8254393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 8264393e4c5SLorenzo Bianconi .reg = { 8274393e4c5SLorenzo Bianconi .addr = 0x10, 8284393e4c5SLorenzo Bianconi .mask = GENMASK(7, 4), 8294393e4c5SLorenzo Bianconi }, 8304393e4c5SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 8314393e4c5SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 8324393e4c5SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 8334393e4c5SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 8344393e4c5SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 8354393e4c5SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 8364393e4c5SLorenzo Bianconi .odr_avl[6] = { 833000, 0x07 }, 8374393e4c5SLorenzo Bianconi .odr_len = 7, 8384393e4c5SLorenzo Bianconi }, 8394393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 8404393e4c5SLorenzo Bianconi .reg = { 8414393e4c5SLorenzo Bianconi .addr = 0x11, 8424393e4c5SLorenzo Bianconi .mask = GENMASK(7, 4), 8434393e4c5SLorenzo Bianconi }, 8444393e4c5SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 8454393e4c5SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 8464393e4c5SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 8474393e4c5SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 8484393e4c5SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 8494393e4c5SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 8504393e4c5SLorenzo Bianconi .odr_avl[6] = { 833000, 0x07 }, 8514393e4c5SLorenzo Bianconi .odr_len = 7, 8524393e4c5SLorenzo Bianconi }, 8534393e4c5SLorenzo Bianconi }, 8544393e4c5SLorenzo Bianconi .fs_table = { 8554393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 8564393e4c5SLorenzo Bianconi .reg = { 8574393e4c5SLorenzo Bianconi .addr = 0x10, 8584393e4c5SLorenzo Bianconi .mask = GENMASK(3, 2), 8594393e4c5SLorenzo Bianconi }, 8604393e4c5SLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 8614393e4c5SLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 8624393e4c5SLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 8634393e4c5SLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, 8644393e4c5SLorenzo Bianconi .fs_len = 4, 8654393e4c5SLorenzo Bianconi }, 8664393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 8674393e4c5SLorenzo Bianconi .reg = { 8684393e4c5SLorenzo Bianconi .addr = 0x11, 8694393e4c5SLorenzo Bianconi .mask = GENMASK(3, 2), 8704393e4c5SLorenzo Bianconi }, 8714393e4c5SLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 8724393e4c5SLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 8734393e4c5SLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, 8744393e4c5SLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 8754393e4c5SLorenzo Bianconi .fs_len = 4, 8764393e4c5SLorenzo Bianconi }, 8774393e4c5SLorenzo Bianconi }, 8784393e4c5SLorenzo Bianconi .irq_config = { 8794393e4c5SLorenzo Bianconi .irq1 = { 8804393e4c5SLorenzo Bianconi .addr = 0x0d, 8814393e4c5SLorenzo Bianconi .mask = BIT(3), 8824393e4c5SLorenzo Bianconi }, 8834393e4c5SLorenzo Bianconi .irq2 = { 8844393e4c5SLorenzo Bianconi .addr = 0x0e, 8854393e4c5SLorenzo Bianconi .mask = BIT(3), 8864393e4c5SLorenzo Bianconi }, 8874393e4c5SLorenzo Bianconi .lir = { 8884393e4c5SLorenzo Bianconi .addr = 0x56, 8894393e4c5SLorenzo Bianconi .mask = BIT(0), 8904393e4c5SLorenzo Bianconi }, 8914393e4c5SLorenzo Bianconi .clear_on_read = { 8924393e4c5SLorenzo Bianconi .addr = 0x56, 8934393e4c5SLorenzo Bianconi .mask = BIT(6), 8944393e4c5SLorenzo Bianconi }, 8954393e4c5SLorenzo Bianconi .irq1_func = { 8964393e4c5SLorenzo Bianconi .addr = 0x5e, 8974393e4c5SLorenzo Bianconi .mask = BIT(5), 8984393e4c5SLorenzo Bianconi }, 8994393e4c5SLorenzo Bianconi .irq2_func = { 9004393e4c5SLorenzo Bianconi .addr = 0x5f, 9014393e4c5SLorenzo Bianconi .mask = BIT(5), 9024393e4c5SLorenzo Bianconi }, 9034393e4c5SLorenzo Bianconi .hla = { 9044393e4c5SLorenzo Bianconi .addr = 0x12, 9054393e4c5SLorenzo Bianconi .mask = BIT(5), 9064393e4c5SLorenzo Bianconi }, 9074393e4c5SLorenzo Bianconi .od = { 9084393e4c5SLorenzo Bianconi .addr = 0x12, 9094393e4c5SLorenzo Bianconi .mask = BIT(4), 9104393e4c5SLorenzo Bianconi }, 9114393e4c5SLorenzo Bianconi }, 9124393e4c5SLorenzo Bianconi .batch = { 9134393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 9144393e4c5SLorenzo Bianconi .addr = 0x09, 9154393e4c5SLorenzo Bianconi .mask = GENMASK(3, 0), 9164393e4c5SLorenzo Bianconi }, 9174393e4c5SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 9184393e4c5SLorenzo Bianconi .addr = 0x09, 9194393e4c5SLorenzo Bianconi .mask = GENMASK(7, 4), 9204393e4c5SLorenzo Bianconi }, 9214393e4c5SLorenzo Bianconi }, 9224393e4c5SLorenzo Bianconi .fifo_ops = { 9234393e4c5SLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 9244393e4c5SLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 9254393e4c5SLorenzo Bianconi .fifo_th = { 9264393e4c5SLorenzo Bianconi .addr = 0x07, 9274393e4c5SLorenzo Bianconi .mask = GENMASK(8, 0), 9284393e4c5SLorenzo Bianconi }, 9294393e4c5SLorenzo Bianconi .fifo_diff = { 9304393e4c5SLorenzo Bianconi .addr = 0x3a, 9314393e4c5SLorenzo Bianconi .mask = GENMASK(9, 0), 9324393e4c5SLorenzo Bianconi }, 9331b7da2faSLorenzo Bianconi .max_size = 512, 9344393e4c5SLorenzo Bianconi .th_wl = 1, 9354393e4c5SLorenzo Bianconi }, 9364393e4c5SLorenzo Bianconi .ts_settings = { 9374393e4c5SLorenzo Bianconi .timer_en = { 9384393e4c5SLorenzo Bianconi .addr = 0x19, 9394393e4c5SLorenzo Bianconi .mask = BIT(5), 9404393e4c5SLorenzo Bianconi }, 9414393e4c5SLorenzo Bianconi .decimator = { 9424393e4c5SLorenzo Bianconi .addr = 0x0a, 9434393e4c5SLorenzo Bianconi .mask = GENMASK(7, 6), 9444393e4c5SLorenzo Bianconi }, 9454393e4c5SLorenzo Bianconi .freq_fine = 0x63, 9464393e4c5SLorenzo Bianconi }, 9474393e4c5SLorenzo Bianconi .shub_settings = { 9484393e4c5SLorenzo Bianconi .page_mux = { 9494393e4c5SLorenzo Bianconi .addr = 0x01, 9504393e4c5SLorenzo Bianconi .mask = BIT(6), 9514393e4c5SLorenzo Bianconi }, 9524393e4c5SLorenzo Bianconi .master_en = { 9534393e4c5SLorenzo Bianconi .sec_page = true, 9544393e4c5SLorenzo Bianconi .addr = 0x14, 9554393e4c5SLorenzo Bianconi .mask = BIT(2), 9564393e4c5SLorenzo Bianconi }, 9574393e4c5SLorenzo Bianconi .pullup_en = { 9584393e4c5SLorenzo Bianconi .sec_page = true, 9594393e4c5SLorenzo Bianconi .addr = 0x14, 9604393e4c5SLorenzo Bianconi .mask = BIT(3), 9614393e4c5SLorenzo Bianconi }, 9624393e4c5SLorenzo Bianconi .aux_sens = { 9634393e4c5SLorenzo Bianconi .addr = 0x14, 9644393e4c5SLorenzo Bianconi .mask = GENMASK(1, 0), 9654393e4c5SLorenzo Bianconi }, 9664393e4c5SLorenzo Bianconi .wr_once = { 9674393e4c5SLorenzo Bianconi .addr = 0x14, 9684393e4c5SLorenzo Bianconi .mask = BIT(6), 9694393e4c5SLorenzo Bianconi }, 9704393e4c5SLorenzo Bianconi .num_ext_dev = 3, 9714393e4c5SLorenzo Bianconi .shub_out = { 9724393e4c5SLorenzo Bianconi .sec_page = true, 9734393e4c5SLorenzo Bianconi .addr = 0x02, 9744393e4c5SLorenzo Bianconi }, 9754393e4c5SLorenzo Bianconi .slv0_addr = 0x15, 9764393e4c5SLorenzo Bianconi .dw_slv0_addr = 0x21, 9774393e4c5SLorenzo Bianconi .batch_en = BIT(3), 9784393e4c5SLorenzo Bianconi }, 9794393e4c5SLorenzo Bianconi .event_settings = { 9804393e4c5SLorenzo Bianconi .enable_reg = { 9814393e4c5SLorenzo Bianconi .addr = 0x58, 9824393e4c5SLorenzo Bianconi .mask = BIT(7), 9834393e4c5SLorenzo Bianconi }, 9844393e4c5SLorenzo Bianconi .wakeup_reg = { 9854393e4c5SLorenzo Bianconi .addr = 0x5b, 9864393e4c5SLorenzo Bianconi .mask = GENMASK(5, 0), 9874393e4c5SLorenzo Bianconi }, 9884393e4c5SLorenzo Bianconi .wakeup_src_reg = 0x1b, 9894393e4c5SLorenzo Bianconi .wakeup_src_status_mask = BIT(3), 9904393e4c5SLorenzo Bianconi .wakeup_src_z_mask = BIT(0), 9914393e4c5SLorenzo Bianconi .wakeup_src_y_mask = BIT(1), 9924393e4c5SLorenzo Bianconi .wakeup_src_x_mask = BIT(2), 9934393e4c5SLorenzo Bianconi }, 9944393e4c5SLorenzo Bianconi }, 99598c3544aSLorenzo Bianconi { 99698c3544aSLorenzo Bianconi .reset = { 99798c3544aSLorenzo Bianconi .addr = 0x12, 99898c3544aSLorenzo Bianconi .mask = BIT(0), 99998c3544aSLorenzo Bianconi }, 100098c3544aSLorenzo Bianconi .boot = { 100198c3544aSLorenzo Bianconi .addr = 0x12, 100298c3544aSLorenzo Bianconi .mask = BIT(7), 100398c3544aSLorenzo Bianconi }, 100498c3544aSLorenzo Bianconi .bdu = { 100598c3544aSLorenzo Bianconi .addr = 0x12, 100698c3544aSLorenzo Bianconi .mask = BIT(6), 100798c3544aSLorenzo Bianconi }, 100898c3544aSLorenzo Bianconi .id = { 100998c3544aSLorenzo Bianconi { 101098c3544aSLorenzo Bianconi .hw_id = ST_ASM330LHH_ID, 101198c3544aSLorenzo Bianconi .name = ST_ASM330LHH_DEV_NAME, 101298c3544aSLorenzo Bianconi .wai = 0x6b, 10132c57d265SLorenzo Bianconi }, { 10142c57d265SLorenzo Bianconi .hw_id = ST_LSM6DSOP_ID, 10152c57d265SLorenzo Bianconi .name = ST_LSM6DSOP_DEV_NAME, 10162c57d265SLorenzo Bianconi .wai = 0x6c, 101798c3544aSLorenzo Bianconi }, 101898c3544aSLorenzo Bianconi }, 101998c3544aSLorenzo Bianconi .channels = { 102098c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 102198c3544aSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 102298c3544aSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 102398c3544aSLorenzo Bianconi }, 102498c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 102598c3544aSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 102698c3544aSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 102798c3544aSLorenzo Bianconi }, 102898c3544aSLorenzo Bianconi }, 102998c3544aSLorenzo Bianconi .drdy_mask = { 103098c3544aSLorenzo Bianconi .addr = 0x13, 103198c3544aSLorenzo Bianconi .mask = BIT(3), 103298c3544aSLorenzo Bianconi }, 103398c3544aSLorenzo Bianconi .odr_table = { 103498c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 103598c3544aSLorenzo Bianconi .reg = { 103698c3544aSLorenzo Bianconi .addr = 0x10, 103798c3544aSLorenzo Bianconi .mask = GENMASK(7, 4), 103898c3544aSLorenzo Bianconi }, 103998c3544aSLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 104098c3544aSLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 104198c3544aSLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 104298c3544aSLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 104398c3544aSLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 104498c3544aSLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 104598c3544aSLorenzo Bianconi .odr_avl[6] = { 833000, 0x07 }, 104698c3544aSLorenzo Bianconi .odr_len = 7, 104798c3544aSLorenzo Bianconi }, 104898c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 104998c3544aSLorenzo Bianconi .reg = { 105098c3544aSLorenzo Bianconi .addr = 0x11, 105198c3544aSLorenzo Bianconi .mask = GENMASK(7, 4), 105298c3544aSLorenzo Bianconi }, 105398c3544aSLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 105498c3544aSLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 105598c3544aSLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 105698c3544aSLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 105798c3544aSLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 105898c3544aSLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 105998c3544aSLorenzo Bianconi .odr_avl[6] = { 833000, 0x07 }, 106098c3544aSLorenzo Bianconi .odr_len = 7, 106198c3544aSLorenzo Bianconi }, 106298c3544aSLorenzo Bianconi }, 106398c3544aSLorenzo Bianconi .fs_table = { 106498c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 106598c3544aSLorenzo Bianconi .reg = { 106698c3544aSLorenzo Bianconi .addr = 0x10, 106798c3544aSLorenzo Bianconi .mask = GENMASK(3, 2), 106898c3544aSLorenzo Bianconi }, 106998c3544aSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 107098c3544aSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 107198c3544aSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 107298c3544aSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, 107398c3544aSLorenzo Bianconi .fs_len = 4, 107498c3544aSLorenzo Bianconi }, 107598c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 107698c3544aSLorenzo Bianconi .reg = { 107798c3544aSLorenzo Bianconi .addr = 0x11, 107898c3544aSLorenzo Bianconi .mask = GENMASK(3, 2), 107998c3544aSLorenzo Bianconi }, 108098c3544aSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 108198c3544aSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 108298c3544aSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, 108398c3544aSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 108498c3544aSLorenzo Bianconi .fs_len = 4, 108598c3544aSLorenzo Bianconi }, 108698c3544aSLorenzo Bianconi }, 108798c3544aSLorenzo Bianconi .irq_config = { 108898c3544aSLorenzo Bianconi .irq1 = { 108998c3544aSLorenzo Bianconi .addr = 0x0d, 109098c3544aSLorenzo Bianconi .mask = BIT(3), 109198c3544aSLorenzo Bianconi }, 109298c3544aSLorenzo Bianconi .irq2 = { 109398c3544aSLorenzo Bianconi .addr = 0x0e, 109498c3544aSLorenzo Bianconi .mask = BIT(3), 109598c3544aSLorenzo Bianconi }, 109698c3544aSLorenzo Bianconi .lir = { 109798c3544aSLorenzo Bianconi .addr = 0x56, 109898c3544aSLorenzo Bianconi .mask = BIT(0), 109998c3544aSLorenzo Bianconi }, 110098c3544aSLorenzo Bianconi .clear_on_read = { 110198c3544aSLorenzo Bianconi .addr = 0x56, 110298c3544aSLorenzo Bianconi .mask = BIT(6), 110398c3544aSLorenzo Bianconi }, 110498c3544aSLorenzo Bianconi .irq1_func = { 110598c3544aSLorenzo Bianconi .addr = 0x5e, 110698c3544aSLorenzo Bianconi .mask = BIT(5), 110798c3544aSLorenzo Bianconi }, 110898c3544aSLorenzo Bianconi .irq2_func = { 110998c3544aSLorenzo Bianconi .addr = 0x5f, 111098c3544aSLorenzo Bianconi .mask = BIT(5), 111198c3544aSLorenzo Bianconi }, 111298c3544aSLorenzo Bianconi .hla = { 111398c3544aSLorenzo Bianconi .addr = 0x12, 111498c3544aSLorenzo Bianconi .mask = BIT(5), 111598c3544aSLorenzo Bianconi }, 111698c3544aSLorenzo Bianconi .od = { 111798c3544aSLorenzo Bianconi .addr = 0x12, 111898c3544aSLorenzo Bianconi .mask = BIT(4), 111998c3544aSLorenzo Bianconi }, 112098c3544aSLorenzo Bianconi }, 112198c3544aSLorenzo Bianconi .batch = { 112298c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 112398c3544aSLorenzo Bianconi .addr = 0x09, 112498c3544aSLorenzo Bianconi .mask = GENMASK(3, 0), 112598c3544aSLorenzo Bianconi }, 112698c3544aSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 112798c3544aSLorenzo Bianconi .addr = 0x09, 112898c3544aSLorenzo Bianconi .mask = GENMASK(7, 4), 112998c3544aSLorenzo Bianconi }, 113098c3544aSLorenzo Bianconi }, 113198c3544aSLorenzo Bianconi .fifo_ops = { 113298c3544aSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 113398c3544aSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 113498c3544aSLorenzo Bianconi .fifo_th = { 113598c3544aSLorenzo Bianconi .addr = 0x07, 113698c3544aSLorenzo Bianconi .mask = GENMASK(8, 0), 113798c3544aSLorenzo Bianconi }, 113898c3544aSLorenzo Bianconi .fifo_diff = { 113998c3544aSLorenzo Bianconi .addr = 0x3a, 114098c3544aSLorenzo Bianconi .mask = GENMASK(9, 0), 114198c3544aSLorenzo Bianconi }, 11421b7da2faSLorenzo Bianconi .max_size = 512, 114398c3544aSLorenzo Bianconi .th_wl = 1, 114498c3544aSLorenzo Bianconi }, 114598c3544aSLorenzo Bianconi .ts_settings = { 114698c3544aSLorenzo Bianconi .timer_en = { 114798c3544aSLorenzo Bianconi .addr = 0x19, 114898c3544aSLorenzo Bianconi .mask = BIT(5), 114998c3544aSLorenzo Bianconi }, 115098c3544aSLorenzo Bianconi .decimator = { 115198c3544aSLorenzo Bianconi .addr = 0x0a, 115298c3544aSLorenzo Bianconi .mask = GENMASK(7, 6), 115398c3544aSLorenzo Bianconi }, 115498c3544aSLorenzo Bianconi .freq_fine = 0x63, 115598c3544aSLorenzo Bianconi }, 115698c3544aSLorenzo Bianconi .event_settings = { 115798c3544aSLorenzo Bianconi .enable_reg = { 115898c3544aSLorenzo Bianconi .addr = 0x58, 115998c3544aSLorenzo Bianconi .mask = BIT(7), 116098c3544aSLorenzo Bianconi }, 116198c3544aSLorenzo Bianconi .wakeup_reg = { 116298c3544aSLorenzo Bianconi .addr = 0x5B, 116398c3544aSLorenzo Bianconi .mask = GENMASK(5, 0), 116498c3544aSLorenzo Bianconi }, 116598c3544aSLorenzo Bianconi .wakeup_src_reg = 0x1b, 116698c3544aSLorenzo Bianconi .wakeup_src_status_mask = BIT(3), 116798c3544aSLorenzo Bianconi .wakeup_src_z_mask = BIT(0), 116898c3544aSLorenzo Bianconi .wakeup_src_y_mask = BIT(1), 116998c3544aSLorenzo Bianconi .wakeup_src_x_mask = BIT(2), 117098c3544aSLorenzo Bianconi }, 117198c3544aSLorenzo Bianconi }, 1172a1c6d631SLorenzo Bianconi { 1173a1c6d631SLorenzo Bianconi .reset = { 1174a1c6d631SLorenzo Bianconi .addr = 0x12, 1175a1c6d631SLorenzo Bianconi .mask = BIT(0), 1176a1c6d631SLorenzo Bianconi }, 1177a1c6d631SLorenzo Bianconi .boot = { 1178a1c6d631SLorenzo Bianconi .addr = 0x12, 1179a1c6d631SLorenzo Bianconi .mask = BIT(7), 1180a1c6d631SLorenzo Bianconi }, 1181a1c6d631SLorenzo Bianconi .bdu = { 1182a1c6d631SLorenzo Bianconi .addr = 0x12, 1183a1c6d631SLorenzo Bianconi .mask = BIT(6), 1184a1c6d631SLorenzo Bianconi }, 1185a1c6d631SLorenzo Bianconi .id = { 1186a1c6d631SLorenzo Bianconi { 1187a1c6d631SLorenzo Bianconi .hw_id = ST_LSM6DSV_ID, 1188a1c6d631SLorenzo Bianconi .name = ST_LSM6DSV_DEV_NAME, 1189a1c6d631SLorenzo Bianconi .wai = 0x70, 119046975081SLorenzo Bianconi }, { 119146975081SLorenzo Bianconi .hw_id = ST_LSM6DSV16X_ID, 119246975081SLorenzo Bianconi .name = ST_LSM6DSV16X_DEV_NAME, 119346975081SLorenzo Bianconi .wai = 0x70, 1194a1c6d631SLorenzo Bianconi }, 1195a1c6d631SLorenzo Bianconi }, 1196a1c6d631SLorenzo Bianconi .channels = { 1197a1c6d631SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 1198a1c6d631SLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 1199a1c6d631SLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 1200a1c6d631SLorenzo Bianconi }, 1201a1c6d631SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 1202a1c6d631SLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 1203a1c6d631SLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 1204a1c6d631SLorenzo Bianconi }, 1205a1c6d631SLorenzo Bianconi }, 1206a1c6d631SLorenzo Bianconi .drdy_mask = { 1207a1c6d631SLorenzo Bianconi .addr = 0x13, 1208a1c6d631SLorenzo Bianconi .mask = BIT(3), 1209a1c6d631SLorenzo Bianconi }, 1210a1c6d631SLorenzo Bianconi .odr_table = { 1211a1c6d631SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 1212a1c6d631SLorenzo Bianconi .reg = { 1213a1c6d631SLorenzo Bianconi .addr = 0x10, 1214a1c6d631SLorenzo Bianconi .mask = GENMASK(3, 0), 1215a1c6d631SLorenzo Bianconi }, 1216a1c6d631SLorenzo Bianconi .odr_avl[0] = { 7500, 0x02 }, 1217a1c6d631SLorenzo Bianconi .odr_avl[1] = { 15000, 0x03 }, 1218a1c6d631SLorenzo Bianconi .odr_avl[2] = { 30000, 0x04 }, 1219a1c6d631SLorenzo Bianconi .odr_avl[3] = { 60000, 0x05 }, 1220a1c6d631SLorenzo Bianconi .odr_avl[4] = { 120000, 0x06 }, 1221a1c6d631SLorenzo Bianconi .odr_avl[5] = { 240000, 0x07 }, 1222a1c6d631SLorenzo Bianconi .odr_avl[6] = { 480000, 0x08 }, 1223a1c6d631SLorenzo Bianconi .odr_avl[7] = { 960000, 0x09 }, 1224a1c6d631SLorenzo Bianconi .odr_len = 8, 1225a1c6d631SLorenzo Bianconi }, 1226a1c6d631SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 1227a1c6d631SLorenzo Bianconi .reg = { 1228a1c6d631SLorenzo Bianconi .addr = 0x11, 1229a1c6d631SLorenzo Bianconi .mask = GENMASK(3, 0), 1230a1c6d631SLorenzo Bianconi }, 1231a1c6d631SLorenzo Bianconi .odr_avl[0] = { 7500, 0x02 }, 1232a1c6d631SLorenzo Bianconi .odr_avl[1] = { 15000, 0x03 }, 1233a1c6d631SLorenzo Bianconi .odr_avl[2] = { 30000, 0x04 }, 1234a1c6d631SLorenzo Bianconi .odr_avl[3] = { 60000, 0x05 }, 1235a1c6d631SLorenzo Bianconi .odr_avl[4] = { 120000, 0x06 }, 1236a1c6d631SLorenzo Bianconi .odr_avl[5] = { 240000, 0x07 }, 1237a1c6d631SLorenzo Bianconi .odr_avl[6] = { 480000, 0x08 }, 1238a1c6d631SLorenzo Bianconi .odr_avl[7] = { 960000, 0x09 }, 1239a1c6d631SLorenzo Bianconi .odr_len = 8, 1240a1c6d631SLorenzo Bianconi }, 1241a1c6d631SLorenzo Bianconi }, 1242a1c6d631SLorenzo Bianconi .fs_table = { 1243a1c6d631SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 1244a1c6d631SLorenzo Bianconi .reg = { 1245a1c6d631SLorenzo Bianconi .addr = 0x17, 1246a1c6d631SLorenzo Bianconi .mask = GENMASK(1, 0), 1247a1c6d631SLorenzo Bianconi }, 1248a1c6d631SLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 1249a1c6d631SLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x1 }, 1250a1c6d631SLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x2 }, 1251a1c6d631SLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x3 }, 1252a1c6d631SLorenzo Bianconi .fs_len = 4, 1253a1c6d631SLorenzo Bianconi }, 1254a1c6d631SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 1255a1c6d631SLorenzo Bianconi .reg = { 1256a1c6d631SLorenzo Bianconi .addr = 0x15, 1257a1c6d631SLorenzo Bianconi .mask = GENMASK(3, 0), 1258a1c6d631SLorenzo Bianconi }, 1259a1c6d631SLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x1 }, 1260a1c6d631SLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x2 }, 1261a1c6d631SLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x3 }, 1262a1c6d631SLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x4 }, 1263a1c6d631SLorenzo Bianconi .fs_len = 4, 1264a1c6d631SLorenzo Bianconi }, 1265a1c6d631SLorenzo Bianconi }, 1266a1c6d631SLorenzo Bianconi .irq_config = { 1267a1c6d631SLorenzo Bianconi .irq1 = { 1268a1c6d631SLorenzo Bianconi .addr = 0x0d, 1269a1c6d631SLorenzo Bianconi .mask = BIT(3), 1270a1c6d631SLorenzo Bianconi }, 1271a1c6d631SLorenzo Bianconi .irq2 = { 1272a1c6d631SLorenzo Bianconi .addr = 0x0e, 1273a1c6d631SLorenzo Bianconi .mask = BIT(3), 1274a1c6d631SLorenzo Bianconi }, 1275a1c6d631SLorenzo Bianconi .lir = { 1276a1c6d631SLorenzo Bianconi .addr = 0x56, 1277a1c6d631SLorenzo Bianconi .mask = BIT(0), 1278a1c6d631SLorenzo Bianconi }, 1279a1c6d631SLorenzo Bianconi .irq1_func = { 1280a1c6d631SLorenzo Bianconi .addr = 0x5e, 1281a1c6d631SLorenzo Bianconi .mask = BIT(5), 1282a1c6d631SLorenzo Bianconi }, 1283a1c6d631SLorenzo Bianconi .irq2_func = { 1284a1c6d631SLorenzo Bianconi .addr = 0x5f, 1285a1c6d631SLorenzo Bianconi .mask = BIT(5), 1286a1c6d631SLorenzo Bianconi }, 1287a1c6d631SLorenzo Bianconi .hla = { 1288a1c6d631SLorenzo Bianconi .addr = 0x03, 1289a1c6d631SLorenzo Bianconi .mask = BIT(4), 1290a1c6d631SLorenzo Bianconi }, 1291a1c6d631SLorenzo Bianconi .od = { 1292a1c6d631SLorenzo Bianconi .addr = 0x03, 1293a1c6d631SLorenzo Bianconi .mask = BIT(3), 1294a1c6d631SLorenzo Bianconi }, 1295a1c6d631SLorenzo Bianconi }, 1296a1c6d631SLorenzo Bianconi .batch = { 1297a1c6d631SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 1298a1c6d631SLorenzo Bianconi .addr = 0x09, 1299a1c6d631SLorenzo Bianconi .mask = GENMASK(3, 0), 1300a1c6d631SLorenzo Bianconi }, 1301a1c6d631SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 1302a1c6d631SLorenzo Bianconi .addr = 0x09, 1303a1c6d631SLorenzo Bianconi .mask = GENMASK(7, 4), 1304a1c6d631SLorenzo Bianconi }, 1305a1c6d631SLorenzo Bianconi }, 1306a1c6d631SLorenzo Bianconi .fifo_ops = { 1307a1c6d631SLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 1308a1c6d631SLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 1309a1c6d631SLorenzo Bianconi .fifo_th = { 1310a1c6d631SLorenzo Bianconi .addr = 0x07, 1311a1c6d631SLorenzo Bianconi .mask = GENMASK(7, 0), 1312a1c6d631SLorenzo Bianconi }, 1313a1c6d631SLorenzo Bianconi .fifo_diff = { 1314a1c6d631SLorenzo Bianconi .addr = 0x1b, 1315a1c6d631SLorenzo Bianconi .mask = GENMASK(8, 0), 1316a1c6d631SLorenzo Bianconi }, 1317a1c6d631SLorenzo Bianconi .max_size = 512, 1318a1c6d631SLorenzo Bianconi .th_wl = 1, 1319a1c6d631SLorenzo Bianconi }, 1320a1c6d631SLorenzo Bianconi .ts_settings = { 1321a1c6d631SLorenzo Bianconi .timer_en = { 1322a1c6d631SLorenzo Bianconi .addr = 0x50, 1323a1c6d631SLorenzo Bianconi .mask = BIT(6), 1324a1c6d631SLorenzo Bianconi }, 1325a1c6d631SLorenzo Bianconi .decimator = { 1326a1c6d631SLorenzo Bianconi .addr = 0x0a, 1327a1c6d631SLorenzo Bianconi .mask = GENMASK(7, 6), 1328a1c6d631SLorenzo Bianconi }, 1329a1c6d631SLorenzo Bianconi .freq_fine = 0x4f, 1330a1c6d631SLorenzo Bianconi }, 1331a1c6d631SLorenzo Bianconi .shub_settings = { 1332a1c6d631SLorenzo Bianconi .page_mux = { 1333a1c6d631SLorenzo Bianconi .addr = 0x01, 1334a1c6d631SLorenzo Bianconi .mask = BIT(6), 1335a1c6d631SLorenzo Bianconi }, 1336a1c6d631SLorenzo Bianconi .master_en = { 1337a1c6d631SLorenzo Bianconi .sec_page = true, 1338a1c6d631SLorenzo Bianconi .addr = 0x14, 1339a1c6d631SLorenzo Bianconi .mask = BIT(2), 1340a1c6d631SLorenzo Bianconi }, 1341a1c6d631SLorenzo Bianconi .pullup_en = { 1342a1c6d631SLorenzo Bianconi .addr = 0x03, 1343a1c6d631SLorenzo Bianconi .mask = BIT(6), 1344a1c6d631SLorenzo Bianconi }, 1345a1c6d631SLorenzo Bianconi .aux_sens = { 1346a1c6d631SLorenzo Bianconi .addr = 0x14, 1347a1c6d631SLorenzo Bianconi .mask = GENMASK(1, 0), 1348a1c6d631SLorenzo Bianconi }, 1349a1c6d631SLorenzo Bianconi .wr_once = { 1350a1c6d631SLorenzo Bianconi .addr = 0x14, 1351a1c6d631SLorenzo Bianconi .mask = BIT(6), 1352a1c6d631SLorenzo Bianconi }, 1353a1c6d631SLorenzo Bianconi .num_ext_dev = 3, 1354a1c6d631SLorenzo Bianconi .shub_out = { 1355a1c6d631SLorenzo Bianconi .sec_page = true, 1356a1c6d631SLorenzo Bianconi .addr = 0x02, 1357a1c6d631SLorenzo Bianconi }, 1358a1c6d631SLorenzo Bianconi .slv0_addr = 0x15, 1359a1c6d631SLorenzo Bianconi .dw_slv0_addr = 0x21, 1360a1c6d631SLorenzo Bianconi .batch_en = BIT(3), 1361a1c6d631SLorenzo Bianconi }, 1362a1c6d631SLorenzo Bianconi .event_settings = { 1363a1c6d631SLorenzo Bianconi .enable_reg = { 1364a1c6d631SLorenzo Bianconi .addr = 0x50, 1365a1c6d631SLorenzo Bianconi .mask = BIT(7), 1366a1c6d631SLorenzo Bianconi }, 1367a1c6d631SLorenzo Bianconi .wakeup_reg = { 1368a1c6d631SLorenzo Bianconi .addr = 0x5b, 1369a1c6d631SLorenzo Bianconi .mask = GENMASK(5, 0), 1370a1c6d631SLorenzo Bianconi }, 1371a1c6d631SLorenzo Bianconi .wakeup_src_reg = 0x45, 1372a1c6d631SLorenzo Bianconi .wakeup_src_status_mask = BIT(3), 1373a1c6d631SLorenzo Bianconi .wakeup_src_z_mask = BIT(0), 1374a1c6d631SLorenzo Bianconi .wakeup_src_y_mask = BIT(1), 1375a1c6d631SLorenzo Bianconi .wakeup_src_x_mask = BIT(2), 1376a1c6d631SLorenzo Bianconi }, 1377a1c6d631SLorenzo Bianconi }, 1378*f35e1ee9SLorenzo Bianconi { 1379*f35e1ee9SLorenzo Bianconi .reset = { 1380*f35e1ee9SLorenzo Bianconi .addr = 0x12, 1381*f35e1ee9SLorenzo Bianconi .mask = BIT(0), 1382*f35e1ee9SLorenzo Bianconi }, 1383*f35e1ee9SLorenzo Bianconi .boot = { 1384*f35e1ee9SLorenzo Bianconi .addr = 0x12, 1385*f35e1ee9SLorenzo Bianconi .mask = BIT(7), 1386*f35e1ee9SLorenzo Bianconi }, 1387*f35e1ee9SLorenzo Bianconi .bdu = { 1388*f35e1ee9SLorenzo Bianconi .addr = 0x12, 1389*f35e1ee9SLorenzo Bianconi .mask = BIT(6), 1390*f35e1ee9SLorenzo Bianconi }, 1391*f35e1ee9SLorenzo Bianconi .id = { 1392*f35e1ee9SLorenzo Bianconi { 1393*f35e1ee9SLorenzo Bianconi .hw_id = ST_LSM6DSO16IS_ID, 1394*f35e1ee9SLorenzo Bianconi .name = ST_LSM6DSO16IS_DEV_NAME, 1395*f35e1ee9SLorenzo Bianconi .wai = 0x22, 1396*f35e1ee9SLorenzo Bianconi }, 1397*f35e1ee9SLorenzo Bianconi }, 1398*f35e1ee9SLorenzo Bianconi .channels = { 1399*f35e1ee9SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 1400*f35e1ee9SLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 1401*f35e1ee9SLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 1402*f35e1ee9SLorenzo Bianconi }, 1403*f35e1ee9SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 1404*f35e1ee9SLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 1405*f35e1ee9SLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 1406*f35e1ee9SLorenzo Bianconi }, 1407*f35e1ee9SLorenzo Bianconi }, 1408*f35e1ee9SLorenzo Bianconi .odr_table = { 1409*f35e1ee9SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 1410*f35e1ee9SLorenzo Bianconi .reg = { 1411*f35e1ee9SLorenzo Bianconi .addr = 0x10, 1412*f35e1ee9SLorenzo Bianconi .mask = GENMASK(7, 4), 1413*f35e1ee9SLorenzo Bianconi }, 1414*f35e1ee9SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 1415*f35e1ee9SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 1416*f35e1ee9SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 1417*f35e1ee9SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 1418*f35e1ee9SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 1419*f35e1ee9SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 1420*f35e1ee9SLorenzo Bianconi .odr_avl[6] = { 833000, 0x07 }, 1421*f35e1ee9SLorenzo Bianconi .odr_len = 7, 1422*f35e1ee9SLorenzo Bianconi }, 1423*f35e1ee9SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 1424*f35e1ee9SLorenzo Bianconi .reg = { 1425*f35e1ee9SLorenzo Bianconi .addr = 0x11, 1426*f35e1ee9SLorenzo Bianconi .mask = GENMASK(7, 4), 1427*f35e1ee9SLorenzo Bianconi }, 1428*f35e1ee9SLorenzo Bianconi .odr_avl[0] = { 12500, 0x01 }, 1429*f35e1ee9SLorenzo Bianconi .odr_avl[1] = { 26000, 0x02 }, 1430*f35e1ee9SLorenzo Bianconi .odr_avl[2] = { 52000, 0x03 }, 1431*f35e1ee9SLorenzo Bianconi .odr_avl[3] = { 104000, 0x04 }, 1432*f35e1ee9SLorenzo Bianconi .odr_avl[4] = { 208000, 0x05 }, 1433*f35e1ee9SLorenzo Bianconi .odr_avl[5] = { 416000, 0x06 }, 1434*f35e1ee9SLorenzo Bianconi .odr_avl[6] = { 833000, 0x07 }, 1435*f35e1ee9SLorenzo Bianconi .odr_len = 7, 1436*f35e1ee9SLorenzo Bianconi }, 1437*f35e1ee9SLorenzo Bianconi }, 1438*f35e1ee9SLorenzo Bianconi .fs_table = { 1439*f35e1ee9SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 1440*f35e1ee9SLorenzo Bianconi .reg = { 1441*f35e1ee9SLorenzo Bianconi .addr = 0x10, 1442*f35e1ee9SLorenzo Bianconi .mask = GENMASK(3, 2), 1443*f35e1ee9SLorenzo Bianconi }, 1444*f35e1ee9SLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, 1445*f35e1ee9SLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, 1446*f35e1ee9SLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, 1447*f35e1ee9SLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, 1448*f35e1ee9SLorenzo Bianconi .fs_len = 4, 1449*f35e1ee9SLorenzo Bianconi }, 1450*f35e1ee9SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 1451*f35e1ee9SLorenzo Bianconi .reg = { 1452*f35e1ee9SLorenzo Bianconi .addr = 0x11, 1453*f35e1ee9SLorenzo Bianconi .mask = GENMASK(3, 2), 1454*f35e1ee9SLorenzo Bianconi }, 1455*f35e1ee9SLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, 1456*f35e1ee9SLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, 1457*f35e1ee9SLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, 1458*f35e1ee9SLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, 1459*f35e1ee9SLorenzo Bianconi .fs_len = 4, 1460*f35e1ee9SLorenzo Bianconi }, 1461*f35e1ee9SLorenzo Bianconi }, 1462*f35e1ee9SLorenzo Bianconi .irq_config = { 1463*f35e1ee9SLorenzo Bianconi .hla = { 1464*f35e1ee9SLorenzo Bianconi .addr = 0x12, 1465*f35e1ee9SLorenzo Bianconi .mask = BIT(5), 1466*f35e1ee9SLorenzo Bianconi }, 1467*f35e1ee9SLorenzo Bianconi .od = { 1468*f35e1ee9SLorenzo Bianconi .addr = 0x12, 1469*f35e1ee9SLorenzo Bianconi .mask = BIT(4), 1470*f35e1ee9SLorenzo Bianconi }, 1471*f35e1ee9SLorenzo Bianconi }, 1472*f35e1ee9SLorenzo Bianconi .shub_settings = { 1473*f35e1ee9SLorenzo Bianconi .page_mux = { 1474*f35e1ee9SLorenzo Bianconi .addr = 0x01, 1475*f35e1ee9SLorenzo Bianconi .mask = BIT(6), 1476*f35e1ee9SLorenzo Bianconi }, 1477*f35e1ee9SLorenzo Bianconi .master_en = { 1478*f35e1ee9SLorenzo Bianconi .sec_page = true, 1479*f35e1ee9SLorenzo Bianconi .addr = 0x14, 1480*f35e1ee9SLorenzo Bianconi .mask = BIT(2), 1481*f35e1ee9SLorenzo Bianconi }, 1482*f35e1ee9SLorenzo Bianconi .pullup_en = { 1483*f35e1ee9SLorenzo Bianconi .sec_page = true, 1484*f35e1ee9SLorenzo Bianconi .addr = 0x14, 1485*f35e1ee9SLorenzo Bianconi .mask = BIT(3), 1486*f35e1ee9SLorenzo Bianconi }, 1487*f35e1ee9SLorenzo Bianconi .aux_sens = { 1488*f35e1ee9SLorenzo Bianconi .addr = 0x14, 1489*f35e1ee9SLorenzo Bianconi .mask = GENMASK(1, 0), 1490*f35e1ee9SLorenzo Bianconi }, 1491*f35e1ee9SLorenzo Bianconi .wr_once = { 1492*f35e1ee9SLorenzo Bianconi .addr = 0x14, 1493*f35e1ee9SLorenzo Bianconi .mask = BIT(6), 1494*f35e1ee9SLorenzo Bianconi }, 1495*f35e1ee9SLorenzo Bianconi .num_ext_dev = 3, 1496*f35e1ee9SLorenzo Bianconi .shub_out = { 1497*f35e1ee9SLorenzo Bianconi .sec_page = true, 1498*f35e1ee9SLorenzo Bianconi .addr = 0x02, 1499*f35e1ee9SLorenzo Bianconi }, 1500*f35e1ee9SLorenzo Bianconi .slv0_addr = 0x15, 1501*f35e1ee9SLorenzo Bianconi .dw_slv0_addr = 0x21, 1502*f35e1ee9SLorenzo Bianconi }, 1503*f35e1ee9SLorenzo Bianconi }, 1504290a6ce1SLorenzo Bianconi }; 1505290a6ce1SLorenzo Bianconi 1506c91c1c84SLorenzo Bianconi int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable) 1507c91c1c84SLorenzo Bianconi { 1508c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 1509c91c1c84SLorenzo Bianconi unsigned int data; 1510c91c1c84SLorenzo Bianconi int err; 1511c91c1c84SLorenzo Bianconi 1512c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 1513c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask); 1514c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr, 1515c91c1c84SLorenzo Bianconi hub_settings->page_mux.mask, data); 1516c91c1c84SLorenzo Bianconi usleep_range(100, 150); 1517c91c1c84SLorenzo Bianconi 1518c91c1c84SLorenzo Bianconi return err; 1519c91c1c84SLorenzo Bianconi } 1520c91c1c84SLorenzo Bianconi 152181956a93SLorenzo Bianconi static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id, 152281956a93SLorenzo Bianconi const char **name) 1523290a6ce1SLorenzo Bianconi { 152451a8b707SLorenzo Bianconi int err, i, j, data; 1525290a6ce1SLorenzo Bianconi 1526290a6ce1SLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) { 1527d068e4a0SLorenzo Bianconi for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) { 1528fb4fbc89SStephan Gerhold if (st_lsm6dsx_sensor_settings[i].id[j].name && 1529fb4fbc89SStephan Gerhold id == st_lsm6dsx_sensor_settings[i].id[j].hw_id) 1530d068e4a0SLorenzo Bianconi break; 1531d068e4a0SLorenzo Bianconi } 1532d068e4a0SLorenzo Bianconi if (j < ST_LSM6DSX_MAX_ID) 1533290a6ce1SLorenzo Bianconi break; 1534290a6ce1SLorenzo Bianconi } 1535290a6ce1SLorenzo Bianconi 1536290a6ce1SLorenzo Bianconi if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) { 1537290a6ce1SLorenzo Bianconi dev_err(hw->dev, "unsupported hw id [%02x]\n", id); 1538290a6ce1SLorenzo Bianconi return -ENODEV; 1539290a6ce1SLorenzo Bianconi } 1540290a6ce1SLorenzo Bianconi 154151a8b707SLorenzo Bianconi err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data); 1542290a6ce1SLorenzo Bianconi if (err < 0) { 1543290a6ce1SLorenzo Bianconi dev_err(hw->dev, "failed to read whoami register\n"); 1544290a6ce1SLorenzo Bianconi return err; 1545290a6ce1SLorenzo Bianconi } 1546290a6ce1SLorenzo Bianconi 154798c3544aSLorenzo Bianconi if (data != st_lsm6dsx_sensor_settings[i].id[j].wai) { 1548290a6ce1SLorenzo Bianconi dev_err(hw->dev, "unsupported whoami [%02x]\n", data); 1549290a6ce1SLorenzo Bianconi return -ENODEV; 1550290a6ce1SLorenzo Bianconi } 1551290a6ce1SLorenzo Bianconi 155281956a93SLorenzo Bianconi *name = st_lsm6dsx_sensor_settings[i].id[j].name; 1553290a6ce1SLorenzo Bianconi hw->settings = &st_lsm6dsx_sensor_settings[i]; 1554290a6ce1SLorenzo Bianconi 1555290a6ce1SLorenzo Bianconi return 0; 1556290a6ce1SLorenzo Bianconi } 1557290a6ce1SLorenzo Bianconi 1558290a6ce1SLorenzo Bianconi static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, 1559290a6ce1SLorenzo Bianconi u32 gain) 1560290a6ce1SLorenzo Bianconi { 1561640aca3fSLorenzo Bianconi const struct st_lsm6dsx_fs_table_entry *fs_table; 1562739aff87SLorenzo Bianconi unsigned int data; 1563290a6ce1SLorenzo Bianconi int i, err; 1564290a6ce1SLorenzo Bianconi 1565640aca3fSLorenzo Bianconi fs_table = &sensor->hw->settings->fs_table[sensor->id]; 156685ae3aeeSLorenzo Bianconi for (i = 0; i < fs_table->fs_len; i++) { 1567640aca3fSLorenzo Bianconi if (fs_table->fs_avl[i].gain == gain) 1568290a6ce1SLorenzo Bianconi break; 156985ae3aeeSLorenzo Bianconi } 1570290a6ce1SLorenzo Bianconi 157185ae3aeeSLorenzo Bianconi if (i == fs_table->fs_len) 1572290a6ce1SLorenzo Bianconi return -EINVAL; 1573290a6ce1SLorenzo Bianconi 1574640aca3fSLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val, 1575640aca3fSLorenzo Bianconi fs_table->reg.mask); 1576640aca3fSLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr, 1577640aca3fSLorenzo Bianconi fs_table->reg.mask, data); 1578290a6ce1SLorenzo Bianconi if (err < 0) 1579290a6ce1SLorenzo Bianconi return err; 1580290a6ce1SLorenzo Bianconi 1581290a6ce1SLorenzo Bianconi sensor->gain = gain; 1582290a6ce1SLorenzo Bianconi 1583290a6ce1SLorenzo Bianconi return 0; 1584290a6ce1SLorenzo Bianconi } 1585290a6ce1SLorenzo Bianconi 1586f8710f03SLorenzo Bianconi int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u32 odr, u8 *val) 1587290a6ce1SLorenzo Bianconi { 158840dd7343SLorenzo Bianconi const struct st_lsm6dsx_odr_table_entry *odr_table; 15892ccc1503SLorenzo Bianconi int i; 1590290a6ce1SLorenzo Bianconi 159140dd7343SLorenzo Bianconi odr_table = &sensor->hw->settings->odr_table[sensor->id]; 159259af4e20SLorenzo Bianconi for (i = 0; i < odr_table->odr_len; i++) { 15936ffb55e5SLorenzo Bianconi /* 15946ffb55e5SLorenzo Bianconi * ext devices can run at different odr respect to 15956ffb55e5SLorenzo Bianconi * accel sensor 15966ffb55e5SLorenzo Bianconi */ 1597f8710f03SLorenzo Bianconi if (odr_table->odr_avl[i].milli_hz >= odr) 1598290a6ce1SLorenzo Bianconi break; 159959af4e20SLorenzo Bianconi } 1600290a6ce1SLorenzo Bianconi 160159af4e20SLorenzo Bianconi if (i == odr_table->odr_len) 1602290a6ce1SLorenzo Bianconi return -EINVAL; 1603290a6ce1SLorenzo Bianconi 160440dd7343SLorenzo Bianconi *val = odr_table->odr_avl[i].val; 1605f8710f03SLorenzo Bianconi return odr_table->odr_avl[i].milli_hz; 1606290a6ce1SLorenzo Bianconi } 1607290a6ce1SLorenzo Bianconi 1608f8710f03SLorenzo Bianconi static int 1609f8710f03SLorenzo Bianconi st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u32 odr, 16106ffb55e5SLorenzo Bianconi enum st_lsm6dsx_sensor_id id) 16112ccc1503SLorenzo Bianconi { 16126ffb55e5SLorenzo Bianconi struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]); 16136ffb55e5SLorenzo Bianconi 16146ffb55e5SLorenzo Bianconi if (odr > 0) { 16156ffb55e5SLorenzo Bianconi if (hw->enable_mask & BIT(id)) 1616f8710f03SLorenzo Bianconi return max_t(u32, ref->odr, odr); 16176ffb55e5SLorenzo Bianconi else 16186ffb55e5SLorenzo Bianconi return odr; 16196ffb55e5SLorenzo Bianconi } else { 16206ffb55e5SLorenzo Bianconi return (hw->enable_mask & BIT(id)) ? ref->odr : 0; 16216ffb55e5SLorenzo Bianconi } 16226ffb55e5SLorenzo Bianconi } 16236ffb55e5SLorenzo Bianconi 1624f8710f03SLorenzo Bianconi static int 1625f8710f03SLorenzo Bianconi st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u32 req_odr) 16266ffb55e5SLorenzo Bianconi { 16276ffb55e5SLorenzo Bianconi struct st_lsm6dsx_sensor *ref_sensor = sensor; 162851a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 162951a8b707SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 1630739aff87SLorenzo Bianconi unsigned int data; 16316ffb55e5SLorenzo Bianconi u8 val = 0; 16322ccc1503SLorenzo Bianconi int err; 16332ccc1503SLorenzo Bianconi 16346ffb55e5SLorenzo Bianconi switch (sensor->id) { 163594be878cSTeng Qi case ST_LSM6DSX_ID_GYRO: 163694be878cSTeng Qi break; 16376ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT0: 16386ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT1: 16396ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT2: 16406ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_ACC: { 1641f8710f03SLorenzo Bianconi u32 odr; 16426ffb55e5SLorenzo Bianconi int i; 16436ffb55e5SLorenzo Bianconi 16446ffb55e5SLorenzo Bianconi /* 16456ffb55e5SLorenzo Bianconi * i2c embedded controller relies on the accelerometer sensor as 16466ffb55e5SLorenzo Bianconi * bus read/write trigger so we need to enable accel device 16476ffb55e5SLorenzo Bianconi * at odr = max(accel_odr, ext_odr) in order to properly 16486ffb55e5SLorenzo Bianconi * communicate with i2c slave devices 16496ffb55e5SLorenzo Bianconi */ 16506ffb55e5SLorenzo Bianconi ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); 16516ffb55e5SLorenzo Bianconi for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) { 16526ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i] || i == sensor->id) 16536ffb55e5SLorenzo Bianconi continue; 16546ffb55e5SLorenzo Bianconi 16556ffb55e5SLorenzo Bianconi odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i); 16566ffb55e5SLorenzo Bianconi if (odr != req_odr) 16576ffb55e5SLorenzo Bianconi /* device already configured */ 16586ffb55e5SLorenzo Bianconi return 0; 16596ffb55e5SLorenzo Bianconi } 16606ffb55e5SLorenzo Bianconi break; 16616ffb55e5SLorenzo Bianconi } 166294be878cSTeng Qi default: /* should never occur */ 166394be878cSTeng Qi return -EINVAL; 16646ffb55e5SLorenzo Bianconi } 16656ffb55e5SLorenzo Bianconi 16666ffb55e5SLorenzo Bianconi if (req_odr > 0) { 16676ffb55e5SLorenzo Bianconi err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val); 16682ccc1503SLorenzo Bianconi if (err < 0) 16692ccc1503SLorenzo Bianconi return err; 16706ffb55e5SLorenzo Bianconi } 16712ccc1503SLorenzo Bianconi 167240dd7343SLorenzo Bianconi reg = &hw->settings->odr_table[ref_sensor->id].reg; 1673739aff87SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask); 1674739aff87SLorenzo Bianconi return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data); 16752ccc1503SLorenzo Bianconi } 16762ccc1503SLorenzo Bianconi 1677bd41c445SLorenzo Bianconi static int 1678bd41c445SLorenzo Bianconi __st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, 167917750443SLorenzo Bianconi bool enable) 1680290a6ce1SLorenzo Bianconi { 168151a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1682f8710f03SLorenzo Bianconi u32 odr = enable ? sensor->odr : 0; 1683290a6ce1SLorenzo Bianconi int err; 1684290a6ce1SLorenzo Bianconi 168517750443SLorenzo Bianconi err = st_lsm6dsx_set_odr(sensor, odr); 1686290a6ce1SLorenzo Bianconi if (err < 0) 1687290a6ce1SLorenzo Bianconi return err; 1688290a6ce1SLorenzo Bianconi 168917750443SLorenzo Bianconi if (enable) 169017750443SLorenzo Bianconi hw->enable_mask |= BIT(sensor->id); 169117750443SLorenzo Bianconi else 169217750443SLorenzo Bianconi hw->enable_mask &= ~BIT(sensor->id); 1693290a6ce1SLorenzo Bianconi 1694290a6ce1SLorenzo Bianconi return 0; 1695290a6ce1SLorenzo Bianconi } 1696290a6ce1SLorenzo Bianconi 1697bd41c445SLorenzo Bianconi static int 1698bd41c445SLorenzo Bianconi st_lsm6dsx_check_events(struct st_lsm6dsx_sensor *sensor, bool enable) 1699bd41c445SLorenzo Bianconi { 1700bd41c445SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1701bd41c445SLorenzo Bianconi 1702bd41c445SLorenzo Bianconi if (sensor->id == ST_LSM6DSX_ID_GYRO || enable) 1703bd41c445SLorenzo Bianconi return 0; 1704bd41c445SLorenzo Bianconi 1705bd41c445SLorenzo Bianconi return hw->enable_event; 1706bd41c445SLorenzo Bianconi } 1707bd41c445SLorenzo Bianconi 1708bd41c445SLorenzo Bianconi int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, 1709bd41c445SLorenzo Bianconi bool enable) 1710bd41c445SLorenzo Bianconi { 1711bd41c445SLorenzo Bianconi if (st_lsm6dsx_check_events(sensor, enable)) 1712bd41c445SLorenzo Bianconi return 0; 1713bd41c445SLorenzo Bianconi 1714bd41c445SLorenzo Bianconi return __st_lsm6dsx_sensor_set_enable(sensor, enable); 1715bd41c445SLorenzo Bianconi } 1716bd41c445SLorenzo Bianconi 1717290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, 1718290a6ce1SLorenzo Bianconi u8 addr, int *val) 1719290a6ce1SLorenzo Bianconi { 172051a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1721290a6ce1SLorenzo Bianconi int err, delay; 1722290a6ce1SLorenzo Bianconi __le16 data; 1723290a6ce1SLorenzo Bianconi 172417750443SLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, true); 1725290a6ce1SLorenzo Bianconi if (err < 0) 1726290a6ce1SLorenzo Bianconi return err; 1727290a6ce1SLorenzo Bianconi 1728ea85bf90SLorenzo Bianconi /* 1729ea85bf90SLorenzo Bianconi * we need to wait for sensor settling time before 1730ea85bf90SLorenzo Bianconi * reading data in order to avoid corrupted samples 1731ea85bf90SLorenzo Bianconi */ 1732f8710f03SLorenzo Bianconi delay = 1000000000 / sensor->odr; 1733ea85bf90SLorenzo Bianconi usleep_range(3 * delay, 4 * delay); 1734290a6ce1SLorenzo Bianconi 1735739aff87SLorenzo Bianconi err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data)); 1736290a6ce1SLorenzo Bianconi if (err < 0) 1737290a6ce1SLorenzo Bianconi return err; 1738290a6ce1SLorenzo Bianconi 1739a2dd9bd9SLorenzo Bianconi if (!hw->enable_event) { 1740a2dd9bd9SLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, false); 1741a2dd9bd9SLorenzo Bianconi if (err < 0) 1742a2dd9bd9SLorenzo Bianconi return err; 1743a2dd9bd9SLorenzo Bianconi } 1744290a6ce1SLorenzo Bianconi 17457b9ebe42SLorenzo Bianconi *val = (s16)le16_to_cpu(data); 1746290a6ce1SLorenzo Bianconi 1747290a6ce1SLorenzo Bianconi return IIO_VAL_INT; 1748290a6ce1SLorenzo Bianconi } 1749290a6ce1SLorenzo Bianconi 1750290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev, 1751290a6ce1SLorenzo Bianconi struct iio_chan_spec const *ch, 1752290a6ce1SLorenzo Bianconi int *val, int *val2, long mask) 1753290a6ce1SLorenzo Bianconi { 1754290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1755290a6ce1SLorenzo Bianconi int ret; 1756290a6ce1SLorenzo Bianconi 1757290a6ce1SLorenzo Bianconi switch (mask) { 1758290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_RAW: 1759290a6ce1SLorenzo Bianconi ret = iio_device_claim_direct_mode(iio_dev); 1760290a6ce1SLorenzo Bianconi if (ret) 1761290a6ce1SLorenzo Bianconi break; 1762290a6ce1SLorenzo Bianconi 1763290a6ce1SLorenzo Bianconi ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val); 1764290a6ce1SLorenzo Bianconi iio_device_release_direct_mode(iio_dev); 1765290a6ce1SLorenzo Bianconi break; 1766290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SAMP_FREQ: 1767f8710f03SLorenzo Bianconi *val = sensor->odr / 1000; 1768f8710f03SLorenzo Bianconi *val2 = (sensor->odr % 1000) * 1000; 1769f8710f03SLorenzo Bianconi ret = IIO_VAL_INT_PLUS_MICRO; 1770290a6ce1SLorenzo Bianconi break; 1771290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SCALE: 1772290a6ce1SLorenzo Bianconi *val = 0; 1773290a6ce1SLorenzo Bianconi *val2 = sensor->gain; 177444a76de8SMario Tesi ret = IIO_VAL_INT_PLUS_NANO; 1775290a6ce1SLorenzo Bianconi break; 1776290a6ce1SLorenzo Bianconi default: 1777290a6ce1SLorenzo Bianconi ret = -EINVAL; 1778290a6ce1SLorenzo Bianconi break; 1779290a6ce1SLorenzo Bianconi } 1780290a6ce1SLorenzo Bianconi 1781290a6ce1SLorenzo Bianconi return ret; 1782290a6ce1SLorenzo Bianconi } 1783290a6ce1SLorenzo Bianconi 1784290a6ce1SLorenzo Bianconi static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev, 1785290a6ce1SLorenzo Bianconi struct iio_chan_spec const *chan, 1786290a6ce1SLorenzo Bianconi int val, int val2, long mask) 1787290a6ce1SLorenzo Bianconi { 1788290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1789290a6ce1SLorenzo Bianconi int err; 1790290a6ce1SLorenzo Bianconi 1791290a6ce1SLorenzo Bianconi err = iio_device_claim_direct_mode(iio_dev); 1792290a6ce1SLorenzo Bianconi if (err) 1793290a6ce1SLorenzo Bianconi return err; 1794290a6ce1SLorenzo Bianconi 1795290a6ce1SLorenzo Bianconi switch (mask) { 1796290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SCALE: 1797290a6ce1SLorenzo Bianconi err = st_lsm6dsx_set_full_scale(sensor, val2); 1798290a6ce1SLorenzo Bianconi break; 17992ccc1503SLorenzo Bianconi case IIO_CHAN_INFO_SAMP_FREQ: { 18002ccc1503SLorenzo Bianconi u8 data; 18012ccc1503SLorenzo Bianconi 1802f8710f03SLorenzo Bianconi val = val * 1000 + val2 / 1000; 1803fc3f6ad7SLorenzo Bianconi val = st_lsm6dsx_check_odr(sensor, val, &data); 1804fc3f6ad7SLorenzo Bianconi if (val < 0) 1805fc3f6ad7SLorenzo Bianconi err = val; 1806fc3f6ad7SLorenzo Bianconi else 18075e3c3e33SLorenzo Bianconi sensor->odr = val; 1808290a6ce1SLorenzo Bianconi break; 18092ccc1503SLorenzo Bianconi } 1810290a6ce1SLorenzo Bianconi default: 1811290a6ce1SLorenzo Bianconi err = -EINVAL; 1812290a6ce1SLorenzo Bianconi break; 1813290a6ce1SLorenzo Bianconi } 1814290a6ce1SLorenzo Bianconi 1815290a6ce1SLorenzo Bianconi iio_device_release_direct_mode(iio_dev); 1816290a6ce1SLorenzo Bianconi 1817290a6ce1SLorenzo Bianconi return err; 1818290a6ce1SLorenzo Bianconi } 1819290a6ce1SLorenzo Bianconi 1820b5969abfSSean Nyekjaer static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state) 1821b5969abfSSean Nyekjaer { 182284b2e7c3SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 182304ca37d5SLorenzo Bianconi unsigned int data; 1824b5969abfSSean Nyekjaer int err; 1825b5969abfSSean Nyekjaer 18267e906103SLorenzo Bianconi if (!hw->settings->irq_config.irq1_func.addr) 1827b5969abfSSean Nyekjaer return -ENOTSUPP; 1828b5969abfSSean Nyekjaer 182984b2e7c3SLorenzo Bianconi reg = &hw->settings->event_settings.enable_reg; 183084b2e7c3SLorenzo Bianconi if (reg->addr) { 183104ca37d5SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(state, reg->mask); 183204ca37d5SLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(hw, reg->addr, 183304ca37d5SLorenzo Bianconi reg->mask, data); 1834b5969abfSSean Nyekjaer if (err < 0) 1835b5969abfSSean Nyekjaer return err; 183684b2e7c3SLorenzo Bianconi } 1837b5969abfSSean Nyekjaer 1838b5969abfSSean Nyekjaer /* Enable wakeup interrupt */ 183904ca37d5SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(state, hw->irq_routing->mask); 184004ca37d5SLorenzo Bianconi return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing->addr, 184104ca37d5SLorenzo Bianconi hw->irq_routing->mask, data); 1842b5969abfSSean Nyekjaer } 1843b5969abfSSean Nyekjaer 1844b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event(struct iio_dev *iio_dev, 1845b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1846b5969abfSSean Nyekjaer enum iio_event_type type, 1847b5969abfSSean Nyekjaer enum iio_event_direction dir, 1848b5969abfSSean Nyekjaer enum iio_event_info info, 1849b5969abfSSean Nyekjaer int *val, int *val2) 1850b5969abfSSean Nyekjaer { 1851b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1852b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 1853b5969abfSSean Nyekjaer 1854b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1855b5969abfSSean Nyekjaer return -EINVAL; 1856b5969abfSSean Nyekjaer 1857b5969abfSSean Nyekjaer *val2 = 0; 1858b5969abfSSean Nyekjaer *val = hw->event_threshold; 1859b5969abfSSean Nyekjaer 1860b5969abfSSean Nyekjaer return IIO_VAL_INT; 1861b5969abfSSean Nyekjaer } 1862b5969abfSSean Nyekjaer 1863b307f495SLorenzo Bianconi static int 1864b307f495SLorenzo Bianconi st_lsm6dsx_write_event(struct iio_dev *iio_dev, 1865b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1866b5969abfSSean Nyekjaer enum iio_event_type type, 1867b5969abfSSean Nyekjaer enum iio_event_direction dir, 1868b5969abfSSean Nyekjaer enum iio_event_info info, 1869b5969abfSSean Nyekjaer int val, int val2) 1870b5969abfSSean Nyekjaer { 1871b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1872b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 187304ca37d5SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 187404ca37d5SLorenzo Bianconi unsigned int data; 1875b5969abfSSean Nyekjaer int err; 1876b5969abfSSean Nyekjaer 1877b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1878b5969abfSSean Nyekjaer return -EINVAL; 1879b5969abfSSean Nyekjaer 1880b5969abfSSean Nyekjaer if (val < 0 || val > 31) 1881b5969abfSSean Nyekjaer return -EINVAL; 1882b5969abfSSean Nyekjaer 188304ca37d5SLorenzo Bianconi reg = &hw->settings->event_settings.wakeup_reg; 188404ca37d5SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask); 188504ca37d5SLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(hw, reg->addr, 188604ca37d5SLorenzo Bianconi reg->mask, data); 188704ca37d5SLorenzo Bianconi if (err < 0) 1888b5969abfSSean Nyekjaer return -EINVAL; 1889b5969abfSSean Nyekjaer 1890b5969abfSSean Nyekjaer hw->event_threshold = val; 1891b5969abfSSean Nyekjaer 1892b5969abfSSean Nyekjaer return 0; 1893b5969abfSSean Nyekjaer } 1894b5969abfSSean Nyekjaer 1895b307f495SLorenzo Bianconi static int 1896b307f495SLorenzo Bianconi st_lsm6dsx_read_event_config(struct iio_dev *iio_dev, 1897b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1898b5969abfSSean Nyekjaer enum iio_event_type type, 1899b5969abfSSean Nyekjaer enum iio_event_direction dir) 1900b5969abfSSean Nyekjaer { 1901b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1902b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 1903b5969abfSSean Nyekjaer 1904b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1905b5969abfSSean Nyekjaer return -EINVAL; 1906b5969abfSSean Nyekjaer 19071aabad1fSSean Nyekjaer return !!(hw->enable_event & BIT(chan->channel2)); 1908b5969abfSSean Nyekjaer } 1909b5969abfSSean Nyekjaer 1910b307f495SLorenzo Bianconi static int 1911b307f495SLorenzo Bianconi st_lsm6dsx_write_event_config(struct iio_dev *iio_dev, 1912b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1913b5969abfSSean Nyekjaer enum iio_event_type type, 1914b307f495SLorenzo Bianconi enum iio_event_direction dir, int state) 1915b5969abfSSean Nyekjaer { 1916b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1917b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 19181aabad1fSSean Nyekjaer u8 enable_event; 1919bd41c445SLorenzo Bianconi int err; 1920b5969abfSSean Nyekjaer 1921b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1922b5969abfSSean Nyekjaer return -EINVAL; 1923b5969abfSSean Nyekjaer 19241aabad1fSSean Nyekjaer if (state) { 19251aabad1fSSean Nyekjaer enable_event = hw->enable_event | BIT(chan->channel2); 19261aabad1fSSean Nyekjaer 1927b5969abfSSean Nyekjaer /* do not enable events if they are already enabled */ 19281aabad1fSSean Nyekjaer if (hw->enable_event) 19291aabad1fSSean Nyekjaer goto out; 19301aabad1fSSean Nyekjaer } else { 19311aabad1fSSean Nyekjaer enable_event = hw->enable_event & ~BIT(chan->channel2); 19321aabad1fSSean Nyekjaer 19331aabad1fSSean Nyekjaer /* only turn off sensor if no events is enabled */ 19341aabad1fSSean Nyekjaer if (enable_event) 19351aabad1fSSean Nyekjaer goto out; 19361aabad1fSSean Nyekjaer } 19371aabad1fSSean Nyekjaer 19381aabad1fSSean Nyekjaer /* stop here if no changes have been made */ 19391aabad1fSSean Nyekjaer if (hw->enable_event == enable_event) 1940b5969abfSSean Nyekjaer return 0; 1941b5969abfSSean Nyekjaer 1942b5969abfSSean Nyekjaer err = st_lsm6dsx_event_setup(hw, state); 1943b5969abfSSean Nyekjaer if (err < 0) 1944b5969abfSSean Nyekjaer return err; 1945b5969abfSSean Nyekjaer 1946d278d447SLorenzo Bianconi mutex_lock(&hw->conf_lock); 1947bd41c445SLorenzo Bianconi if (enable_event || !(hw->fifo_mask & BIT(sensor->id))) 1948bd41c445SLorenzo Bianconi err = __st_lsm6dsx_sensor_set_enable(sensor, state); 1949d278d447SLorenzo Bianconi mutex_unlock(&hw->conf_lock); 1950b5969abfSSean Nyekjaer if (err < 0) 1951b5969abfSSean Nyekjaer return err; 1952b5969abfSSean Nyekjaer 19531aabad1fSSean Nyekjaer out: 19541aabad1fSSean Nyekjaer hw->enable_event = enable_event; 1955b5969abfSSean Nyekjaer 1956b5969abfSSean Nyekjaer return 0; 1957b5969abfSSean Nyekjaer } 1958b5969abfSSean Nyekjaer 1959d40464f3SLorenzo Bianconi int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val) 1960290a6ce1SLorenzo Bianconi { 1961290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1962290a6ce1SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 19638f2a88a2SLorenzo Bianconi int err; 1964290a6ce1SLorenzo Bianconi 19659e5b4cd2SPaul Cercueil val = clamp_val(val, 1, hw->settings->fifo_ops.max_size); 1966290a6ce1SLorenzo Bianconi 1967335eaedcSLorenzo Bianconi mutex_lock(&hw->conf_lock); 1968335eaedcSLorenzo Bianconi 1969290a6ce1SLorenzo Bianconi err = st_lsm6dsx_update_watermark(sensor, val); 1970335eaedcSLorenzo Bianconi 1971335eaedcSLorenzo Bianconi mutex_unlock(&hw->conf_lock); 1972335eaedcSLorenzo Bianconi 1973290a6ce1SLorenzo Bianconi if (err < 0) 1974290a6ce1SLorenzo Bianconi return err; 1975290a6ce1SLorenzo Bianconi 1976290a6ce1SLorenzo Bianconi sensor->watermark = val; 1977290a6ce1SLorenzo Bianconi 1978290a6ce1SLorenzo Bianconi return 0; 1979290a6ce1SLorenzo Bianconi } 1980290a6ce1SLorenzo Bianconi 1981290a6ce1SLorenzo Bianconi static ssize_t 1982290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev, 1983290a6ce1SLorenzo Bianconi struct device_attribute *attr, 1984290a6ce1SLorenzo Bianconi char *buf) 1985290a6ce1SLorenzo Bianconi { 19866270bf1fSHaibo Chen struct st_lsm6dsx_sensor *sensor = iio_priv(dev_to_iio_dev(dev)); 198759af4e20SLorenzo Bianconi const struct st_lsm6dsx_odr_table_entry *odr_table; 1988290a6ce1SLorenzo Bianconi int i, len = 0; 1989290a6ce1SLorenzo Bianconi 199059af4e20SLorenzo Bianconi odr_table = &sensor->hw->settings->odr_table[sensor->id]; 199159af4e20SLorenzo Bianconi for (i = 0; i < odr_table->odr_len; i++) 1992f8710f03SLorenzo Bianconi len += scnprintf(buf + len, PAGE_SIZE - len, "%d.%03d ", 1993f8710f03SLorenzo Bianconi odr_table->odr_avl[i].milli_hz / 1000, 1994f8710f03SLorenzo Bianconi odr_table->odr_avl[i].milli_hz % 1000); 1995290a6ce1SLorenzo Bianconi buf[len - 1] = '\n'; 1996290a6ce1SLorenzo Bianconi 1997290a6ce1SLorenzo Bianconi return len; 1998290a6ce1SLorenzo Bianconi } 1999290a6ce1SLorenzo Bianconi 2000290a6ce1SLorenzo Bianconi static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev, 2001290a6ce1SLorenzo Bianconi struct device_attribute *attr, 2002290a6ce1SLorenzo Bianconi char *buf) 2003290a6ce1SLorenzo Bianconi { 20046270bf1fSHaibo Chen struct st_lsm6dsx_sensor *sensor = iio_priv(dev_to_iio_dev(dev)); 20050f7e1728SLorenzo Bianconi const struct st_lsm6dsx_fs_table_entry *fs_table; 2006640aca3fSLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 2007290a6ce1SLorenzo Bianconi int i, len = 0; 2008290a6ce1SLorenzo Bianconi 200985ae3aeeSLorenzo Bianconi fs_table = &hw->settings->fs_table[sensor->id]; 201085ae3aeeSLorenzo Bianconi for (i = 0; i < fs_table->fs_len; i++) 201144a76de8SMario Tesi len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09u ", 20120f7e1728SLorenzo Bianconi fs_table->fs_avl[i].gain); 2013290a6ce1SLorenzo Bianconi buf[len - 1] = '\n'; 2014290a6ce1SLorenzo Bianconi 2015290a6ce1SLorenzo Bianconi return len; 2016290a6ce1SLorenzo Bianconi } 2017290a6ce1SLorenzo Bianconi 201844a76de8SMario Tesi static int st_lsm6dsx_write_raw_get_fmt(struct iio_dev *indio_dev, 201944a76de8SMario Tesi struct iio_chan_spec const *chan, 202044a76de8SMario Tesi long mask) 202144a76de8SMario Tesi { 202244a76de8SMario Tesi switch (mask) { 202344a76de8SMario Tesi case IIO_CHAN_INFO_SCALE: 202444a76de8SMario Tesi switch (chan->type) { 202544a76de8SMario Tesi case IIO_ANGL_VEL: 202644a76de8SMario Tesi case IIO_ACCEL: 202744a76de8SMario Tesi return IIO_VAL_INT_PLUS_NANO; 202844a76de8SMario Tesi default: 202944a76de8SMario Tesi return IIO_VAL_INT_PLUS_MICRO; 203044a76de8SMario Tesi } 203144a76de8SMario Tesi default: 203244a76de8SMario Tesi return IIO_VAL_INT_PLUS_MICRO; 203344a76de8SMario Tesi } 203444a76de8SMario Tesi } 203544a76de8SMario Tesi 2036290a6ce1SLorenzo Bianconi static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail); 2037290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_accel_scale_available, 0444, 2038290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_scale_avail, NULL, 0); 2039290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444, 2040290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_scale_avail, NULL, 0); 2041290a6ce1SLorenzo Bianconi 2042290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_acc_attributes[] = { 2043290a6ce1SLorenzo Bianconi &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 2044290a6ce1SLorenzo Bianconi &iio_dev_attr_in_accel_scale_available.dev_attr.attr, 2045290a6ce1SLorenzo Bianconi NULL, 2046290a6ce1SLorenzo Bianconi }; 2047290a6ce1SLorenzo Bianconi 2048290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_acc_attribute_group = { 2049290a6ce1SLorenzo Bianconi .attrs = st_lsm6dsx_acc_attributes, 2050290a6ce1SLorenzo Bianconi }; 2051290a6ce1SLorenzo Bianconi 2052290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_acc_info = { 2053290a6ce1SLorenzo Bianconi .attrs = &st_lsm6dsx_acc_attribute_group, 2054290a6ce1SLorenzo Bianconi .read_raw = st_lsm6dsx_read_raw, 2055290a6ce1SLorenzo Bianconi .write_raw = st_lsm6dsx_write_raw, 2056b5969abfSSean Nyekjaer .read_event_value = st_lsm6dsx_read_event, 2057b5969abfSSean Nyekjaer .write_event_value = st_lsm6dsx_write_event, 2058b5969abfSSean Nyekjaer .read_event_config = st_lsm6dsx_read_event_config, 2059b5969abfSSean Nyekjaer .write_event_config = st_lsm6dsx_write_event_config, 2060290a6ce1SLorenzo Bianconi .hwfifo_set_watermark = st_lsm6dsx_set_watermark, 206144a76de8SMario Tesi .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, 2062290a6ce1SLorenzo Bianconi }; 2063290a6ce1SLorenzo Bianconi 2064290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_gyro_attributes[] = { 2065290a6ce1SLorenzo Bianconi &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 2066290a6ce1SLorenzo Bianconi &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr, 2067290a6ce1SLorenzo Bianconi NULL, 2068290a6ce1SLorenzo Bianconi }; 2069290a6ce1SLorenzo Bianconi 2070290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_gyro_attribute_group = { 2071290a6ce1SLorenzo Bianconi .attrs = st_lsm6dsx_gyro_attributes, 2072290a6ce1SLorenzo Bianconi }; 2073290a6ce1SLorenzo Bianconi 2074290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_gyro_info = { 2075290a6ce1SLorenzo Bianconi .attrs = &st_lsm6dsx_gyro_attribute_group, 2076290a6ce1SLorenzo Bianconi .read_raw = st_lsm6dsx_read_raw, 2077290a6ce1SLorenzo Bianconi .write_raw = st_lsm6dsx_write_raw, 2078290a6ce1SLorenzo Bianconi .hwfifo_set_watermark = st_lsm6dsx_set_watermark, 207944a76de8SMario Tesi .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, 2080290a6ce1SLorenzo Bianconi }; 2081290a6ce1SLorenzo Bianconi 208203d4c566SAndy Shevchenko static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) 2083dba32904SLorenzo Bianconi { 208403d4c566SAndy Shevchenko struct device *dev = hw->dev; 2085dba32904SLorenzo Bianconi 208603d4c566SAndy Shevchenko if (!dev_fwnode(dev)) 2087dba32904SLorenzo Bianconi return -EINVAL; 2088dba32904SLorenzo Bianconi 208903d4c566SAndy Shevchenko return device_property_read_u32(dev, "st,drdy-int-pin", drdy_pin); 2090dba32904SLorenzo Bianconi } 2091dba32904SLorenzo Bianconi 20927e906103SLorenzo Bianconi static int 20937e906103SLorenzo Bianconi st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, 20947e906103SLorenzo Bianconi const struct st_lsm6dsx_reg **drdy_reg) 2095dba32904SLorenzo Bianconi { 2096dba32904SLorenzo Bianconi int err = 0, drdy_pin; 2097dba32904SLorenzo Bianconi 209803d4c566SAndy Shevchenko if (st_lsm6dsx_get_drdy_pin(hw, &drdy_pin) < 0) { 2099dba32904SLorenzo Bianconi struct st_sensors_platform_data *pdata; 2100dba32904SLorenzo Bianconi struct device *dev = hw->dev; 2101dba32904SLorenzo Bianconi 2102dba32904SLorenzo Bianconi pdata = (struct st_sensors_platform_data *)dev->platform_data; 2103dba32904SLorenzo Bianconi drdy_pin = pdata ? pdata->drdy_int_pin : 1; 2104dba32904SLorenzo Bianconi } 2105dba32904SLorenzo Bianconi 2106dba32904SLorenzo Bianconi switch (drdy_pin) { 2107dba32904SLorenzo Bianconi case 1: 21087e906103SLorenzo Bianconi hw->irq_routing = &hw->settings->irq_config.irq1_func; 21097e906103SLorenzo Bianconi *drdy_reg = &hw->settings->irq_config.irq1; 2110dba32904SLorenzo Bianconi break; 2111dba32904SLorenzo Bianconi case 2: 21127e906103SLorenzo Bianconi hw->irq_routing = &hw->settings->irq_config.irq2_func; 21137e906103SLorenzo Bianconi *drdy_reg = &hw->settings->irq_config.irq2; 2114dba32904SLorenzo Bianconi break; 2115dba32904SLorenzo Bianconi default: 2116dba32904SLorenzo Bianconi dev_err(hw->dev, "unsupported data ready pin\n"); 2117dba32904SLorenzo Bianconi err = -EINVAL; 2118dba32904SLorenzo Bianconi break; 2119dba32904SLorenzo Bianconi } 2120dba32904SLorenzo Bianconi 2121dba32904SLorenzo Bianconi return err; 2122dba32904SLorenzo Bianconi } 2123dba32904SLorenzo Bianconi 2124c91c1c84SLorenzo Bianconi static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw) 2125c91c1c84SLorenzo Bianconi { 2126c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 2127c91c1c84SLorenzo Bianconi struct st_sensors_platform_data *pdata; 212803d4c566SAndy Shevchenko struct device *dev = hw->dev; 2129c91c1c84SLorenzo Bianconi unsigned int data; 2130c91c1c84SLorenzo Bianconi int err = 0; 2131c91c1c84SLorenzo Bianconi 2132c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 2133c91c1c84SLorenzo Bianconi 213403d4c566SAndy Shevchenko pdata = (struct st_sensors_platform_data *)dev->platform_data; 213503d4c566SAndy Shevchenko if ((dev_fwnode(dev) && device_property_read_bool(dev, "st,pullups")) || 2136c91c1c84SLorenzo Bianconi (pdata && pdata->pullups)) { 21373a431957SLorenzo Bianconi if (hub_settings->pullup_en.sec_page) { 2138c91c1c84SLorenzo Bianconi err = st_lsm6dsx_set_page(hw, true); 2139c91c1c84SLorenzo Bianconi if (err < 0) 2140c91c1c84SLorenzo Bianconi return err; 21413a431957SLorenzo Bianconi } 2142c91c1c84SLorenzo Bianconi 2143c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask); 2144c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 2145c91c1c84SLorenzo Bianconi hub_settings->pullup_en.addr, 2146c91c1c84SLorenzo Bianconi hub_settings->pullup_en.mask, data); 2147c91c1c84SLorenzo Bianconi 21483a431957SLorenzo Bianconi if (hub_settings->pullup_en.sec_page) 2149c91c1c84SLorenzo Bianconi st_lsm6dsx_set_page(hw, false); 2150c91c1c84SLorenzo Bianconi 2151c91c1c84SLorenzo Bianconi if (err < 0) 2152c91c1c84SLorenzo Bianconi return err; 2153c91c1c84SLorenzo Bianconi } 2154c91c1c84SLorenzo Bianconi 2155c91c1c84SLorenzo Bianconi if (hub_settings->aux_sens.addr) { 2156c91c1c84SLorenzo Bianconi /* configure aux sensors */ 2157c91c1c84SLorenzo Bianconi err = st_lsm6dsx_set_page(hw, true); 2158c91c1c84SLorenzo Bianconi if (err < 0) 2159c91c1c84SLorenzo Bianconi return err; 2160c91c1c84SLorenzo Bianconi 2161c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask); 2162c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 2163c91c1c84SLorenzo Bianconi hub_settings->aux_sens.addr, 2164c91c1c84SLorenzo Bianconi hub_settings->aux_sens.mask, data); 2165c91c1c84SLorenzo Bianconi 2166c91c1c84SLorenzo Bianconi st_lsm6dsx_set_page(hw, false); 2167e485e2a2SLorenzo Bianconi 2168e485e2a2SLorenzo Bianconi if (err < 0) 2169e485e2a2SLorenzo Bianconi return err; 2170e485e2a2SLorenzo Bianconi } 2171e485e2a2SLorenzo Bianconi 2172e485e2a2SLorenzo Bianconi if (hub_settings->emb_func.addr) { 2173e485e2a2SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->emb_func.mask); 2174e485e2a2SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 2175e485e2a2SLorenzo Bianconi hub_settings->emb_func.addr, 2176e485e2a2SLorenzo Bianconi hub_settings->emb_func.mask, data); 2177c91c1c84SLorenzo Bianconi } 2178c91c1c84SLorenzo Bianconi 2179c91c1c84SLorenzo Bianconi return err; 2180c91c1c84SLorenzo Bianconi } 2181c91c1c84SLorenzo Bianconi 218221345107SLorenzo Bianconi static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw) 218321345107SLorenzo Bianconi { 218421345107SLorenzo Bianconi const struct st_lsm6dsx_hw_ts_settings *ts_settings; 218521345107SLorenzo Bianconi int err, val; 218621345107SLorenzo Bianconi 218721345107SLorenzo Bianconi ts_settings = &hw->settings->ts_settings; 218821345107SLorenzo Bianconi /* enable hw timestamp generation if necessary */ 218921345107SLorenzo Bianconi if (ts_settings->timer_en.addr) { 219021345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask); 219121345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 219221345107SLorenzo Bianconi ts_settings->timer_en.addr, 219321345107SLorenzo Bianconi ts_settings->timer_en.mask, val); 219421345107SLorenzo Bianconi if (err < 0) 219521345107SLorenzo Bianconi return err; 219621345107SLorenzo Bianconi } 219721345107SLorenzo Bianconi 219821345107SLorenzo Bianconi /* enable high resolution for hw ts timer if necessary */ 219921345107SLorenzo Bianconi if (ts_settings->hr_timer.addr) { 220021345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask); 220121345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 220221345107SLorenzo Bianconi ts_settings->hr_timer.addr, 220321345107SLorenzo Bianconi ts_settings->hr_timer.mask, val); 220421345107SLorenzo Bianconi if (err < 0) 220521345107SLorenzo Bianconi return err; 220621345107SLorenzo Bianconi } 220721345107SLorenzo Bianconi 220821345107SLorenzo Bianconi /* enable ts queueing in FIFO if necessary */ 220921345107SLorenzo Bianconi if (ts_settings->fifo_en.addr) { 221021345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask); 221121345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 221221345107SLorenzo Bianconi ts_settings->fifo_en.addr, 221321345107SLorenzo Bianconi ts_settings->fifo_en.mask, val); 221421345107SLorenzo Bianconi if (err < 0) 221521345107SLorenzo Bianconi return err; 221621345107SLorenzo Bianconi } 2217cb3b6b8eSMario Tesi 2218cb3b6b8eSMario Tesi /* calibrate timestamp sensitivity */ 2219cb3b6b8eSMario Tesi hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY; 2220cb3b6b8eSMario Tesi if (ts_settings->freq_fine) { 2221cb3b6b8eSMario Tesi err = regmap_read(hw->regmap, ts_settings->freq_fine, &val); 2222cb3b6b8eSMario Tesi if (err < 0) 2223cb3b6b8eSMario Tesi return err; 2224cb3b6b8eSMario Tesi 2225cb3b6b8eSMario Tesi /* 2226cb3b6b8eSMario Tesi * linearize the AN5192 formula: 2227cb3b6b8eSMario Tesi * 1 / (1 + x) ~= 1 - x (Taylor’s Series) 2228cb3b6b8eSMario Tesi * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val)) 2229cb3b6b8eSMario Tesi * ttrim[ns] ~= 25000 - 37.5 * val 2230cb3b6b8eSMario Tesi * ttrim[ns] ~= 25000 - (37500 * val) / 1000 2231cb3b6b8eSMario Tesi */ 2232cb3b6b8eSMario Tesi hw->ts_gain -= ((s8)val * 37500) / 1000; 2233cb3b6b8eSMario Tesi } 2234cb3b6b8eSMario Tesi 223521345107SLorenzo Bianconi return 0; 223621345107SLorenzo Bianconi } 223721345107SLorenzo Bianconi 22383a63da26SLorenzo Bianconi static int st_lsm6dsx_reset_device(struct st_lsm6dsx_hw *hw) 2239290a6ce1SLorenzo Bianconi { 22407e906103SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 2241290a6ce1SLorenzo Bianconi int err; 2242290a6ce1SLorenzo Bianconi 22433a63da26SLorenzo Bianconi /* 22443a63da26SLorenzo Bianconi * flush hw FIFO before device reset in order to avoid 22453a63da26SLorenzo Bianconi * possible races on interrupt line 1. If the first interrupt 22463a63da26SLorenzo Bianconi * line is asserted during hw reset the device will work in 22473a63da26SLorenzo Bianconi * I3C-only mode (if it is supported) 22483a63da26SLorenzo Bianconi */ 22493a63da26SLorenzo Bianconi err = st_lsm6dsx_flush_fifo(hw); 22503a63da26SLorenzo Bianconi if (err < 0 && err != -ENOTSUPP) 22513a63da26SLorenzo Bianconi return err; 22523a63da26SLorenzo Bianconi 225319435425SLorenzo Bianconi /* device sw reset */ 225466b662a1SLorenzo Bianconi reg = &hw->settings->reset; 225566b662a1SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 225666b662a1SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 2257290a6ce1SLorenzo Bianconi if (err < 0) 2258290a6ce1SLorenzo Bianconi return err; 2259290a6ce1SLorenzo Bianconi 226019435425SLorenzo Bianconi msleep(50); 226119435425SLorenzo Bianconi 226219435425SLorenzo Bianconi /* reload trimming parameter */ 226366b662a1SLorenzo Bianconi reg = &hw->settings->boot; 226466b662a1SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 226566b662a1SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 226619435425SLorenzo Bianconi if (err < 0) 226719435425SLorenzo Bianconi return err; 226819435425SLorenzo Bianconi 226919435425SLorenzo Bianconi msleep(50); 2270290a6ce1SLorenzo Bianconi 22713a63da26SLorenzo Bianconi return 0; 22723a63da26SLorenzo Bianconi } 22733a63da26SLorenzo Bianconi 22743a63da26SLorenzo Bianconi static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) 22753a63da26SLorenzo Bianconi { 22763a63da26SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 22773a63da26SLorenzo Bianconi int err; 22783a63da26SLorenzo Bianconi 22793a63da26SLorenzo Bianconi err = st_lsm6dsx_reset_device(hw); 22803a63da26SLorenzo Bianconi if (err < 0) 22813a63da26SLorenzo Bianconi return err; 22823a63da26SLorenzo Bianconi 2283290a6ce1SLorenzo Bianconi /* enable Block Data Update */ 228466b662a1SLorenzo Bianconi reg = &hw->settings->bdu; 228566b662a1SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 228666b662a1SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 2287290a6ce1SLorenzo Bianconi if (err < 0) 2288290a6ce1SLorenzo Bianconi return err; 2289290a6ce1SLorenzo Bianconi 2290290a6ce1SLorenzo Bianconi /* enable FIFO watermak interrupt */ 22917e906103SLorenzo Bianconi err = st_lsm6dsx_get_drdy_reg(hw, ®); 2292290a6ce1SLorenzo Bianconi if (err < 0) 2293290a6ce1SLorenzo Bianconi return err; 2294290a6ce1SLorenzo Bianconi 22957e906103SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 22967e906103SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 229721345107SLorenzo Bianconi if (err < 0) 229821345107SLorenzo Bianconi return err; 229921345107SLorenzo Bianconi 23009db02d32SLorenzo Bianconi /* enable Latched interrupts for device events */ 23017e906103SLorenzo Bianconi if (hw->settings->irq_config.lir.addr) { 23027e906103SLorenzo Bianconi reg = &hw->settings->irq_config.lir; 23037e906103SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 23047e906103SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 23059db02d32SLorenzo Bianconi if (err < 0) 23069db02d32SLorenzo Bianconi return err; 230722ea5651SLorenzo Bianconi 230822ea5651SLorenzo Bianconi /* enable clear on read for latched interrupts */ 23097e906103SLorenzo Bianconi if (hw->settings->irq_config.clear_on_read.addr) { 23107e906103SLorenzo Bianconi reg = &hw->settings->irq_config.clear_on_read; 231122ea5651SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 23127e906103SLorenzo Bianconi reg->addr, reg->mask, 23137e906103SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 231422ea5651SLorenzo Bianconi if (err < 0) 231522ea5651SLorenzo Bianconi return err; 231622ea5651SLorenzo Bianconi } 23179db02d32SLorenzo Bianconi } 23189db02d32SLorenzo Bianconi 2319960506edSLorenzo Bianconi /* enable drdy-mas if available */ 2320960506edSLorenzo Bianconi if (hw->settings->drdy_mask.addr) { 2321960506edSLorenzo Bianconi reg = &hw->settings->drdy_mask; 2322960506edSLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 2323960506edSLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 2324960506edSLorenzo Bianconi if (err < 0) 2325960506edSLorenzo Bianconi return err; 2326960506edSLorenzo Bianconi } 2327960506edSLorenzo Bianconi 2328c91c1c84SLorenzo Bianconi err = st_lsm6dsx_init_shub(hw); 2329c91c1c84SLorenzo Bianconi if (err < 0) 2330c91c1c84SLorenzo Bianconi return err; 2331c91c1c84SLorenzo Bianconi 233221345107SLorenzo Bianconi return st_lsm6dsx_init_hw_timer(hw); 2333290a6ce1SLorenzo Bianconi } 2334290a6ce1SLorenzo Bianconi 2335290a6ce1SLorenzo Bianconi static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, 2336510c0106SLorenzo Bianconi enum st_lsm6dsx_sensor_id id, 2337510c0106SLorenzo Bianconi const char *name) 2338290a6ce1SLorenzo Bianconi { 2339290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 2340290a6ce1SLorenzo Bianconi struct iio_dev *iio_dev; 2341290a6ce1SLorenzo Bianconi 2342290a6ce1SLorenzo Bianconi iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor)); 2343290a6ce1SLorenzo Bianconi if (!iio_dev) 2344290a6ce1SLorenzo Bianconi return NULL; 2345290a6ce1SLorenzo Bianconi 2346290a6ce1SLorenzo Bianconi iio_dev->modes = INDIO_DIRECT_MODE; 2347290a6ce1SLorenzo Bianconi iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks; 2348f48bc49bSLorenzo Bianconi iio_dev->channels = hw->settings->channels[id].chan; 2349f48bc49bSLorenzo Bianconi iio_dev->num_channels = hw->settings->channels[id].len; 2350290a6ce1SLorenzo Bianconi 2351290a6ce1SLorenzo Bianconi sensor = iio_priv(iio_dev); 2352290a6ce1SLorenzo Bianconi sensor->id = id; 2353290a6ce1SLorenzo Bianconi sensor->hw = hw; 2354f8710f03SLorenzo Bianconi sensor->odr = hw->settings->odr_table[id].odr_avl[0].milli_hz; 2355640aca3fSLorenzo Bianconi sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain; 2356290a6ce1SLorenzo Bianconi sensor->watermark = 1; 2357290a6ce1SLorenzo Bianconi 2358290a6ce1SLorenzo Bianconi switch (id) { 2359290a6ce1SLorenzo Bianconi case ST_LSM6DSX_ID_ACC: 2360290a6ce1SLorenzo Bianconi iio_dev->info = &st_lsm6dsx_acc_info; 2361510c0106SLorenzo Bianconi scnprintf(sensor->name, sizeof(sensor->name), "%s_accel", 2362510c0106SLorenzo Bianconi name); 2363290a6ce1SLorenzo Bianconi break; 2364290a6ce1SLorenzo Bianconi case ST_LSM6DSX_ID_GYRO: 2365290a6ce1SLorenzo Bianconi iio_dev->info = &st_lsm6dsx_gyro_info; 2366510c0106SLorenzo Bianconi scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro", 2367510c0106SLorenzo Bianconi name); 2368290a6ce1SLorenzo Bianconi break; 2369290a6ce1SLorenzo Bianconi default: 2370290a6ce1SLorenzo Bianconi return NULL; 2371290a6ce1SLorenzo Bianconi } 2372510c0106SLorenzo Bianconi iio_dev->name = sensor->name; 2373290a6ce1SLorenzo Bianconi 2374290a6ce1SLorenzo Bianconi return iio_dev; 2375290a6ce1SLorenzo Bianconi } 2376290a6ce1SLorenzo Bianconi 2377615bd378SLorenzo Bianconi static bool 2378615bd378SLorenzo Bianconi st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw) 23791aabad1fSSean Nyekjaer { 2380615bd378SLorenzo Bianconi const struct st_lsm6dsx_event_settings *event_settings; 2381615bd378SLorenzo Bianconi int err, data; 2382615bd378SLorenzo Bianconi s64 timestamp; 23831aabad1fSSean Nyekjaer 2384615bd378SLorenzo Bianconi if (!hw->enable_event) 2385615bd378SLorenzo Bianconi return false; 2386615bd378SLorenzo Bianconi 2387615bd378SLorenzo Bianconi event_settings = &hw->settings->event_settings; 2388615bd378SLorenzo Bianconi err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg, 2389615bd378SLorenzo Bianconi &data, sizeof(data)); 2390615bd378SLorenzo Bianconi if (err < 0) 2391615bd378SLorenzo Bianconi return false; 2392615bd378SLorenzo Bianconi 2393615bd378SLorenzo Bianconi timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]); 23941aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_z_mask) && 23951aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_Z))) 23961aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 23971aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 23981aabad1fSSean Nyekjaer 0, 23991aabad1fSSean Nyekjaer IIO_MOD_Z, 24001aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 24011aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 24021aabad1fSSean Nyekjaer timestamp); 24031aabad1fSSean Nyekjaer 24041aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_y_mask) && 24051aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_Y))) 24061aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 24071aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 24081aabad1fSSean Nyekjaer 0, 24091aabad1fSSean Nyekjaer IIO_MOD_Y, 24101aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 24111aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 24121aabad1fSSean Nyekjaer timestamp); 24131aabad1fSSean Nyekjaer 24141aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_x_mask) && 24151aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_X))) 24161aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 24171aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 24181aabad1fSSean Nyekjaer 0, 24191aabad1fSSean Nyekjaer IIO_MOD_X, 24201aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 24211aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 24221aabad1fSSean Nyekjaer timestamp); 2423615bd378SLorenzo Bianconi 2424615bd378SLorenzo Bianconi return data & event_settings->wakeup_src_status_mask; 24251aabad1fSSean Nyekjaer } 24261aabad1fSSean Nyekjaer 24276ee6a368SSean Nyekjaer static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) 24286ee6a368SSean Nyekjaer { 24296ee6a368SSean Nyekjaer struct st_lsm6dsx_hw *hw = private; 24303f9bce7aSLorenzo Bianconi int fifo_len = 0, len; 2431615bd378SLorenzo Bianconi bool event; 24321aabad1fSSean Nyekjaer 2433615bd378SLorenzo Bianconi event = st_lsm6dsx_report_motion_event(hw); 24346ee6a368SSean Nyekjaer 2435a912ee4cSLorenzo Bianconi if (!hw->settings->fifo_ops.read_fifo) 2436a912ee4cSLorenzo Bianconi return event ? IRQ_HANDLED : IRQ_NONE; 2437a912ee4cSLorenzo Bianconi 24383f9bce7aSLorenzo Bianconi /* 24393f9bce7aSLorenzo Bianconi * If we are using edge IRQs, new samples can arrive while 24403f9bce7aSLorenzo Bianconi * processing current interrupt since there are no hw 24413f9bce7aSLorenzo Bianconi * guarantees the irq line stays "low" long enough to properly 24423f9bce7aSLorenzo Bianconi * detect the new interrupt. In this case the new sample will 24433f9bce7aSLorenzo Bianconi * be missed. 24443f9bce7aSLorenzo Bianconi * Polling FIFO status register allow us to read new 24453f9bce7aSLorenzo Bianconi * samples even if the interrupt arrives while processing 24463f9bce7aSLorenzo Bianconi * previous data and the timeslot where the line is "low" is 24473f9bce7aSLorenzo Bianconi * too short to be properly detected. 24483f9bce7aSLorenzo Bianconi */ 24493f9bce7aSLorenzo Bianconi do { 24506ee6a368SSean Nyekjaer mutex_lock(&hw->fifo_lock); 24513f9bce7aSLorenzo Bianconi len = hw->settings->fifo_ops.read_fifo(hw); 24526ee6a368SSean Nyekjaer mutex_unlock(&hw->fifo_lock); 24536ee6a368SSean Nyekjaer 24543f9bce7aSLorenzo Bianconi if (len > 0) 24553f9bce7aSLorenzo Bianconi fifo_len += len; 24563f9bce7aSLorenzo Bianconi } while (len > 0); 24573f9bce7aSLorenzo Bianconi 24583f9bce7aSLorenzo Bianconi return fifo_len || event ? IRQ_HANDLED : IRQ_NONE; 24596ee6a368SSean Nyekjaer } 24606ee6a368SSean Nyekjaer 24612cfb2180SLorenzo Bianconi static irqreturn_t st_lsm6dsx_sw_trigger_handler_thread(int irq, 24622cfb2180SLorenzo Bianconi void *private) 24632cfb2180SLorenzo Bianconi { 24642cfb2180SLorenzo Bianconi struct iio_poll_func *pf = private; 24652cfb2180SLorenzo Bianconi struct iio_dev *iio_dev = pf->indio_dev; 24662cfb2180SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 24672cfb2180SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 24682cfb2180SLorenzo Bianconi 24692cfb2180SLorenzo Bianconi if (sensor->id == ST_LSM6DSX_ID_EXT0 || 24702cfb2180SLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT1 || 24712cfb2180SLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT2) 24722cfb2180SLorenzo Bianconi st_lsm6dsx_shub_read_output(hw, 24732cfb2180SLorenzo Bianconi (u8 *)hw->scan[sensor->id].channels, 24742cfb2180SLorenzo Bianconi sizeof(hw->scan[sensor->id].channels)); 24752cfb2180SLorenzo Bianconi else 24762cfb2180SLorenzo Bianconi st_lsm6dsx_read_locked(hw, iio_dev->channels[0].address, 24772cfb2180SLorenzo Bianconi hw->scan[sensor->id].channels, 24782cfb2180SLorenzo Bianconi sizeof(hw->scan[sensor->id].channels)); 24792cfb2180SLorenzo Bianconi 24802cfb2180SLorenzo Bianconi iio_push_to_buffers_with_timestamp(iio_dev, &hw->scan[sensor->id], 24812cfb2180SLorenzo Bianconi iio_get_time_ns(iio_dev)); 24822cfb2180SLorenzo Bianconi iio_trigger_notify_done(iio_dev->trig); 24832cfb2180SLorenzo Bianconi 24842cfb2180SLorenzo Bianconi return IRQ_HANDLED; 24852cfb2180SLorenzo Bianconi } 24862cfb2180SLorenzo Bianconi 24876ee6a368SSean Nyekjaer static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) 24886ee6a368SSean Nyekjaer { 248931fe8d4eSLorenzo Bianconi struct st_sensors_platform_data *pdata; 249031fe8d4eSLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 249103d4c566SAndy Shevchenko struct device *dev = hw->dev; 24926ee6a368SSean Nyekjaer unsigned long irq_type; 24936ee6a368SSean Nyekjaer bool irq_active_low; 24946ee6a368SSean Nyekjaer int err; 24956ee6a368SSean Nyekjaer 24966ee6a368SSean Nyekjaer irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq)); 24976ee6a368SSean Nyekjaer 24986ee6a368SSean Nyekjaer switch (irq_type) { 24996ee6a368SSean Nyekjaer case IRQF_TRIGGER_HIGH: 25006ee6a368SSean Nyekjaer case IRQF_TRIGGER_RISING: 25016ee6a368SSean Nyekjaer irq_active_low = false; 25026ee6a368SSean Nyekjaer break; 25036ee6a368SSean Nyekjaer case IRQF_TRIGGER_LOW: 25046ee6a368SSean Nyekjaer case IRQF_TRIGGER_FALLING: 25056ee6a368SSean Nyekjaer irq_active_low = true; 25066ee6a368SSean Nyekjaer break; 25076ee6a368SSean Nyekjaer default: 25086ee6a368SSean Nyekjaer dev_info(hw->dev, "mode %lx unsupported\n", irq_type); 25096ee6a368SSean Nyekjaer return -EINVAL; 25106ee6a368SSean Nyekjaer } 25116ee6a368SSean Nyekjaer 251231fe8d4eSLorenzo Bianconi reg = &hw->settings->irq_config.hla; 251331fe8d4eSLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 251431fe8d4eSLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(irq_active_low, 251531fe8d4eSLorenzo Bianconi reg->mask)); 25166ee6a368SSean Nyekjaer if (err < 0) 25176ee6a368SSean Nyekjaer return err; 25186ee6a368SSean Nyekjaer 251903d4c566SAndy Shevchenko pdata = (struct st_sensors_platform_data *)dev->platform_data; 252003d4c566SAndy Shevchenko if ((dev_fwnode(dev) && device_property_read_bool(dev, "drive-open-drain")) || 25216ee6a368SSean Nyekjaer (pdata && pdata->open_drain)) { 252231fe8d4eSLorenzo Bianconi reg = &hw->settings->irq_config.od; 252331fe8d4eSLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 252431fe8d4eSLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 25256ee6a368SSean Nyekjaer if (err < 0) 25266ee6a368SSean Nyekjaer return err; 25276ee6a368SSean Nyekjaer 25286ee6a368SSean Nyekjaer irq_type |= IRQF_SHARED; 25296ee6a368SSean Nyekjaer } 25306ee6a368SSean Nyekjaer 25316ee6a368SSean Nyekjaer err = devm_request_threaded_irq(hw->dev, hw->irq, 2532a3aa17d4SSean Nyekjaer NULL, 25336ee6a368SSean Nyekjaer st_lsm6dsx_handler_thread, 25346ee6a368SSean Nyekjaer irq_type | IRQF_ONESHOT, 25356ee6a368SSean Nyekjaer "lsm6dsx", hw); 25366ee6a368SSean Nyekjaer if (err) { 25376ee6a368SSean Nyekjaer dev_err(hw->dev, "failed to request trigger irq %d\n", 25386ee6a368SSean Nyekjaer hw->irq); 25396ee6a368SSean Nyekjaer return err; 25406ee6a368SSean Nyekjaer } 25416ee6a368SSean Nyekjaer 25426ee6a368SSean Nyekjaer return 0; 25436ee6a368SSean Nyekjaer } 25446ee6a368SSean Nyekjaer 25452cfb2180SLorenzo Bianconi static int st_lsm6dsx_sw_buffer_preenable(struct iio_dev *iio_dev) 25462cfb2180SLorenzo Bianconi { 25472cfb2180SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 25482cfb2180SLorenzo Bianconi 25492cfb2180SLorenzo Bianconi return st_lsm6dsx_device_set_enable(sensor, true); 25502cfb2180SLorenzo Bianconi } 25512cfb2180SLorenzo Bianconi 25522cfb2180SLorenzo Bianconi static int st_lsm6dsx_sw_buffer_postdisable(struct iio_dev *iio_dev) 25532cfb2180SLorenzo Bianconi { 25542cfb2180SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 25552cfb2180SLorenzo Bianconi 25562cfb2180SLorenzo Bianconi return st_lsm6dsx_device_set_enable(sensor, false); 25572cfb2180SLorenzo Bianconi } 25582cfb2180SLorenzo Bianconi 25592cfb2180SLorenzo Bianconi static const struct iio_buffer_setup_ops st_lsm6dsx_sw_buffer_ops = { 25602cfb2180SLorenzo Bianconi .preenable = st_lsm6dsx_sw_buffer_preenable, 25612cfb2180SLorenzo Bianconi .postdisable = st_lsm6dsx_sw_buffer_postdisable, 25622cfb2180SLorenzo Bianconi }; 25632cfb2180SLorenzo Bianconi 25642cfb2180SLorenzo Bianconi static int st_lsm6dsx_sw_buffers_setup(struct st_lsm6dsx_hw *hw) 25652cfb2180SLorenzo Bianconi { 25662cfb2180SLorenzo Bianconi int i; 25672cfb2180SLorenzo Bianconi 25682cfb2180SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 25692cfb2180SLorenzo Bianconi int err; 25702cfb2180SLorenzo Bianconi 25712cfb2180SLorenzo Bianconi if (!hw->iio_devs[i]) 25722cfb2180SLorenzo Bianconi continue; 25732cfb2180SLorenzo Bianconi 25742cfb2180SLorenzo Bianconi err = devm_iio_triggered_buffer_setup(hw->dev, 25752cfb2180SLorenzo Bianconi hw->iio_devs[i], NULL, 25762cfb2180SLorenzo Bianconi st_lsm6dsx_sw_trigger_handler_thread, 25772cfb2180SLorenzo Bianconi &st_lsm6dsx_sw_buffer_ops); 25782cfb2180SLorenzo Bianconi if (err) 25792cfb2180SLorenzo Bianconi return err; 25802cfb2180SLorenzo Bianconi } 25812cfb2180SLorenzo Bianconi 25822cfb2180SLorenzo Bianconi return 0; 25832cfb2180SLorenzo Bianconi } 25842cfb2180SLorenzo Bianconi 2585f346b16fSLorenzo Bianconi static int st_lsm6dsx_init_regulators(struct device *dev) 2586f346b16fSLorenzo Bianconi { 25876900cdbfSMatti Vaittinen /* vdd-vddio power regulators */ 25886900cdbfSMatti Vaittinen static const char * const regulators[] = { "vdd", "vddio" }; 2589f346b16fSLorenzo Bianconi int err; 2590f346b16fSLorenzo Bianconi 25916900cdbfSMatti Vaittinen err = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(regulators), 25926900cdbfSMatti Vaittinen regulators); 2593f346b16fSLorenzo Bianconi if (err) 25946900cdbfSMatti Vaittinen return dev_err_probe(dev, err, "failed to enable regulators\n"); 2595f346b16fSLorenzo Bianconi 2596f346b16fSLorenzo Bianconi msleep(50); 2597f346b16fSLorenzo Bianconi 2598f346b16fSLorenzo Bianconi return 0; 2599f346b16fSLorenzo Bianconi } 2600f346b16fSLorenzo Bianconi 260181956a93SLorenzo Bianconi int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, 260251a8b707SLorenzo Bianconi struct regmap *regmap) 2603290a6ce1SLorenzo Bianconi { 2604b7a73b33SLorenzo Bianconi struct st_sensors_platform_data *pdata = dev->platform_data; 2605c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 2606290a6ce1SLorenzo Bianconi struct st_lsm6dsx_hw *hw; 260781956a93SLorenzo Bianconi const char *name = NULL; 2608290a6ce1SLorenzo Bianconi int i, err; 2609290a6ce1SLorenzo Bianconi 2610290a6ce1SLorenzo Bianconi hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); 2611290a6ce1SLorenzo Bianconi if (!hw) 2612290a6ce1SLorenzo Bianconi return -ENOMEM; 2613290a6ce1SLorenzo Bianconi 2614290a6ce1SLorenzo Bianconi dev_set_drvdata(dev, (void *)hw); 2615290a6ce1SLorenzo Bianconi 2616290a6ce1SLorenzo Bianconi mutex_init(&hw->fifo_lock); 2617335eaedcSLorenzo Bianconi mutex_init(&hw->conf_lock); 2618739aff87SLorenzo Bianconi mutex_init(&hw->page_lock); 2619290a6ce1SLorenzo Bianconi 2620f346b16fSLorenzo Bianconi err = st_lsm6dsx_init_regulators(dev); 2621f346b16fSLorenzo Bianconi if (err) 2622f346b16fSLorenzo Bianconi return err; 2623f346b16fSLorenzo Bianconi 262491a6b841SLorenzo Bianconi hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL); 262591a6b841SLorenzo Bianconi if (!hw->buff) 262691a6b841SLorenzo Bianconi return -ENOMEM; 262791a6b841SLorenzo Bianconi 2628290a6ce1SLorenzo Bianconi hw->dev = dev; 2629290a6ce1SLorenzo Bianconi hw->irq = irq; 263051a8b707SLorenzo Bianconi hw->regmap = regmap; 2631290a6ce1SLorenzo Bianconi 263281956a93SLorenzo Bianconi err = st_lsm6dsx_check_whoami(hw, hw_id, &name); 2633290a6ce1SLorenzo Bianconi if (err < 0) 2634290a6ce1SLorenzo Bianconi return err; 2635290a6ce1SLorenzo Bianconi 26366ffb55e5SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) { 2637510c0106SLorenzo Bianconi hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name); 2638290a6ce1SLorenzo Bianconi if (!hw->iio_devs[i]) 2639290a6ce1SLorenzo Bianconi return -ENOMEM; 2640290a6ce1SLorenzo Bianconi } 2641290a6ce1SLorenzo Bianconi 2642290a6ce1SLorenzo Bianconi err = st_lsm6dsx_init_device(hw); 2643290a6ce1SLorenzo Bianconi if (err < 0) 2644290a6ce1SLorenzo Bianconi return err; 2645290a6ce1SLorenzo Bianconi 2646c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 264735619155SLorenzo Bianconi if (hub_settings->master_en.addr && 264835619155SLorenzo Bianconi (!dev_fwnode(dev) || 264935619155SLorenzo Bianconi !device_property_read_bool(dev, "st,disable-sensor-hub"))) { 2650c91c1c84SLorenzo Bianconi err = st_lsm6dsx_shub_probe(hw, name); 2651c91c1c84SLorenzo Bianconi if (err < 0) 2652c91c1c84SLorenzo Bianconi return err; 2653c91c1c84SLorenzo Bianconi } 2654c91c1c84SLorenzo Bianconi 2655290a6ce1SLorenzo Bianconi if (hw->irq > 0) { 26566ee6a368SSean Nyekjaer err = st_lsm6dsx_irq_setup(hw); 26576ee6a368SSean Nyekjaer if (err < 0) 26586ee6a368SSean Nyekjaer return err; 26596ee6a368SSean Nyekjaer 2660290a6ce1SLorenzo Bianconi err = st_lsm6dsx_fifo_setup(hw); 2661290a6ce1SLorenzo Bianconi if (err < 0) 2662290a6ce1SLorenzo Bianconi return err; 2663290a6ce1SLorenzo Bianconi } 2664290a6ce1SLorenzo Bianconi 26652cfb2180SLorenzo Bianconi if (!hw->irq || !hw->settings->fifo_ops.read_fifo) { 26662cfb2180SLorenzo Bianconi /* 26672cfb2180SLorenzo Bianconi * Rely on sw triggers (e.g. hr-timers) if irq pin is not 26682cfb2180SLorenzo Bianconi * connected of if the device does not support HW FIFO 26692cfb2180SLorenzo Bianconi */ 26702cfb2180SLorenzo Bianconi err = st_lsm6dsx_sw_buffers_setup(hw); 26712cfb2180SLorenzo Bianconi if (err) 26722cfb2180SLorenzo Bianconi return err; 26732cfb2180SLorenzo Bianconi } 26742cfb2180SLorenzo Bianconi 2675b892770aSAndy Shevchenko err = iio_read_mount_matrix(hw->dev, &hw->orientation); 267604e6fedbSMartin Kepplinger if (err) 267704e6fedbSMartin Kepplinger return err; 267804e6fedbSMartin Kepplinger 2679290a6ce1SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 26806ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 26816ffb55e5SLorenzo Bianconi continue; 26826ffb55e5SLorenzo Bianconi 2683290a6ce1SLorenzo Bianconi err = devm_iio_device_register(hw->dev, hw->iio_devs[i]); 2684290a6ce1SLorenzo Bianconi if (err) 2685290a6ce1SLorenzo Bianconi return err; 2686290a6ce1SLorenzo Bianconi } 2687290a6ce1SLorenzo Bianconi 268803d4c566SAndy Shevchenko if ((dev_fwnode(dev) && device_property_read_bool(dev, "wakeup-source")) || 2689b7a73b33SLorenzo Bianconi (pdata && pdata->wakeup_source)) 26904c997dfaSSean Nyekjaer device_init_wakeup(dev, true); 26914c997dfaSSean Nyekjaer 2692290a6ce1SLorenzo Bianconi return 0; 2693290a6ce1SLorenzo Bianconi } 26942b059449SJonathan Cameron EXPORT_SYMBOL_NS(st_lsm6dsx_probe, IIO_LSM6DSX); 2695290a6ce1SLorenzo Bianconi 2696acc416ffSJonathan Cameron static int st_lsm6dsx_suspend(struct device *dev) 2697d3f77058SLorenzo Bianconi { 2698d3f77058SLorenzo Bianconi struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); 2699d3f77058SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 2700d3f77058SLorenzo Bianconi int i, err = 0; 2701d3f77058SLorenzo Bianconi 2702d3f77058SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 27036ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 27046ffb55e5SLorenzo Bianconi continue; 27056ffb55e5SLorenzo Bianconi 2706d3f77058SLorenzo Bianconi sensor = iio_priv(hw->iio_devs[i]); 2707d3f77058SLorenzo Bianconi if (!(hw->enable_mask & BIT(sensor->id))) 2708d3f77058SLorenzo Bianconi continue; 2709d3f77058SLorenzo Bianconi 27104c997dfaSSean Nyekjaer if (device_may_wakeup(dev) && 27114c997dfaSSean Nyekjaer sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) { 27124c997dfaSSean Nyekjaer /* Enable wake from IRQ */ 27134c997dfaSSean Nyekjaer enable_irq_wake(hw->irq); 27144c997dfaSSean Nyekjaer continue; 27154c997dfaSSean Nyekjaer } 27164c997dfaSSean Nyekjaer 2717cd83c5c1SLorenzo Bianconi err = st_lsm6dsx_device_set_enable(sensor, false); 2718d3f77058SLorenzo Bianconi if (err < 0) 2719d3f77058SLorenzo Bianconi return err; 2720bce0d57dSLorenzo Bianconi 2721bce0d57dSLorenzo Bianconi hw->suspend_mask |= BIT(sensor->id); 2722d3f77058SLorenzo Bianconi } 2723d3f77058SLorenzo Bianconi 2724c2686eb2SLorenzo Bianconi if (hw->fifo_mask) 2725d3f77058SLorenzo Bianconi err = st_lsm6dsx_flush_fifo(hw); 2726d3f77058SLorenzo Bianconi 2727d3f77058SLorenzo Bianconi return err; 2728d3f77058SLorenzo Bianconi } 2729d3f77058SLorenzo Bianconi 2730acc416ffSJonathan Cameron static int st_lsm6dsx_resume(struct device *dev) 2731d3f77058SLorenzo Bianconi { 2732d3f77058SLorenzo Bianconi struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); 2733d3f77058SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 2734d3f77058SLorenzo Bianconi int i, err = 0; 2735d3f77058SLorenzo Bianconi 2736d3f77058SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 27376ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 27386ffb55e5SLorenzo Bianconi continue; 27396ffb55e5SLorenzo Bianconi 2740d3f77058SLorenzo Bianconi sensor = iio_priv(hw->iio_devs[i]); 27414c997dfaSSean Nyekjaer if (device_may_wakeup(dev) && 27424c997dfaSSean Nyekjaer sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) 27434c997dfaSSean Nyekjaer disable_irq_wake(hw->irq); 27444c997dfaSSean Nyekjaer 2745bce0d57dSLorenzo Bianconi if (!(hw->suspend_mask & BIT(sensor->id))) 2746d3f77058SLorenzo Bianconi continue; 2747d3f77058SLorenzo Bianconi 2748cd83c5c1SLorenzo Bianconi err = st_lsm6dsx_device_set_enable(sensor, true); 2749d3f77058SLorenzo Bianconi if (err < 0) 2750d3f77058SLorenzo Bianconi return err; 2751bce0d57dSLorenzo Bianconi 2752bce0d57dSLorenzo Bianconi hw->suspend_mask &= ~BIT(sensor->id); 2753d3f77058SLorenzo Bianconi } 2754d3f77058SLorenzo Bianconi 2755c2686eb2SLorenzo Bianconi if (hw->fifo_mask) 2756a1bab939SLorenzo Bianconi err = st_lsm6dsx_resume_fifo(hw); 2757d3f77058SLorenzo Bianconi 2758d3f77058SLorenzo Bianconi return err; 2759d3f77058SLorenzo Bianconi } 2760d3f77058SLorenzo Bianconi 27612b059449SJonathan Cameron EXPORT_NS_SIMPLE_DEV_PM_OPS(st_lsm6dsx_pm_ops, st_lsm6dsx_suspend, 27622b059449SJonathan Cameron st_lsm6dsx_resume, IIO_LSM6DSX); 2763d3f77058SLorenzo Bianconi 2764290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>"); 2765290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 2766290a6ce1SLorenzo Bianconi MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver"); 2767290a6ce1SLorenzo Bianconi MODULE_LICENSE("GPL v2"); 2768