1fda8d26eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2290a6ce1SLorenzo Bianconi /* 3290a6ce1SLorenzo Bianconi * STMicroelectronics st_lsm6dsx sensor driver 4290a6ce1SLorenzo Bianconi * 5290a6ce1SLorenzo Bianconi * The ST LSM6DSx IMU MEMS series consists of 3D digital accelerometer 6290a6ce1SLorenzo Bianconi * and 3D digital gyroscope system-in-package with a digital I2C/SPI serial 7290a6ce1SLorenzo Bianconi * interface standard output. 8290a6ce1SLorenzo Bianconi * LSM6DSx IMU MEMS series has a dynamic user-selectable full-scale 9290a6ce1SLorenzo Bianconi * acceleration range of +-2/+-4/+-8/+-16 g and an angular rate range of 10290a6ce1SLorenzo Bianconi * +-125/+-245/+-500/+-1000/+-2000 dps 11290a6ce1SLorenzo Bianconi * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer 12290a6ce1SLorenzo Bianconi * allowing dynamic batching of sensor data. 1352f4b1f1SMartin Kepplinger * LSM9DSx series is similar but includes an additional magnetometer, handled 1452f4b1f1SMartin Kepplinger * by a different driver. 15290a6ce1SLorenzo Bianconi * 16290a6ce1SLorenzo Bianconi * Supported sensors: 17290a6ce1SLorenzo Bianconi * - LSM6DS3: 18290a6ce1SLorenzo Bianconi * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416 19290a6ce1SLorenzo Bianconi * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 20290a6ce1SLorenzo Bianconi * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 21290a6ce1SLorenzo Bianconi * - FIFO size: 8KB 22290a6ce1SLorenzo Bianconi * 23dbcd2088SLorenzo Bianconi * - LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC/LSM6DS3TR-C: 24290a6ce1SLorenzo Bianconi * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416 25290a6ce1SLorenzo Bianconi * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 26290a6ce1SLorenzo Bianconi * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 27290a6ce1SLorenzo Bianconi * - FIFO size: 4KB 28290a6ce1SLorenzo Bianconi * 29db947a79SLorenzo Bianconi * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX: 30801a6e0aSLorenzo Bianconi * - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416 31801a6e0aSLorenzo Bianconi * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 32801a6e0aSLorenzo Bianconi * - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000 33801a6e0aSLorenzo Bianconi * - FIFO size: 3KB 34801a6e0aSLorenzo Bianconi * 3552f4b1f1SMartin Kepplinger * - LSM9DS1: 3652f4b1f1SMartin Kepplinger * - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952 3752f4b1f1SMartin Kepplinger * - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16 3852f4b1f1SMartin Kepplinger * - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952 3952f4b1f1SMartin Kepplinger * - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000 4052f4b1f1SMartin Kepplinger * - FIFO size: 32 4152f4b1f1SMartin Kepplinger * 42290a6ce1SLorenzo Bianconi * Copyright 2016 STMicroelectronics Inc. 43290a6ce1SLorenzo Bianconi * 44290a6ce1SLorenzo Bianconi * Lorenzo Bianconi <lorenzo.bianconi@st.com> 45290a6ce1SLorenzo Bianconi * Denis Ciocca <denis.ciocca@st.com> 46290a6ce1SLorenzo Bianconi */ 47290a6ce1SLorenzo Bianconi 48290a6ce1SLorenzo Bianconi #include <linux/kernel.h> 49290a6ce1SLorenzo Bianconi #include <linux/module.h> 50290a6ce1SLorenzo Bianconi #include <linux/delay.h> 511aabad1fSSean Nyekjaer #include <linux/iio/events.h> 52290a6ce1SLorenzo Bianconi #include <linux/iio/iio.h> 53290a6ce1SLorenzo Bianconi #include <linux/iio/sysfs.h> 546ee6a368SSean Nyekjaer #include <linux/interrupt.h> 556ee6a368SSean Nyekjaer #include <linux/irq.h> 56d3f77058SLorenzo Bianconi #include <linux/pm.h> 5751a8b707SLorenzo Bianconi #include <linux/regmap.h> 5851a8b707SLorenzo Bianconi #include <linux/bitfield.h> 59290a6ce1SLorenzo Bianconi 60dba32904SLorenzo Bianconi #include <linux/platform_data/st_sensors_pdata.h> 61dba32904SLorenzo Bianconi 62290a6ce1SLorenzo Bianconi #include "st_lsm6dsx.h" 63290a6ce1SLorenzo Bianconi 64290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f 65290a6ce1SLorenzo Bianconi 66cb3b6b8eSMario Tesi #define ST_LSM6DSX_TS_SENSITIVITY 25000UL /* 25us */ 67cb3b6b8eSMario Tesi 68f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { 69b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0), 70b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1), 71b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2), 72f48bc49bSLorenzo Bianconi IIO_CHAN_SOFT_TIMESTAMP(3), 73f48bc49bSLorenzo Bianconi }; 74f48bc49bSLorenzo Bianconi 75f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = { 76f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0), 77f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1), 78f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2), 79f48bc49bSLorenzo Bianconi IIO_CHAN_SOFT_TIMESTAMP(3), 80f48bc49bSLorenzo Bianconi }; 81f48bc49bSLorenzo Bianconi 8252f4b1f1SMartin Kepplinger static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = { 8352f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0), 8452f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1), 8552f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2), 8652f4b1f1SMartin Kepplinger IIO_CHAN_SOFT_TIMESTAMP(3), 8752f4b1f1SMartin Kepplinger }; 8852f4b1f1SMartin Kepplinger 89290a6ce1SLorenzo Bianconi static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { 90290a6ce1SLorenzo Bianconi { 9152f4b1f1SMartin Kepplinger .wai = 0x68, 9266b662a1SLorenzo Bianconi .reset = { 9366b662a1SLorenzo Bianconi .addr = 0x22, 9466b662a1SLorenzo Bianconi .mask = BIT(0), 9566b662a1SLorenzo Bianconi }, 9666b662a1SLorenzo Bianconi .boot = { 9766b662a1SLorenzo Bianconi .addr = 0x22, 9866b662a1SLorenzo Bianconi .mask = BIT(7), 9966b662a1SLorenzo Bianconi }, 10066b662a1SLorenzo Bianconi .bdu = { 10166b662a1SLorenzo Bianconi .addr = 0x22, 10266b662a1SLorenzo Bianconi .mask = BIT(6), 10366b662a1SLorenzo Bianconi }, 10452f4b1f1SMartin Kepplinger .max_fifo_size = 32, 10552f4b1f1SMartin Kepplinger .id = { 10652f4b1f1SMartin Kepplinger { 10752f4b1f1SMartin Kepplinger .hw_id = ST_LSM9DS1_ID, 10852f4b1f1SMartin Kepplinger .name = ST_LSM9DS1_DEV_NAME, 10952f4b1f1SMartin Kepplinger }, 11052f4b1f1SMartin Kepplinger }, 11152f4b1f1SMartin Kepplinger .channels = { 11252f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 11352f4b1f1SMartin Kepplinger .chan = st_lsm6dsx_acc_channels, 11452f4b1f1SMartin Kepplinger .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 11552f4b1f1SMartin Kepplinger }, 11652f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 11752f4b1f1SMartin Kepplinger .chan = st_lsm6ds0_gyro_channels, 11852f4b1f1SMartin Kepplinger .len = ARRAY_SIZE(st_lsm6ds0_gyro_channels), 11952f4b1f1SMartin Kepplinger }, 12052f4b1f1SMartin Kepplinger }, 12152f4b1f1SMartin Kepplinger .odr_table = { 12252f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 12352f4b1f1SMartin Kepplinger .reg = { 12452f4b1f1SMartin Kepplinger .addr = 0x20, 12552f4b1f1SMartin Kepplinger .mask = GENMASK(7, 5), 12652f4b1f1SMartin Kepplinger }, 12752f4b1f1SMartin Kepplinger .odr_avl[0] = { 10, 0x01 }, 12852f4b1f1SMartin Kepplinger .odr_avl[1] = { 50, 0x02 }, 12952f4b1f1SMartin Kepplinger .odr_avl[2] = { 119, 0x03 }, 13052f4b1f1SMartin Kepplinger .odr_avl[3] = { 238, 0x04 }, 13152f4b1f1SMartin Kepplinger .odr_avl[4] = { 476, 0x05 }, 13252f4b1f1SMartin Kepplinger .odr_avl[5] = { 952, 0x06 }, 13352f4b1f1SMartin Kepplinger }, 13452f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 13552f4b1f1SMartin Kepplinger .reg = { 13652f4b1f1SMartin Kepplinger .addr = 0x10, 13752f4b1f1SMartin Kepplinger .mask = GENMASK(7, 5), 13852f4b1f1SMartin Kepplinger }, 13952f4b1f1SMartin Kepplinger .odr_avl[0] = { 15, 0x01 }, 14052f4b1f1SMartin Kepplinger .odr_avl[1] = { 60, 0x02 }, 14152f4b1f1SMartin Kepplinger .odr_avl[2] = { 119, 0x03 }, 14252f4b1f1SMartin Kepplinger .odr_avl[3] = { 238, 0x04 }, 14352f4b1f1SMartin Kepplinger .odr_avl[4] = { 476, 0x05 }, 14452f4b1f1SMartin Kepplinger .odr_avl[5] = { 952, 0x06 }, 14552f4b1f1SMartin Kepplinger }, 14652f4b1f1SMartin Kepplinger }, 14752f4b1f1SMartin Kepplinger .fs_table = { 14852f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 14952f4b1f1SMartin Kepplinger .reg = { 15052f4b1f1SMartin Kepplinger .addr = 0x20, 15152f4b1f1SMartin Kepplinger .mask = GENMASK(4, 3), 15252f4b1f1SMartin Kepplinger }, 1536fa02948SLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 1546fa02948SLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 1556fa02948SLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 1566fa02948SLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 }, 15785ae3aeeSLorenzo Bianconi .fs_len = 4, 15852f4b1f1SMartin Kepplinger }, 15952f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 16052f4b1f1SMartin Kepplinger .reg = { 16152f4b1f1SMartin Kepplinger .addr = 0x10, 16252f4b1f1SMartin Kepplinger .mask = GENMASK(4, 3), 16352f4b1f1SMartin Kepplinger }, 1641b375101SLorenzo Bianconi 1651b375101SLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 1661b375101SLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 1671b375101SLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 16885ae3aeeSLorenzo Bianconi .fs_len = 3, 16952f4b1f1SMartin Kepplinger }, 17052f4b1f1SMartin Kepplinger }, 1717e906103SLorenzo Bianconi .irq_config = { 1727e906103SLorenzo Bianconi .irq1 = { 1737e906103SLorenzo Bianconi .addr = 0x0c, 1747e906103SLorenzo Bianconi .mask = BIT(3), 1757e906103SLorenzo Bianconi }, 1767e906103SLorenzo Bianconi .irq2 = { 1777e906103SLorenzo Bianconi .addr = 0x0d, 1787e906103SLorenzo Bianconi .mask = BIT(3), 1797e906103SLorenzo Bianconi }, 18031fe8d4eSLorenzo Bianconi .hla = { 18131fe8d4eSLorenzo Bianconi .addr = 0x22, 18231fe8d4eSLorenzo Bianconi .mask = BIT(5), 18331fe8d4eSLorenzo Bianconi }, 18431fe8d4eSLorenzo Bianconi .od = { 18531fe8d4eSLorenzo Bianconi .addr = 0x22, 18631fe8d4eSLorenzo Bianconi .mask = BIT(4), 18731fe8d4eSLorenzo Bianconi }, 1887e906103SLorenzo Bianconi }, 18952f4b1f1SMartin Kepplinger }, 19052f4b1f1SMartin Kepplinger { 191d068e4a0SLorenzo Bianconi .wai = 0x69, 19266b662a1SLorenzo Bianconi .reset = { 19366b662a1SLorenzo Bianconi .addr = 0x12, 19466b662a1SLorenzo Bianconi .mask = BIT(0), 19566b662a1SLorenzo Bianconi }, 19666b662a1SLorenzo Bianconi .boot = { 19766b662a1SLorenzo Bianconi .addr = 0x12, 19866b662a1SLorenzo Bianconi .mask = BIT(7), 19966b662a1SLorenzo Bianconi }, 20066b662a1SLorenzo Bianconi .bdu = { 20166b662a1SLorenzo Bianconi .addr = 0x12, 20266b662a1SLorenzo Bianconi .mask = BIT(6), 20366b662a1SLorenzo Bianconi }, 2048f2a88a2SLorenzo Bianconi .max_fifo_size = 1365, 205d068e4a0SLorenzo Bianconi .id = { 20681956a93SLorenzo Bianconi { 20781956a93SLorenzo Bianconi .hw_id = ST_LSM6DS3_ID, 20881956a93SLorenzo Bianconi .name = ST_LSM6DS3_DEV_NAME, 20981956a93SLorenzo Bianconi }, 210d068e4a0SLorenzo Bianconi }, 211f48bc49bSLorenzo Bianconi .channels = { 212f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 213f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 214f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 215f48bc49bSLorenzo Bianconi }, 216f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 217f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 218f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 219f48bc49bSLorenzo Bianconi }, 220f48bc49bSLorenzo Bianconi }, 22140dd7343SLorenzo Bianconi .odr_table = { 22240dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 22340dd7343SLorenzo Bianconi .reg = { 22440dd7343SLorenzo Bianconi .addr = 0x10, 22540dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 22640dd7343SLorenzo Bianconi }, 22740dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 22840dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 22940dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 23040dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 23140dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 23240dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 23340dd7343SLorenzo Bianconi }, 23440dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 23540dd7343SLorenzo Bianconi .reg = { 23640dd7343SLorenzo Bianconi .addr = 0x11, 23740dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 23840dd7343SLorenzo Bianconi }, 23940dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 24040dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 24140dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 24240dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 24340dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 24440dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 24540dd7343SLorenzo Bianconi }, 24640dd7343SLorenzo Bianconi }, 247640aca3fSLorenzo Bianconi .fs_table = { 248640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 249640aca3fSLorenzo Bianconi .reg = { 250640aca3fSLorenzo Bianconi .addr = 0x10, 251640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 252640aca3fSLorenzo Bianconi }, 253640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 254640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 255640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 256640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 25785ae3aeeSLorenzo Bianconi .fs_len = 4, 258640aca3fSLorenzo Bianconi }, 259640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 260640aca3fSLorenzo Bianconi .reg = { 261640aca3fSLorenzo Bianconi .addr = 0x11, 262640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 263640aca3fSLorenzo Bianconi }, 264640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 265640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 266640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 267640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 26885ae3aeeSLorenzo Bianconi .fs_len = 4, 269640aca3fSLorenzo Bianconi }, 270640aca3fSLorenzo Bianconi }, 2717e906103SLorenzo Bianconi .irq_config = { 2727e906103SLorenzo Bianconi .irq1 = { 2737e906103SLorenzo Bianconi .addr = 0x0d, 2747e906103SLorenzo Bianconi .mask = BIT(3), 2757e906103SLorenzo Bianconi }, 2767e906103SLorenzo Bianconi .irq2 = { 2777e906103SLorenzo Bianconi .addr = 0x0e, 2787e906103SLorenzo Bianconi .mask = BIT(3), 2797e906103SLorenzo Bianconi }, 2807e906103SLorenzo Bianconi .lir = { 2817e906103SLorenzo Bianconi .addr = 0x58, 2827e906103SLorenzo Bianconi .mask = BIT(0), 2837e906103SLorenzo Bianconi }, 2847e906103SLorenzo Bianconi .irq1_func = { 2857e906103SLorenzo Bianconi .addr = 0x5e, 2867e906103SLorenzo Bianconi .mask = BIT(5), 2877e906103SLorenzo Bianconi }, 2887e906103SLorenzo Bianconi .irq2_func = { 2897e906103SLorenzo Bianconi .addr = 0x5f, 2907e906103SLorenzo Bianconi .mask = BIT(5), 2917e906103SLorenzo Bianconi }, 29231fe8d4eSLorenzo Bianconi .hla = { 29331fe8d4eSLorenzo Bianconi .addr = 0x12, 29431fe8d4eSLorenzo Bianconi .mask = BIT(5), 29531fe8d4eSLorenzo Bianconi }, 29631fe8d4eSLorenzo Bianconi .od = { 29731fe8d4eSLorenzo Bianconi .addr = 0x12, 29831fe8d4eSLorenzo Bianconi .mask = BIT(4), 29931fe8d4eSLorenzo Bianconi }, 3007e906103SLorenzo Bianconi }, 3017ca3ac9eSLorenzo Bianconi .decimator = { 3027ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 3037ca3ac9eSLorenzo Bianconi .addr = 0x08, 3047ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 3057ca3ac9eSLorenzo Bianconi }, 3067ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 3077ca3ac9eSLorenzo Bianconi .addr = 0x08, 3087ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 3097ca3ac9eSLorenzo Bianconi }, 3107ca3ac9eSLorenzo Bianconi }, 31192617c15SLorenzo Bianconi .fifo_ops = { 3123b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 31350ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 31492617c15SLorenzo Bianconi .fifo_th = { 31592617c15SLorenzo Bianconi .addr = 0x06, 31692617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 31792617c15SLorenzo Bianconi }, 31892617c15SLorenzo Bianconi .fifo_diff = { 31992617c15SLorenzo Bianconi .addr = 0x3a, 32092617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 32192617c15SLorenzo Bianconi }, 32292617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 32392617c15SLorenzo Bianconi }, 32421345107SLorenzo Bianconi .ts_settings = { 32521345107SLorenzo Bianconi .timer_en = { 32621345107SLorenzo Bianconi .addr = 0x58, 32721345107SLorenzo Bianconi .mask = BIT(7), 32821345107SLorenzo Bianconi }, 32921345107SLorenzo Bianconi .hr_timer = { 33021345107SLorenzo Bianconi .addr = 0x5c, 33121345107SLorenzo Bianconi .mask = BIT(4), 33221345107SLorenzo Bianconi }, 33321345107SLorenzo Bianconi .fifo_en = { 33421345107SLorenzo Bianconi .addr = 0x07, 33521345107SLorenzo Bianconi .mask = BIT(7), 33621345107SLorenzo Bianconi }, 33721345107SLorenzo Bianconi .decimator = { 33821345107SLorenzo Bianconi .addr = 0x09, 33921345107SLorenzo Bianconi .mask = GENMASK(5, 3), 34021345107SLorenzo Bianconi }, 34121345107SLorenzo Bianconi }, 342b5969abfSSean Nyekjaer .event_settings = { 343b5969abfSSean Nyekjaer .wakeup_reg = { 344b5969abfSSean Nyekjaer .addr = 0x5B, 345b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 346b5969abfSSean Nyekjaer }, 3471aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 3481aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 3491aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 3501aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 3511aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 352b5969abfSSean Nyekjaer }, 353290a6ce1SLorenzo Bianconi }, 354290a6ce1SLorenzo Bianconi { 355df47710aSLorenzo Bianconi .wai = 0x69, 35666b662a1SLorenzo Bianconi .reset = { 35766b662a1SLorenzo Bianconi .addr = 0x12, 35866b662a1SLorenzo Bianconi .mask = BIT(0), 35966b662a1SLorenzo Bianconi }, 36066b662a1SLorenzo Bianconi .boot = { 36166b662a1SLorenzo Bianconi .addr = 0x12, 36266b662a1SLorenzo Bianconi .mask = BIT(7), 36366b662a1SLorenzo Bianconi }, 36466b662a1SLorenzo Bianconi .bdu = { 36566b662a1SLorenzo Bianconi .addr = 0x12, 36666b662a1SLorenzo Bianconi .mask = BIT(6), 36766b662a1SLorenzo Bianconi }, 3688f2a88a2SLorenzo Bianconi .max_fifo_size = 682, 369df47710aSLorenzo Bianconi .id = { 37081956a93SLorenzo Bianconi { 37181956a93SLorenzo Bianconi .hw_id = ST_LSM6DS3H_ID, 37281956a93SLorenzo Bianconi .name = ST_LSM6DS3H_DEV_NAME, 37381956a93SLorenzo Bianconi }, 374df47710aSLorenzo Bianconi }, 375f48bc49bSLorenzo Bianconi .channels = { 376f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 377f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 378f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 379f48bc49bSLorenzo Bianconi }, 380f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 381f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 382f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 383f48bc49bSLorenzo Bianconi }, 384f48bc49bSLorenzo Bianconi }, 38540dd7343SLorenzo Bianconi .odr_table = { 38640dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 38740dd7343SLorenzo Bianconi .reg = { 38840dd7343SLorenzo Bianconi .addr = 0x10, 38940dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 39040dd7343SLorenzo Bianconi }, 39140dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 39240dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 39340dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 39440dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 39540dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 39640dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 39740dd7343SLorenzo Bianconi }, 39840dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 39940dd7343SLorenzo Bianconi .reg = { 40040dd7343SLorenzo Bianconi .addr = 0x11, 40140dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 40240dd7343SLorenzo Bianconi }, 40340dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 40440dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 40540dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 40640dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 40740dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 40840dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 40940dd7343SLorenzo Bianconi }, 41040dd7343SLorenzo Bianconi }, 411640aca3fSLorenzo Bianconi .fs_table = { 412640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 413640aca3fSLorenzo Bianconi .reg = { 414640aca3fSLorenzo Bianconi .addr = 0x10, 415640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 416640aca3fSLorenzo Bianconi }, 417640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 418640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 419640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 420640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 42185ae3aeeSLorenzo Bianconi .fs_len = 4, 422640aca3fSLorenzo Bianconi }, 423640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 424640aca3fSLorenzo Bianconi .reg = { 425640aca3fSLorenzo Bianconi .addr = 0x11, 426640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 427640aca3fSLorenzo Bianconi }, 428640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 429640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 430640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 431640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 43285ae3aeeSLorenzo Bianconi .fs_len = 4, 433640aca3fSLorenzo Bianconi }, 434640aca3fSLorenzo Bianconi }, 4357e906103SLorenzo Bianconi .irq_config = { 4367e906103SLorenzo Bianconi .irq1 = { 4377e906103SLorenzo Bianconi .addr = 0x0d, 4387e906103SLorenzo Bianconi .mask = BIT(3), 4397e906103SLorenzo Bianconi }, 4407e906103SLorenzo Bianconi .irq2 = { 4417e906103SLorenzo Bianconi .addr = 0x0e, 4427e906103SLorenzo Bianconi .mask = BIT(3), 4437e906103SLorenzo Bianconi }, 4447e906103SLorenzo Bianconi .lir = { 4457e906103SLorenzo Bianconi .addr = 0x58, 4467e906103SLorenzo Bianconi .mask = BIT(0), 4477e906103SLorenzo Bianconi }, 4487e906103SLorenzo Bianconi .irq1_func = { 4497e906103SLorenzo Bianconi .addr = 0x5e, 4507e906103SLorenzo Bianconi .mask = BIT(5), 4517e906103SLorenzo Bianconi }, 4527e906103SLorenzo Bianconi .irq2_func = { 4537e906103SLorenzo Bianconi .addr = 0x5f, 4547e906103SLorenzo Bianconi .mask = BIT(5), 4557e906103SLorenzo Bianconi }, 45631fe8d4eSLorenzo Bianconi .hla = { 45731fe8d4eSLorenzo Bianconi .addr = 0x12, 45831fe8d4eSLorenzo Bianconi .mask = BIT(5), 45931fe8d4eSLorenzo Bianconi }, 46031fe8d4eSLorenzo Bianconi .od = { 46131fe8d4eSLorenzo Bianconi .addr = 0x12, 46231fe8d4eSLorenzo Bianconi .mask = BIT(4), 46331fe8d4eSLorenzo Bianconi }, 4647e906103SLorenzo Bianconi }, 4657ca3ac9eSLorenzo Bianconi .decimator = { 4667ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 4677ca3ac9eSLorenzo Bianconi .addr = 0x08, 4687ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 4697ca3ac9eSLorenzo Bianconi }, 4707ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 4717ca3ac9eSLorenzo Bianconi .addr = 0x08, 4727ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 4737ca3ac9eSLorenzo Bianconi }, 4747ca3ac9eSLorenzo Bianconi }, 47592617c15SLorenzo Bianconi .fifo_ops = { 4763b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 47750ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 47892617c15SLorenzo Bianconi .fifo_th = { 47992617c15SLorenzo Bianconi .addr = 0x06, 48092617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 48192617c15SLorenzo Bianconi }, 48292617c15SLorenzo Bianconi .fifo_diff = { 48392617c15SLorenzo Bianconi .addr = 0x3a, 48492617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 48592617c15SLorenzo Bianconi }, 48692617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 48792617c15SLorenzo Bianconi }, 48821345107SLorenzo Bianconi .ts_settings = { 48921345107SLorenzo Bianconi .timer_en = { 49021345107SLorenzo Bianconi .addr = 0x58, 49121345107SLorenzo Bianconi .mask = BIT(7), 49221345107SLorenzo Bianconi }, 49321345107SLorenzo Bianconi .hr_timer = { 49421345107SLorenzo Bianconi .addr = 0x5c, 49521345107SLorenzo Bianconi .mask = BIT(4), 49621345107SLorenzo Bianconi }, 49721345107SLorenzo Bianconi .fifo_en = { 49821345107SLorenzo Bianconi .addr = 0x07, 49921345107SLorenzo Bianconi .mask = BIT(7), 50021345107SLorenzo Bianconi }, 50121345107SLorenzo Bianconi .decimator = { 50221345107SLorenzo Bianconi .addr = 0x09, 50321345107SLorenzo Bianconi .mask = GENMASK(5, 3), 50421345107SLorenzo Bianconi }, 50521345107SLorenzo Bianconi }, 506b5969abfSSean Nyekjaer .event_settings = { 507b5969abfSSean Nyekjaer .wakeup_reg = { 508b5969abfSSean Nyekjaer .addr = 0x5B, 509b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 510b5969abfSSean Nyekjaer }, 5111aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 5121aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 5131aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 5141aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 5151aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 516b5969abfSSean Nyekjaer }, 517df47710aSLorenzo Bianconi }, 518df47710aSLorenzo Bianconi { 519d068e4a0SLorenzo Bianconi .wai = 0x6a, 52066b662a1SLorenzo Bianconi .reset = { 52166b662a1SLorenzo Bianconi .addr = 0x12, 52266b662a1SLorenzo Bianconi .mask = BIT(0), 52366b662a1SLorenzo Bianconi }, 52466b662a1SLorenzo Bianconi .boot = { 52566b662a1SLorenzo Bianconi .addr = 0x12, 52666b662a1SLorenzo Bianconi .mask = BIT(7), 52766b662a1SLorenzo Bianconi }, 52866b662a1SLorenzo Bianconi .bdu = { 52966b662a1SLorenzo Bianconi .addr = 0x12, 53066b662a1SLorenzo Bianconi .mask = BIT(6), 53166b662a1SLorenzo Bianconi }, 5328f2a88a2SLorenzo Bianconi .max_fifo_size = 682, 533d068e4a0SLorenzo Bianconi .id = { 53481956a93SLorenzo Bianconi { 53581956a93SLorenzo Bianconi .hw_id = ST_LSM6DSL_ID, 53681956a93SLorenzo Bianconi .name = ST_LSM6DSL_DEV_NAME, 53781956a93SLorenzo Bianconi }, { 53881956a93SLorenzo Bianconi .hw_id = ST_LSM6DSM_ID, 53981956a93SLorenzo Bianconi .name = ST_LSM6DSM_DEV_NAME, 54081956a93SLorenzo Bianconi }, { 54181956a93SLorenzo Bianconi .hw_id = ST_ISM330DLC_ID, 54281956a93SLorenzo Bianconi .name = ST_ISM330DLC_DEV_NAME, 543dbcd2088SLorenzo Bianconi }, { 544dbcd2088SLorenzo Bianconi .hw_id = ST_LSM6DS3TRC_ID, 545dbcd2088SLorenzo Bianconi .name = ST_LSM6DS3TRC_DEV_NAME, 54681956a93SLorenzo Bianconi }, 547d068e4a0SLorenzo Bianconi }, 548f48bc49bSLorenzo Bianconi .channels = { 549f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 550f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 551f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 552f48bc49bSLorenzo Bianconi }, 553f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 554f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 555f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 556f48bc49bSLorenzo Bianconi }, 557f48bc49bSLorenzo Bianconi }, 55840dd7343SLorenzo Bianconi .odr_table = { 55940dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 56040dd7343SLorenzo Bianconi .reg = { 56140dd7343SLorenzo Bianconi .addr = 0x10, 56240dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 56340dd7343SLorenzo Bianconi }, 56440dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 56540dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 56640dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 56740dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 56840dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 56940dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 57040dd7343SLorenzo Bianconi }, 57140dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 57240dd7343SLorenzo Bianconi .reg = { 57340dd7343SLorenzo Bianconi .addr = 0x11, 57440dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 57540dd7343SLorenzo Bianconi }, 57640dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 57740dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 57840dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 57940dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 58040dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 58140dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 58240dd7343SLorenzo Bianconi }, 58340dd7343SLorenzo Bianconi }, 584640aca3fSLorenzo Bianconi .fs_table = { 585640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 586640aca3fSLorenzo Bianconi .reg = { 587640aca3fSLorenzo Bianconi .addr = 0x10, 588640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 589640aca3fSLorenzo Bianconi }, 590640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 591640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 592640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 593640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 59485ae3aeeSLorenzo Bianconi .fs_len = 4, 595640aca3fSLorenzo Bianconi }, 596640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 597640aca3fSLorenzo Bianconi .reg = { 598640aca3fSLorenzo Bianconi .addr = 0x11, 599640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 600640aca3fSLorenzo Bianconi }, 601640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 602640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 603640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 604640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 60585ae3aeeSLorenzo Bianconi .fs_len = 4, 606640aca3fSLorenzo Bianconi }, 607640aca3fSLorenzo Bianconi }, 6087e906103SLorenzo Bianconi .irq_config = { 6097e906103SLorenzo Bianconi .irq1 = { 6107e906103SLorenzo Bianconi .addr = 0x0d, 6117e906103SLorenzo Bianconi .mask = BIT(3), 6127e906103SLorenzo Bianconi }, 6137e906103SLorenzo Bianconi .irq2 = { 6147e906103SLorenzo Bianconi .addr = 0x0e, 6157e906103SLorenzo Bianconi .mask = BIT(3), 6167e906103SLorenzo Bianconi }, 6177e906103SLorenzo Bianconi .lir = { 6187e906103SLorenzo Bianconi .addr = 0x58, 6197e906103SLorenzo Bianconi .mask = BIT(0), 6207e906103SLorenzo Bianconi }, 6217e906103SLorenzo Bianconi .irq1_func = { 6227e906103SLorenzo Bianconi .addr = 0x5e, 6237e906103SLorenzo Bianconi .mask = BIT(5), 6247e906103SLorenzo Bianconi }, 6257e906103SLorenzo Bianconi .irq2_func = { 6267e906103SLorenzo Bianconi .addr = 0x5f, 6277e906103SLorenzo Bianconi .mask = BIT(5), 6287e906103SLorenzo Bianconi }, 62931fe8d4eSLorenzo Bianconi .hla = { 63031fe8d4eSLorenzo Bianconi .addr = 0x12, 63131fe8d4eSLorenzo Bianconi .mask = BIT(5), 63231fe8d4eSLorenzo Bianconi }, 63331fe8d4eSLorenzo Bianconi .od = { 63431fe8d4eSLorenzo Bianconi .addr = 0x12, 63531fe8d4eSLorenzo Bianconi .mask = BIT(4), 63631fe8d4eSLorenzo Bianconi }, 6377e906103SLorenzo Bianconi }, 6387ca3ac9eSLorenzo Bianconi .decimator = { 6397ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 6407ca3ac9eSLorenzo Bianconi .addr = 0x08, 6417ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 6427ca3ac9eSLorenzo Bianconi }, 6437ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 6447ca3ac9eSLorenzo Bianconi .addr = 0x08, 6457ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 6467ca3ac9eSLorenzo Bianconi }, 6477ca3ac9eSLorenzo Bianconi }, 64892617c15SLorenzo Bianconi .fifo_ops = { 6493b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 65050ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 65192617c15SLorenzo Bianconi .fifo_th = { 65292617c15SLorenzo Bianconi .addr = 0x06, 653be75eb86SLorenzo Bianconi .mask = GENMASK(10, 0), 65492617c15SLorenzo Bianconi }, 65592617c15SLorenzo Bianconi .fifo_diff = { 65692617c15SLorenzo Bianconi .addr = 0x3a, 657be75eb86SLorenzo Bianconi .mask = GENMASK(10, 0), 65892617c15SLorenzo Bianconi }, 65992617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 66092617c15SLorenzo Bianconi }, 66121345107SLorenzo Bianconi .ts_settings = { 66221345107SLorenzo Bianconi .timer_en = { 66321345107SLorenzo Bianconi .addr = 0x19, 66421345107SLorenzo Bianconi .mask = BIT(5), 66521345107SLorenzo Bianconi }, 66621345107SLorenzo Bianconi .hr_timer = { 66721345107SLorenzo Bianconi .addr = 0x5c, 66821345107SLorenzo Bianconi .mask = BIT(4), 66921345107SLorenzo Bianconi }, 67021345107SLorenzo Bianconi .fifo_en = { 67121345107SLorenzo Bianconi .addr = 0x07, 67221345107SLorenzo Bianconi .mask = BIT(7), 67321345107SLorenzo Bianconi }, 67421345107SLorenzo Bianconi .decimator = { 67521345107SLorenzo Bianconi .addr = 0x09, 67621345107SLorenzo Bianconi .mask = GENMASK(5, 3), 67721345107SLorenzo Bianconi }, 67821345107SLorenzo Bianconi }, 679b5969abfSSean Nyekjaer .event_settings = { 680b5969abfSSean Nyekjaer .enable_reg = { 681b5969abfSSean Nyekjaer .addr = 0x58, 682b5969abfSSean Nyekjaer .mask = BIT(7), 683b5969abfSSean Nyekjaer }, 684b5969abfSSean Nyekjaer .wakeup_reg = { 685b5969abfSSean Nyekjaer .addr = 0x5B, 686b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 687b5969abfSSean Nyekjaer }, 6881aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 6891aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 6901aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 6911aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 6921aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 693b5969abfSSean Nyekjaer }, 694290a6ce1SLorenzo Bianconi }, 695801a6e0aSLorenzo Bianconi { 696801a6e0aSLorenzo Bianconi .wai = 0x6c, 69766b662a1SLorenzo Bianconi .reset = { 69866b662a1SLorenzo Bianconi .addr = 0x12, 69966b662a1SLorenzo Bianconi .mask = BIT(0), 70066b662a1SLorenzo Bianconi }, 70166b662a1SLorenzo Bianconi .boot = { 70266b662a1SLorenzo Bianconi .addr = 0x12, 70366b662a1SLorenzo Bianconi .mask = BIT(7), 70466b662a1SLorenzo Bianconi }, 70566b662a1SLorenzo Bianconi .bdu = { 70666b662a1SLorenzo Bianconi .addr = 0x12, 70766b662a1SLorenzo Bianconi .mask = BIT(6), 70866b662a1SLorenzo Bianconi }, 709801a6e0aSLorenzo Bianconi .max_fifo_size = 512, 710801a6e0aSLorenzo Bianconi .id = { 71181956a93SLorenzo Bianconi { 71281956a93SLorenzo Bianconi .hw_id = ST_LSM6DSO_ID, 71381956a93SLorenzo Bianconi .name = ST_LSM6DSO_DEV_NAME, 71481956a93SLorenzo Bianconi }, { 71581956a93SLorenzo Bianconi .hw_id = ST_LSM6DSOX_ID, 71681956a93SLorenzo Bianconi .name = ST_LSM6DSOX_DEV_NAME, 71781956a93SLorenzo Bianconi }, 718801a6e0aSLorenzo Bianconi }, 719f48bc49bSLorenzo Bianconi .channels = { 720f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 721f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 722f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 723f48bc49bSLorenzo Bianconi }, 724f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 725f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 726f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 727f48bc49bSLorenzo Bianconi }, 728f48bc49bSLorenzo Bianconi }, 729960506edSLorenzo Bianconi .drdy_mask = { 730960506edSLorenzo Bianconi .addr = 0x13, 731960506edSLorenzo Bianconi .mask = BIT(3), 732960506edSLorenzo Bianconi }, 73340dd7343SLorenzo Bianconi .odr_table = { 73440dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 73540dd7343SLorenzo Bianconi .reg = { 73640dd7343SLorenzo Bianconi .addr = 0x10, 73740dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 73840dd7343SLorenzo Bianconi }, 73940dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 74040dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 74140dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 74240dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 74340dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 74440dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 74540dd7343SLorenzo Bianconi }, 74640dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 74740dd7343SLorenzo Bianconi .reg = { 74840dd7343SLorenzo Bianconi .addr = 0x11, 74940dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 75040dd7343SLorenzo Bianconi }, 75140dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 75240dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 75340dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 75440dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 75540dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 75640dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 75740dd7343SLorenzo Bianconi }, 75840dd7343SLorenzo Bianconi }, 759640aca3fSLorenzo Bianconi .fs_table = { 760640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 761640aca3fSLorenzo Bianconi .reg = { 762640aca3fSLorenzo Bianconi .addr = 0x10, 763640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 764640aca3fSLorenzo Bianconi }, 765640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 766640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 767640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 768640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 76985ae3aeeSLorenzo Bianconi .fs_len = 4, 770640aca3fSLorenzo Bianconi }, 771640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 772640aca3fSLorenzo Bianconi .reg = { 773640aca3fSLorenzo Bianconi .addr = 0x11, 774640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 775640aca3fSLorenzo Bianconi }, 776640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 777640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 778640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 779640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 78085ae3aeeSLorenzo Bianconi .fs_len = 4, 781640aca3fSLorenzo Bianconi }, 782640aca3fSLorenzo Bianconi }, 7837e906103SLorenzo Bianconi .irq_config = { 7847e906103SLorenzo Bianconi .irq1 = { 7857e906103SLorenzo Bianconi .addr = 0x0d, 7867e906103SLorenzo Bianconi .mask = BIT(3), 7877e906103SLorenzo Bianconi }, 7887e906103SLorenzo Bianconi .irq2 = { 7897e906103SLorenzo Bianconi .addr = 0x0e, 7907e906103SLorenzo Bianconi .mask = BIT(3), 7917e906103SLorenzo Bianconi }, 7927e906103SLorenzo Bianconi .lir = { 7937e906103SLorenzo Bianconi .addr = 0x56, 7947e906103SLorenzo Bianconi .mask = BIT(0), 7957e906103SLorenzo Bianconi }, 7967e906103SLorenzo Bianconi .clear_on_read = { 7977e906103SLorenzo Bianconi .addr = 0x56, 7987e906103SLorenzo Bianconi .mask = BIT(6), 7997e906103SLorenzo Bianconi }, 8003ea39d61SLorenzo Bianconi .irq1_func = { 8013ea39d61SLorenzo Bianconi .addr = 0x5e, 8023ea39d61SLorenzo Bianconi .mask = BIT(5), 8033ea39d61SLorenzo Bianconi }, 8043ea39d61SLorenzo Bianconi .irq2_func = { 8053ea39d61SLorenzo Bianconi .addr = 0x5f, 8063ea39d61SLorenzo Bianconi .mask = BIT(5), 8073ea39d61SLorenzo Bianconi }, 80831fe8d4eSLorenzo Bianconi .hla = { 80931fe8d4eSLorenzo Bianconi .addr = 0x12, 81031fe8d4eSLorenzo Bianconi .mask = BIT(5), 81131fe8d4eSLorenzo Bianconi }, 81231fe8d4eSLorenzo Bianconi .od = { 81331fe8d4eSLorenzo Bianconi .addr = 0x12, 81431fe8d4eSLorenzo Bianconi .mask = BIT(4), 81531fe8d4eSLorenzo Bianconi }, 8167e906103SLorenzo Bianconi }, 817801a6e0aSLorenzo Bianconi .batch = { 818801a6e0aSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 819801a6e0aSLorenzo Bianconi .addr = 0x09, 820801a6e0aSLorenzo Bianconi .mask = GENMASK(3, 0), 821801a6e0aSLorenzo Bianconi }, 822801a6e0aSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 823801a6e0aSLorenzo Bianconi .addr = 0x09, 824801a6e0aSLorenzo Bianconi .mask = GENMASK(7, 4), 825801a6e0aSLorenzo Bianconi }, 826801a6e0aSLorenzo Bianconi }, 827801a6e0aSLorenzo Bianconi .fifo_ops = { 8283b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 829801a6e0aSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 830801a6e0aSLorenzo Bianconi .fifo_th = { 831801a6e0aSLorenzo Bianconi .addr = 0x07, 832801a6e0aSLorenzo Bianconi .mask = GENMASK(8, 0), 833801a6e0aSLorenzo Bianconi }, 834801a6e0aSLorenzo Bianconi .fifo_diff = { 835801a6e0aSLorenzo Bianconi .addr = 0x3a, 83670575abeSmario tesi .mask = GENMASK(9, 0), 837801a6e0aSLorenzo Bianconi }, 838801a6e0aSLorenzo Bianconi .th_wl = 1, 839801a6e0aSLorenzo Bianconi }, 840801a6e0aSLorenzo Bianconi .ts_settings = { 841801a6e0aSLorenzo Bianconi .timer_en = { 842801a6e0aSLorenzo Bianconi .addr = 0x19, 843801a6e0aSLorenzo Bianconi .mask = BIT(5), 844801a6e0aSLorenzo Bianconi }, 845801a6e0aSLorenzo Bianconi .decimator = { 846801a6e0aSLorenzo Bianconi .addr = 0x0a, 847801a6e0aSLorenzo Bianconi .mask = GENMASK(7, 6), 848801a6e0aSLorenzo Bianconi }, 849cb3b6b8eSMario Tesi .freq_fine = 0x63, 850801a6e0aSLorenzo Bianconi }, 851c91c1c84SLorenzo Bianconi .shub_settings = { 852c91c1c84SLorenzo Bianconi .page_mux = { 853c91c1c84SLorenzo Bianconi .addr = 0x01, 854c91c1c84SLorenzo Bianconi .mask = BIT(6), 855c91c1c84SLorenzo Bianconi }, 856c91c1c84SLorenzo Bianconi .master_en = { 857c91c1c84SLorenzo Bianconi .addr = 0x14, 858c91c1c84SLorenzo Bianconi .mask = BIT(2), 859c91c1c84SLorenzo Bianconi }, 860c91c1c84SLorenzo Bianconi .pullup_en = { 861c91c1c84SLorenzo Bianconi .addr = 0x14, 862c91c1c84SLorenzo Bianconi .mask = BIT(3), 863c91c1c84SLorenzo Bianconi }, 864c91c1c84SLorenzo Bianconi .aux_sens = { 865c91c1c84SLorenzo Bianconi .addr = 0x14, 866c91c1c84SLorenzo Bianconi .mask = GENMASK(1, 0), 867c91c1c84SLorenzo Bianconi }, 8686d0205fdSLorenzo Bianconi .wr_once = { 8696d0205fdSLorenzo Bianconi .addr = 0x14, 8706d0205fdSLorenzo Bianconi .mask = BIT(6), 8716d0205fdSLorenzo Bianconi }, 872c91c1c84SLorenzo Bianconi .shub_out = 0x02, 873c91c1c84SLorenzo Bianconi .slv0_addr = 0x15, 874c91c1c84SLorenzo Bianconi .dw_slv0_addr = 0x21, 8756d0205fdSLorenzo Bianconi .batch_en = BIT(3), 8763ea39d61SLorenzo Bianconi }, 8773ea39d61SLorenzo Bianconi .event_settings = { 8783ea39d61SLorenzo Bianconi .enable_reg = { 8793ea39d61SLorenzo Bianconi .addr = 0x58, 8803ea39d61SLorenzo Bianconi .mask = BIT(7), 8813ea39d61SLorenzo Bianconi }, 8823ea39d61SLorenzo Bianconi .wakeup_reg = { 8833ea39d61SLorenzo Bianconi .addr = 0x5b, 8843ea39d61SLorenzo Bianconi .mask = GENMASK(5, 0), 8853ea39d61SLorenzo Bianconi }, 8863ea39d61SLorenzo Bianconi .wakeup_src_reg = 0x1b, 8873ea39d61SLorenzo Bianconi .wakeup_src_status_mask = BIT(3), 8883ea39d61SLorenzo Bianconi .wakeup_src_z_mask = BIT(0), 8893ea39d61SLorenzo Bianconi .wakeup_src_y_mask = BIT(1), 8903ea39d61SLorenzo Bianconi .wakeup_src_x_mask = BIT(2), 8913ea39d61SLorenzo Bianconi }, 892801a6e0aSLorenzo Bianconi }, 8933054c4ffSLorenzo Bianconi { 8943054c4ffSLorenzo Bianconi .wai = 0x6b, 89566b662a1SLorenzo Bianconi .reset = { 89666b662a1SLorenzo Bianconi .addr = 0x12, 89766b662a1SLorenzo Bianconi .mask = BIT(0), 89866b662a1SLorenzo Bianconi }, 89966b662a1SLorenzo Bianconi .boot = { 90066b662a1SLorenzo Bianconi .addr = 0x12, 90166b662a1SLorenzo Bianconi .mask = BIT(7), 90266b662a1SLorenzo Bianconi }, 90366b662a1SLorenzo Bianconi .bdu = { 90466b662a1SLorenzo Bianconi .addr = 0x12, 90566b662a1SLorenzo Bianconi .mask = BIT(6), 90666b662a1SLorenzo Bianconi }, 9073054c4ffSLorenzo Bianconi .max_fifo_size = 512, 9083054c4ffSLorenzo Bianconi .id = { 90981956a93SLorenzo Bianconi { 91081956a93SLorenzo Bianconi .hw_id = ST_ASM330LHH_ID, 91181956a93SLorenzo Bianconi .name = ST_ASM330LHH_DEV_NAME, 91281956a93SLorenzo Bianconi }, 9133054c4ffSLorenzo Bianconi }, 914f48bc49bSLorenzo Bianconi .channels = { 915f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 916f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 917f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 918f48bc49bSLorenzo Bianconi }, 919f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 920f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 921f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 922f48bc49bSLorenzo Bianconi }, 923f48bc49bSLorenzo Bianconi }, 924960506edSLorenzo Bianconi .drdy_mask = { 925960506edSLorenzo Bianconi .addr = 0x13, 926960506edSLorenzo Bianconi .mask = BIT(3), 927960506edSLorenzo Bianconi }, 92840dd7343SLorenzo Bianconi .odr_table = { 92940dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 93040dd7343SLorenzo Bianconi .reg = { 93140dd7343SLorenzo Bianconi .addr = 0x10, 93240dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 93340dd7343SLorenzo Bianconi }, 93440dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 93540dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 93640dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 93740dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 93840dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 93940dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 94040dd7343SLorenzo Bianconi }, 94140dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 94240dd7343SLorenzo Bianconi .reg = { 94340dd7343SLorenzo Bianconi .addr = 0x11, 94440dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 94540dd7343SLorenzo Bianconi }, 94640dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 94740dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 94840dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 94940dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 95040dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 95140dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 95240dd7343SLorenzo Bianconi }, 95340dd7343SLorenzo Bianconi }, 954640aca3fSLorenzo Bianconi .fs_table = { 955640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 956640aca3fSLorenzo Bianconi .reg = { 957640aca3fSLorenzo Bianconi .addr = 0x10, 958640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 959640aca3fSLorenzo Bianconi }, 960640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 961640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 962640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 963640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 96485ae3aeeSLorenzo Bianconi .fs_len = 4, 965640aca3fSLorenzo Bianconi }, 966640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 967640aca3fSLorenzo Bianconi .reg = { 968640aca3fSLorenzo Bianconi .addr = 0x11, 969640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 970640aca3fSLorenzo Bianconi }, 971640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 972640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 973640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 974640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 97585ae3aeeSLorenzo Bianconi .fs_len = 4, 976640aca3fSLorenzo Bianconi }, 977640aca3fSLorenzo Bianconi }, 9787e906103SLorenzo Bianconi .irq_config = { 9797e906103SLorenzo Bianconi .irq1 = { 9807e906103SLorenzo Bianconi .addr = 0x0d, 9817e906103SLorenzo Bianconi .mask = BIT(3), 9827e906103SLorenzo Bianconi }, 9837e906103SLorenzo Bianconi .irq2 = { 9847e906103SLorenzo Bianconi .addr = 0x0e, 9857e906103SLorenzo Bianconi .mask = BIT(3), 9867e906103SLorenzo Bianconi }, 9877e906103SLorenzo Bianconi .lir = { 9887e906103SLorenzo Bianconi .addr = 0x56, 9897e906103SLorenzo Bianconi .mask = BIT(0), 9907e906103SLorenzo Bianconi }, 9917e906103SLorenzo Bianconi .clear_on_read = { 9927e906103SLorenzo Bianconi .addr = 0x56, 9937e906103SLorenzo Bianconi .mask = BIT(6), 9947e906103SLorenzo Bianconi }, 9957e906103SLorenzo Bianconi .irq1_func = { 9967e906103SLorenzo Bianconi .addr = 0x5e, 9977e906103SLorenzo Bianconi .mask = BIT(5), 9987e906103SLorenzo Bianconi }, 9997e906103SLorenzo Bianconi .irq2_func = { 10007e906103SLorenzo Bianconi .addr = 0x5f, 10017e906103SLorenzo Bianconi .mask = BIT(5), 10027e906103SLorenzo Bianconi }, 100331fe8d4eSLorenzo Bianconi .hla = { 100431fe8d4eSLorenzo Bianconi .addr = 0x12, 100531fe8d4eSLorenzo Bianconi .mask = BIT(5), 100631fe8d4eSLorenzo Bianconi }, 100731fe8d4eSLorenzo Bianconi .od = { 100831fe8d4eSLorenzo Bianconi .addr = 0x12, 100931fe8d4eSLorenzo Bianconi .mask = BIT(4), 101031fe8d4eSLorenzo Bianconi }, 10117e906103SLorenzo Bianconi }, 10123054c4ffSLorenzo Bianconi .batch = { 10133054c4ffSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 10143054c4ffSLorenzo Bianconi .addr = 0x09, 10153054c4ffSLorenzo Bianconi .mask = GENMASK(3, 0), 10163054c4ffSLorenzo Bianconi }, 10173054c4ffSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 10183054c4ffSLorenzo Bianconi .addr = 0x09, 10193054c4ffSLorenzo Bianconi .mask = GENMASK(7, 4), 10203054c4ffSLorenzo Bianconi }, 10213054c4ffSLorenzo Bianconi }, 10223054c4ffSLorenzo Bianconi .fifo_ops = { 10233b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 10243054c4ffSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 10253054c4ffSLorenzo Bianconi .fifo_th = { 10263054c4ffSLorenzo Bianconi .addr = 0x07, 10273054c4ffSLorenzo Bianconi .mask = GENMASK(8, 0), 10283054c4ffSLorenzo Bianconi }, 10293054c4ffSLorenzo Bianconi .fifo_diff = { 10303054c4ffSLorenzo Bianconi .addr = 0x3a, 103170575abeSmario tesi .mask = GENMASK(9, 0), 10323054c4ffSLorenzo Bianconi }, 10333054c4ffSLorenzo Bianconi .th_wl = 1, 10343054c4ffSLorenzo Bianconi }, 10353054c4ffSLorenzo Bianconi .ts_settings = { 10363054c4ffSLorenzo Bianconi .timer_en = { 10373054c4ffSLorenzo Bianconi .addr = 0x19, 10383054c4ffSLorenzo Bianconi .mask = BIT(5), 10393054c4ffSLorenzo Bianconi }, 10403054c4ffSLorenzo Bianconi .decimator = { 10413054c4ffSLorenzo Bianconi .addr = 0x0a, 10423054c4ffSLorenzo Bianconi .mask = GENMASK(7, 6), 10433054c4ffSLorenzo Bianconi }, 1044cb3b6b8eSMario Tesi .freq_fine = 0x63, 10453054c4ffSLorenzo Bianconi }, 1046b5969abfSSean Nyekjaer .event_settings = { 1047b5969abfSSean Nyekjaer .enable_reg = { 1048b5969abfSSean Nyekjaer .addr = 0x58, 1049b5969abfSSean Nyekjaer .mask = BIT(7), 1050b5969abfSSean Nyekjaer }, 1051b5969abfSSean Nyekjaer .wakeup_reg = { 1052b5969abfSSean Nyekjaer .addr = 0x5B, 1053b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 1054b5969abfSSean Nyekjaer }, 10551aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 10561aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 10571aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 10581aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 10591aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 1060b5969abfSSean Nyekjaer }, 10613054c4ffSLorenzo Bianconi }, 106243901008SLorenzo Bianconi { 106343901008SLorenzo Bianconi .wai = 0x6b, 106466b662a1SLorenzo Bianconi .reset = { 106566b662a1SLorenzo Bianconi .addr = 0x12, 106666b662a1SLorenzo Bianconi .mask = BIT(0), 106766b662a1SLorenzo Bianconi }, 106866b662a1SLorenzo Bianconi .boot = { 106966b662a1SLorenzo Bianconi .addr = 0x12, 107066b662a1SLorenzo Bianconi .mask = BIT(7), 107166b662a1SLorenzo Bianconi }, 107266b662a1SLorenzo Bianconi .bdu = { 107366b662a1SLorenzo Bianconi .addr = 0x12, 107466b662a1SLorenzo Bianconi .mask = BIT(6), 107566b662a1SLorenzo Bianconi }, 107643901008SLorenzo Bianconi .max_fifo_size = 512, 107743901008SLorenzo Bianconi .id = { 107881956a93SLorenzo Bianconi { 107981956a93SLorenzo Bianconi .hw_id = ST_LSM6DSR_ID, 108081956a93SLorenzo Bianconi .name = ST_LSM6DSR_DEV_NAME, 1081db947a79SLorenzo Bianconi }, { 1082db947a79SLorenzo Bianconi .hw_id = ST_ISM330DHCX_ID, 1083db947a79SLorenzo Bianconi .name = ST_ISM330DHCX_DEV_NAME, 108481956a93SLorenzo Bianconi }, 108543901008SLorenzo Bianconi }, 1086f48bc49bSLorenzo Bianconi .channels = { 1087f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 1088f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 1089f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 1090f48bc49bSLorenzo Bianconi }, 1091f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 1092f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 1093f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 1094f48bc49bSLorenzo Bianconi }, 1095f48bc49bSLorenzo Bianconi }, 1096960506edSLorenzo Bianconi .drdy_mask = { 1097960506edSLorenzo Bianconi .addr = 0x13, 1098960506edSLorenzo Bianconi .mask = BIT(3), 1099960506edSLorenzo Bianconi }, 110040dd7343SLorenzo Bianconi .odr_table = { 110140dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 110240dd7343SLorenzo Bianconi .reg = { 110340dd7343SLorenzo Bianconi .addr = 0x10, 110440dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 110540dd7343SLorenzo Bianconi }, 110640dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 110740dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 110840dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 110940dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 111040dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 111140dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 111240dd7343SLorenzo Bianconi }, 111340dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 111440dd7343SLorenzo Bianconi .reg = { 111540dd7343SLorenzo Bianconi .addr = 0x11, 111640dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 111740dd7343SLorenzo Bianconi }, 111840dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 111940dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 112040dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 112140dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 112240dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 112340dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 112440dd7343SLorenzo Bianconi }, 112540dd7343SLorenzo Bianconi }, 1126640aca3fSLorenzo Bianconi .fs_table = { 1127640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 1128640aca3fSLorenzo Bianconi .reg = { 1129640aca3fSLorenzo Bianconi .addr = 0x10, 1130640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 1131640aca3fSLorenzo Bianconi }, 1132640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 1133640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 1134640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 1135640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 113685ae3aeeSLorenzo Bianconi .fs_len = 4, 1137640aca3fSLorenzo Bianconi }, 1138640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 1139640aca3fSLorenzo Bianconi .reg = { 1140640aca3fSLorenzo Bianconi .addr = 0x11, 1141640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 1142640aca3fSLorenzo Bianconi }, 1143640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 1144640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 1145640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 1146640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 114785ae3aeeSLorenzo Bianconi .fs_len = 4, 1148640aca3fSLorenzo Bianconi }, 1149640aca3fSLorenzo Bianconi }, 11507e906103SLorenzo Bianconi .irq_config = { 11517e906103SLorenzo Bianconi .irq1 = { 11527e906103SLorenzo Bianconi .addr = 0x0d, 11537e906103SLorenzo Bianconi .mask = BIT(3), 11547e906103SLorenzo Bianconi }, 11557e906103SLorenzo Bianconi .irq2 = { 11567e906103SLorenzo Bianconi .addr = 0x0e, 11577e906103SLorenzo Bianconi .mask = BIT(3), 11587e906103SLorenzo Bianconi }, 11597e906103SLorenzo Bianconi .lir = { 11607e906103SLorenzo Bianconi .addr = 0x56, 11617e906103SLorenzo Bianconi .mask = BIT(0), 11627e906103SLorenzo Bianconi }, 11637e906103SLorenzo Bianconi .clear_on_read = { 11647e906103SLorenzo Bianconi .addr = 0x56, 11657e906103SLorenzo Bianconi .mask = BIT(6), 11667e906103SLorenzo Bianconi }, 11677e906103SLorenzo Bianconi .irq1_func = { 11687e906103SLorenzo Bianconi .addr = 0x5e, 11697e906103SLorenzo Bianconi .mask = BIT(5), 11707e906103SLorenzo Bianconi }, 11717e906103SLorenzo Bianconi .irq2_func = { 11727e906103SLorenzo Bianconi .addr = 0x5f, 11737e906103SLorenzo Bianconi .mask = BIT(5), 11747e906103SLorenzo Bianconi }, 117531fe8d4eSLorenzo Bianconi .hla = { 117631fe8d4eSLorenzo Bianconi .addr = 0x12, 117731fe8d4eSLorenzo Bianconi .mask = BIT(5), 117831fe8d4eSLorenzo Bianconi }, 117931fe8d4eSLorenzo Bianconi .od = { 118031fe8d4eSLorenzo Bianconi .addr = 0x12, 118131fe8d4eSLorenzo Bianconi .mask = BIT(4), 118231fe8d4eSLorenzo Bianconi }, 11837e906103SLorenzo Bianconi }, 118443901008SLorenzo Bianconi .batch = { 118543901008SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 118643901008SLorenzo Bianconi .addr = 0x09, 118743901008SLorenzo Bianconi .mask = GENMASK(3, 0), 118843901008SLorenzo Bianconi }, 118943901008SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 119043901008SLorenzo Bianconi .addr = 0x09, 119143901008SLorenzo Bianconi .mask = GENMASK(7, 4), 119243901008SLorenzo Bianconi }, 119343901008SLorenzo Bianconi }, 119443901008SLorenzo Bianconi .fifo_ops = { 11953b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 119643901008SLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 119743901008SLorenzo Bianconi .fifo_th = { 119843901008SLorenzo Bianconi .addr = 0x07, 119943901008SLorenzo Bianconi .mask = GENMASK(8, 0), 120043901008SLorenzo Bianconi }, 120143901008SLorenzo Bianconi .fifo_diff = { 120243901008SLorenzo Bianconi .addr = 0x3a, 120370575abeSmario tesi .mask = GENMASK(9, 0), 120443901008SLorenzo Bianconi }, 120543901008SLorenzo Bianconi .th_wl = 1, 120643901008SLorenzo Bianconi }, 120743901008SLorenzo Bianconi .ts_settings = { 120843901008SLorenzo Bianconi .timer_en = { 120943901008SLorenzo Bianconi .addr = 0x19, 121043901008SLorenzo Bianconi .mask = BIT(5), 121143901008SLorenzo Bianconi }, 121243901008SLorenzo Bianconi .decimator = { 121343901008SLorenzo Bianconi .addr = 0x0a, 121443901008SLorenzo Bianconi .mask = GENMASK(7, 6), 121543901008SLorenzo Bianconi }, 1216cb3b6b8eSMario Tesi .freq_fine = 0x63, 121743901008SLorenzo Bianconi }, 121843901008SLorenzo Bianconi .shub_settings = { 121943901008SLorenzo Bianconi .page_mux = { 122043901008SLorenzo Bianconi .addr = 0x01, 122143901008SLorenzo Bianconi .mask = BIT(6), 122243901008SLorenzo Bianconi }, 122343901008SLorenzo Bianconi .master_en = { 122443901008SLorenzo Bianconi .addr = 0x14, 122543901008SLorenzo Bianconi .mask = BIT(2), 122643901008SLorenzo Bianconi }, 122743901008SLorenzo Bianconi .pullup_en = { 122843901008SLorenzo Bianconi .addr = 0x14, 122943901008SLorenzo Bianconi .mask = BIT(3), 123043901008SLorenzo Bianconi }, 123143901008SLorenzo Bianconi .aux_sens = { 123243901008SLorenzo Bianconi .addr = 0x14, 123343901008SLorenzo Bianconi .mask = GENMASK(1, 0), 123443901008SLorenzo Bianconi }, 123543901008SLorenzo Bianconi .wr_once = { 123643901008SLorenzo Bianconi .addr = 0x14, 123743901008SLorenzo Bianconi .mask = BIT(6), 123843901008SLorenzo Bianconi }, 123943901008SLorenzo Bianconi .shub_out = 0x02, 124043901008SLorenzo Bianconi .slv0_addr = 0x15, 124143901008SLorenzo Bianconi .dw_slv0_addr = 0x21, 124243901008SLorenzo Bianconi .batch_en = BIT(3), 1243b5969abfSSean Nyekjaer }, 1244b5969abfSSean Nyekjaer .event_settings = { 1245b5969abfSSean Nyekjaer .enable_reg = { 1246b5969abfSSean Nyekjaer .addr = 0x58, 1247b5969abfSSean Nyekjaer .mask = BIT(7), 1248b5969abfSSean Nyekjaer }, 1249b5969abfSSean Nyekjaer .wakeup_reg = { 1250b5969abfSSean Nyekjaer .addr = 0x5B, 1251b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 1252b5969abfSSean Nyekjaer }, 12531aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 12541aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 12551aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 12561aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 12571aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 125843901008SLorenzo Bianconi } 125943901008SLorenzo Bianconi }, 1260290a6ce1SLorenzo Bianconi }; 1261290a6ce1SLorenzo Bianconi 1262c91c1c84SLorenzo Bianconi int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable) 1263c91c1c84SLorenzo Bianconi { 1264c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 1265c91c1c84SLorenzo Bianconi unsigned int data; 1266c91c1c84SLorenzo Bianconi int err; 1267c91c1c84SLorenzo Bianconi 1268c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 1269c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask); 1270c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr, 1271c91c1c84SLorenzo Bianconi hub_settings->page_mux.mask, data); 1272c91c1c84SLorenzo Bianconi usleep_range(100, 150); 1273c91c1c84SLorenzo Bianconi 1274c91c1c84SLorenzo Bianconi return err; 1275c91c1c84SLorenzo Bianconi } 1276c91c1c84SLorenzo Bianconi 127781956a93SLorenzo Bianconi static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id, 127881956a93SLorenzo Bianconi const char **name) 1279290a6ce1SLorenzo Bianconi { 128051a8b707SLorenzo Bianconi int err, i, j, data; 1281290a6ce1SLorenzo Bianconi 1282290a6ce1SLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) { 1283d068e4a0SLorenzo Bianconi for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) { 128481956a93SLorenzo Bianconi if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id) 1285d068e4a0SLorenzo Bianconi break; 1286d068e4a0SLorenzo Bianconi } 1287d068e4a0SLorenzo Bianconi if (j < ST_LSM6DSX_MAX_ID) 1288290a6ce1SLorenzo Bianconi break; 1289290a6ce1SLorenzo Bianconi } 1290290a6ce1SLorenzo Bianconi 1291290a6ce1SLorenzo Bianconi if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) { 1292290a6ce1SLorenzo Bianconi dev_err(hw->dev, "unsupported hw id [%02x]\n", id); 1293290a6ce1SLorenzo Bianconi return -ENODEV; 1294290a6ce1SLorenzo Bianconi } 1295290a6ce1SLorenzo Bianconi 129651a8b707SLorenzo Bianconi err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data); 1297290a6ce1SLorenzo Bianconi if (err < 0) { 1298290a6ce1SLorenzo Bianconi dev_err(hw->dev, "failed to read whoami register\n"); 1299290a6ce1SLorenzo Bianconi return err; 1300290a6ce1SLorenzo Bianconi } 1301290a6ce1SLorenzo Bianconi 1302290a6ce1SLorenzo Bianconi if (data != st_lsm6dsx_sensor_settings[i].wai) { 1303290a6ce1SLorenzo Bianconi dev_err(hw->dev, "unsupported whoami [%02x]\n", data); 1304290a6ce1SLorenzo Bianconi return -ENODEV; 1305290a6ce1SLorenzo Bianconi } 1306290a6ce1SLorenzo Bianconi 130781956a93SLorenzo Bianconi *name = st_lsm6dsx_sensor_settings[i].id[j].name; 1308290a6ce1SLorenzo Bianconi hw->settings = &st_lsm6dsx_sensor_settings[i]; 1309290a6ce1SLorenzo Bianconi 1310290a6ce1SLorenzo Bianconi return 0; 1311290a6ce1SLorenzo Bianconi } 1312290a6ce1SLorenzo Bianconi 1313290a6ce1SLorenzo Bianconi static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, 1314290a6ce1SLorenzo Bianconi u32 gain) 1315290a6ce1SLorenzo Bianconi { 1316640aca3fSLorenzo Bianconi const struct st_lsm6dsx_fs_table_entry *fs_table; 1317739aff87SLorenzo Bianconi unsigned int data; 1318290a6ce1SLorenzo Bianconi int i, err; 1319290a6ce1SLorenzo Bianconi 1320640aca3fSLorenzo Bianconi fs_table = &sensor->hw->settings->fs_table[sensor->id]; 132185ae3aeeSLorenzo Bianconi for (i = 0; i < fs_table->fs_len; i++) { 1322640aca3fSLorenzo Bianconi if (fs_table->fs_avl[i].gain == gain) 1323290a6ce1SLorenzo Bianconi break; 132485ae3aeeSLorenzo Bianconi } 1325290a6ce1SLorenzo Bianconi 132685ae3aeeSLorenzo Bianconi if (i == fs_table->fs_len) 1327290a6ce1SLorenzo Bianconi return -EINVAL; 1328290a6ce1SLorenzo Bianconi 1329640aca3fSLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val, 1330640aca3fSLorenzo Bianconi fs_table->reg.mask); 1331640aca3fSLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr, 1332640aca3fSLorenzo Bianconi fs_table->reg.mask, data); 1333290a6ce1SLorenzo Bianconi if (err < 0) 1334290a6ce1SLorenzo Bianconi return err; 1335290a6ce1SLorenzo Bianconi 1336290a6ce1SLorenzo Bianconi sensor->gain = gain; 1337290a6ce1SLorenzo Bianconi 1338290a6ce1SLorenzo Bianconi return 0; 1339290a6ce1SLorenzo Bianconi } 1340290a6ce1SLorenzo Bianconi 134154a6d0c6SLorenzo Bianconi int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val) 1342290a6ce1SLorenzo Bianconi { 134340dd7343SLorenzo Bianconi const struct st_lsm6dsx_odr_table_entry *odr_table; 13442ccc1503SLorenzo Bianconi int i; 1345290a6ce1SLorenzo Bianconi 134640dd7343SLorenzo Bianconi odr_table = &sensor->hw->settings->odr_table[sensor->id]; 1347290a6ce1SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) 13486ffb55e5SLorenzo Bianconi /* 13496ffb55e5SLorenzo Bianconi * ext devices can run at different odr respect to 13506ffb55e5SLorenzo Bianconi * accel sensor 13516ffb55e5SLorenzo Bianconi */ 135240dd7343SLorenzo Bianconi if (odr_table->odr_avl[i].hz >= odr) 1353290a6ce1SLorenzo Bianconi break; 1354290a6ce1SLorenzo Bianconi 1355290a6ce1SLorenzo Bianconi if (i == ST_LSM6DSX_ODR_LIST_SIZE) 1356290a6ce1SLorenzo Bianconi return -EINVAL; 1357290a6ce1SLorenzo Bianconi 135840dd7343SLorenzo Bianconi *val = odr_table->odr_avl[i].val; 1359290a6ce1SLorenzo Bianconi 1360290a6ce1SLorenzo Bianconi return 0; 1361290a6ce1SLorenzo Bianconi } 1362290a6ce1SLorenzo Bianconi 13636ffb55e5SLorenzo Bianconi static u16 st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u16 odr, 13646ffb55e5SLorenzo Bianconi enum st_lsm6dsx_sensor_id id) 13652ccc1503SLorenzo Bianconi { 13666ffb55e5SLorenzo Bianconi struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]); 13676ffb55e5SLorenzo Bianconi 13686ffb55e5SLorenzo Bianconi if (odr > 0) { 13696ffb55e5SLorenzo Bianconi if (hw->enable_mask & BIT(id)) 13706ffb55e5SLorenzo Bianconi return max_t(u16, ref->odr, odr); 13716ffb55e5SLorenzo Bianconi else 13726ffb55e5SLorenzo Bianconi return odr; 13736ffb55e5SLorenzo Bianconi } else { 13746ffb55e5SLorenzo Bianconi return (hw->enable_mask & BIT(id)) ? ref->odr : 0; 13756ffb55e5SLorenzo Bianconi } 13766ffb55e5SLorenzo Bianconi } 13776ffb55e5SLorenzo Bianconi 13786ffb55e5SLorenzo Bianconi static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 req_odr) 13796ffb55e5SLorenzo Bianconi { 13806ffb55e5SLorenzo Bianconi struct st_lsm6dsx_sensor *ref_sensor = sensor; 138151a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 138251a8b707SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 1383739aff87SLorenzo Bianconi unsigned int data; 13846ffb55e5SLorenzo Bianconi u8 val = 0; 13852ccc1503SLorenzo Bianconi int err; 13862ccc1503SLorenzo Bianconi 13876ffb55e5SLorenzo Bianconi switch (sensor->id) { 13886ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT0: 13896ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT1: 13906ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT2: 13916ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_ACC: { 13926ffb55e5SLorenzo Bianconi u16 odr; 13936ffb55e5SLorenzo Bianconi int i; 13946ffb55e5SLorenzo Bianconi 13956ffb55e5SLorenzo Bianconi /* 13966ffb55e5SLorenzo Bianconi * i2c embedded controller relies on the accelerometer sensor as 13976ffb55e5SLorenzo Bianconi * bus read/write trigger so we need to enable accel device 13986ffb55e5SLorenzo Bianconi * at odr = max(accel_odr, ext_odr) in order to properly 13996ffb55e5SLorenzo Bianconi * communicate with i2c slave devices 14006ffb55e5SLorenzo Bianconi */ 14016ffb55e5SLorenzo Bianconi ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); 14026ffb55e5SLorenzo Bianconi for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) { 14036ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i] || i == sensor->id) 14046ffb55e5SLorenzo Bianconi continue; 14056ffb55e5SLorenzo Bianconi 14066ffb55e5SLorenzo Bianconi odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i); 14076ffb55e5SLorenzo Bianconi if (odr != req_odr) 14086ffb55e5SLorenzo Bianconi /* device already configured */ 14096ffb55e5SLorenzo Bianconi return 0; 14106ffb55e5SLorenzo Bianconi } 14116ffb55e5SLorenzo Bianconi break; 14126ffb55e5SLorenzo Bianconi } 14136ffb55e5SLorenzo Bianconi default: 14146ffb55e5SLorenzo Bianconi break; 14156ffb55e5SLorenzo Bianconi } 14166ffb55e5SLorenzo Bianconi 14176ffb55e5SLorenzo Bianconi if (req_odr > 0) { 14186ffb55e5SLorenzo Bianconi err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val); 14192ccc1503SLorenzo Bianconi if (err < 0) 14202ccc1503SLorenzo Bianconi return err; 14216ffb55e5SLorenzo Bianconi } 14222ccc1503SLorenzo Bianconi 142340dd7343SLorenzo Bianconi reg = &hw->settings->odr_table[ref_sensor->id].reg; 1424739aff87SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask); 1425739aff87SLorenzo Bianconi return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data); 14262ccc1503SLorenzo Bianconi } 14272ccc1503SLorenzo Bianconi 142817750443SLorenzo Bianconi int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, 142917750443SLorenzo Bianconi bool enable) 1430290a6ce1SLorenzo Bianconi { 143151a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 143217750443SLorenzo Bianconi u16 odr = enable ? sensor->odr : 0; 1433290a6ce1SLorenzo Bianconi int err; 1434290a6ce1SLorenzo Bianconi 143517750443SLorenzo Bianconi err = st_lsm6dsx_set_odr(sensor, odr); 1436290a6ce1SLorenzo Bianconi if (err < 0) 1437290a6ce1SLorenzo Bianconi return err; 1438290a6ce1SLorenzo Bianconi 143917750443SLorenzo Bianconi if (enable) 144017750443SLorenzo Bianconi hw->enable_mask |= BIT(sensor->id); 144117750443SLorenzo Bianconi else 144217750443SLorenzo Bianconi hw->enable_mask &= ~BIT(sensor->id); 1443290a6ce1SLorenzo Bianconi 1444290a6ce1SLorenzo Bianconi return 0; 1445290a6ce1SLorenzo Bianconi } 1446290a6ce1SLorenzo Bianconi 1447290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, 1448290a6ce1SLorenzo Bianconi u8 addr, int *val) 1449290a6ce1SLorenzo Bianconi { 145051a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1451290a6ce1SLorenzo Bianconi int err, delay; 1452290a6ce1SLorenzo Bianconi __le16 data; 1453290a6ce1SLorenzo Bianconi 145417750443SLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, true); 1455290a6ce1SLorenzo Bianconi if (err < 0) 1456290a6ce1SLorenzo Bianconi return err; 1457290a6ce1SLorenzo Bianconi 1458290a6ce1SLorenzo Bianconi delay = 1000000 / sensor->odr; 1459290a6ce1SLorenzo Bianconi usleep_range(delay, 2 * delay); 1460290a6ce1SLorenzo Bianconi 1461739aff87SLorenzo Bianconi err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data)); 1462290a6ce1SLorenzo Bianconi if (err < 0) 1463290a6ce1SLorenzo Bianconi return err; 1464290a6ce1SLorenzo Bianconi 1465b5969abfSSean Nyekjaer if (!hw->enable_event) 146617750443SLorenzo Bianconi st_lsm6dsx_sensor_set_enable(sensor, false); 1467290a6ce1SLorenzo Bianconi 14687b9ebe42SLorenzo Bianconi *val = (s16)le16_to_cpu(data); 1469290a6ce1SLorenzo Bianconi 1470290a6ce1SLorenzo Bianconi return IIO_VAL_INT; 1471290a6ce1SLorenzo Bianconi } 1472290a6ce1SLorenzo Bianconi 1473290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev, 1474290a6ce1SLorenzo Bianconi struct iio_chan_spec const *ch, 1475290a6ce1SLorenzo Bianconi int *val, int *val2, long mask) 1476290a6ce1SLorenzo Bianconi { 1477290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1478290a6ce1SLorenzo Bianconi int ret; 1479290a6ce1SLorenzo Bianconi 1480290a6ce1SLorenzo Bianconi switch (mask) { 1481290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_RAW: 1482290a6ce1SLorenzo Bianconi ret = iio_device_claim_direct_mode(iio_dev); 1483290a6ce1SLorenzo Bianconi if (ret) 1484290a6ce1SLorenzo Bianconi break; 1485290a6ce1SLorenzo Bianconi 1486290a6ce1SLorenzo Bianconi ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val); 1487290a6ce1SLorenzo Bianconi iio_device_release_direct_mode(iio_dev); 1488290a6ce1SLorenzo Bianconi break; 1489290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SAMP_FREQ: 1490290a6ce1SLorenzo Bianconi *val = sensor->odr; 1491290a6ce1SLorenzo Bianconi ret = IIO_VAL_INT; 1492290a6ce1SLorenzo Bianconi break; 1493290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SCALE: 1494290a6ce1SLorenzo Bianconi *val = 0; 1495290a6ce1SLorenzo Bianconi *val2 = sensor->gain; 1496290a6ce1SLorenzo Bianconi ret = IIO_VAL_INT_PLUS_MICRO; 1497290a6ce1SLorenzo Bianconi break; 1498290a6ce1SLorenzo Bianconi default: 1499290a6ce1SLorenzo Bianconi ret = -EINVAL; 1500290a6ce1SLorenzo Bianconi break; 1501290a6ce1SLorenzo Bianconi } 1502290a6ce1SLorenzo Bianconi 1503290a6ce1SLorenzo Bianconi return ret; 1504290a6ce1SLorenzo Bianconi } 1505290a6ce1SLorenzo Bianconi 1506290a6ce1SLorenzo Bianconi static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev, 1507290a6ce1SLorenzo Bianconi struct iio_chan_spec const *chan, 1508290a6ce1SLorenzo Bianconi int val, int val2, long mask) 1509290a6ce1SLorenzo Bianconi { 1510290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1511290a6ce1SLorenzo Bianconi int err; 1512290a6ce1SLorenzo Bianconi 1513290a6ce1SLorenzo Bianconi err = iio_device_claim_direct_mode(iio_dev); 1514290a6ce1SLorenzo Bianconi if (err) 1515290a6ce1SLorenzo Bianconi return err; 1516290a6ce1SLorenzo Bianconi 1517290a6ce1SLorenzo Bianconi switch (mask) { 1518290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SCALE: 1519290a6ce1SLorenzo Bianconi err = st_lsm6dsx_set_full_scale(sensor, val2); 1520290a6ce1SLorenzo Bianconi break; 15212ccc1503SLorenzo Bianconi case IIO_CHAN_INFO_SAMP_FREQ: { 15222ccc1503SLorenzo Bianconi u8 data; 15232ccc1503SLorenzo Bianconi 15242ccc1503SLorenzo Bianconi err = st_lsm6dsx_check_odr(sensor, val, &data); 15255e3c3e33SLorenzo Bianconi if (!err) 15265e3c3e33SLorenzo Bianconi sensor->odr = val; 1527290a6ce1SLorenzo Bianconi break; 15282ccc1503SLorenzo Bianconi } 1529290a6ce1SLorenzo Bianconi default: 1530290a6ce1SLorenzo Bianconi err = -EINVAL; 1531290a6ce1SLorenzo Bianconi break; 1532290a6ce1SLorenzo Bianconi } 1533290a6ce1SLorenzo Bianconi 1534290a6ce1SLorenzo Bianconi iio_device_release_direct_mode(iio_dev); 1535290a6ce1SLorenzo Bianconi 1536290a6ce1SLorenzo Bianconi return err; 1537290a6ce1SLorenzo Bianconi } 1538290a6ce1SLorenzo Bianconi 1539b5969abfSSean Nyekjaer static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state) 1540b5969abfSSean Nyekjaer { 154184b2e7c3SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 154204ca37d5SLorenzo Bianconi unsigned int data; 1543b5969abfSSean Nyekjaer int err; 1544b5969abfSSean Nyekjaer 15457e906103SLorenzo Bianconi if (!hw->settings->irq_config.irq1_func.addr) 1546b5969abfSSean Nyekjaer return -ENOTSUPP; 1547b5969abfSSean Nyekjaer 154884b2e7c3SLorenzo Bianconi reg = &hw->settings->event_settings.enable_reg; 154984b2e7c3SLorenzo Bianconi if (reg->addr) { 155004ca37d5SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(state, reg->mask); 155104ca37d5SLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(hw, reg->addr, 155204ca37d5SLorenzo Bianconi reg->mask, data); 1553b5969abfSSean Nyekjaer if (err < 0) 1554b5969abfSSean Nyekjaer return err; 155584b2e7c3SLorenzo Bianconi } 1556b5969abfSSean Nyekjaer 1557b5969abfSSean Nyekjaer /* Enable wakeup interrupt */ 155804ca37d5SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(state, hw->irq_routing->mask); 155904ca37d5SLorenzo Bianconi return st_lsm6dsx_update_bits_locked(hw, hw->irq_routing->addr, 156004ca37d5SLorenzo Bianconi hw->irq_routing->mask, data); 1561b5969abfSSean Nyekjaer } 1562b5969abfSSean Nyekjaer 1563b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event(struct iio_dev *iio_dev, 1564b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1565b5969abfSSean Nyekjaer enum iio_event_type type, 1566b5969abfSSean Nyekjaer enum iio_event_direction dir, 1567b5969abfSSean Nyekjaer enum iio_event_info info, 1568b5969abfSSean Nyekjaer int *val, int *val2) 1569b5969abfSSean Nyekjaer { 1570b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1571b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 1572b5969abfSSean Nyekjaer 1573b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1574b5969abfSSean Nyekjaer return -EINVAL; 1575b5969abfSSean Nyekjaer 1576b5969abfSSean Nyekjaer *val2 = 0; 1577b5969abfSSean Nyekjaer *val = hw->event_threshold; 1578b5969abfSSean Nyekjaer 1579b5969abfSSean Nyekjaer return IIO_VAL_INT; 1580b5969abfSSean Nyekjaer } 1581b5969abfSSean Nyekjaer 1582b307f495SLorenzo Bianconi static int 1583b307f495SLorenzo Bianconi st_lsm6dsx_write_event(struct iio_dev *iio_dev, 1584b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1585b5969abfSSean Nyekjaer enum iio_event_type type, 1586b5969abfSSean Nyekjaer enum iio_event_direction dir, 1587b5969abfSSean Nyekjaer enum iio_event_info info, 1588b5969abfSSean Nyekjaer int val, int val2) 1589b5969abfSSean Nyekjaer { 1590b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1591b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 159204ca37d5SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 159304ca37d5SLorenzo Bianconi unsigned int data; 1594b5969abfSSean Nyekjaer int err; 1595b5969abfSSean Nyekjaer 1596b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1597b5969abfSSean Nyekjaer return -EINVAL; 1598b5969abfSSean Nyekjaer 1599b5969abfSSean Nyekjaer if (val < 0 || val > 31) 1600b5969abfSSean Nyekjaer return -EINVAL; 1601b5969abfSSean Nyekjaer 160204ca37d5SLorenzo Bianconi reg = &hw->settings->event_settings.wakeup_reg; 160304ca37d5SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask); 160404ca37d5SLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(hw, reg->addr, 160504ca37d5SLorenzo Bianconi reg->mask, data); 160604ca37d5SLorenzo Bianconi if (err < 0) 1607b5969abfSSean Nyekjaer return -EINVAL; 1608b5969abfSSean Nyekjaer 1609b5969abfSSean Nyekjaer hw->event_threshold = val; 1610b5969abfSSean Nyekjaer 1611b5969abfSSean Nyekjaer return 0; 1612b5969abfSSean Nyekjaer } 1613b5969abfSSean Nyekjaer 1614b307f495SLorenzo Bianconi static int 1615b307f495SLorenzo Bianconi st_lsm6dsx_read_event_config(struct iio_dev *iio_dev, 1616b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1617b5969abfSSean Nyekjaer enum iio_event_type type, 1618b5969abfSSean Nyekjaer enum iio_event_direction dir) 1619b5969abfSSean Nyekjaer { 1620b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1621b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 1622b5969abfSSean Nyekjaer 1623b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1624b5969abfSSean Nyekjaer return -EINVAL; 1625b5969abfSSean Nyekjaer 16261aabad1fSSean Nyekjaer return !!(hw->enable_event & BIT(chan->channel2)); 1627b5969abfSSean Nyekjaer } 1628b5969abfSSean Nyekjaer 1629b307f495SLorenzo Bianconi static int 1630b307f495SLorenzo Bianconi st_lsm6dsx_write_event_config(struct iio_dev *iio_dev, 1631b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1632b5969abfSSean Nyekjaer enum iio_event_type type, 1633b307f495SLorenzo Bianconi enum iio_event_direction dir, int state) 1634b5969abfSSean Nyekjaer { 1635b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1636b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 16371aabad1fSSean Nyekjaer u8 enable_event; 1638b5969abfSSean Nyekjaer int err = 0; 1639b5969abfSSean Nyekjaer 1640b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1641b5969abfSSean Nyekjaer return -EINVAL; 1642b5969abfSSean Nyekjaer 16431aabad1fSSean Nyekjaer if (state) { 16441aabad1fSSean Nyekjaer enable_event = hw->enable_event | BIT(chan->channel2); 16451aabad1fSSean Nyekjaer 1646b5969abfSSean Nyekjaer /* do not enable events if they are already enabled */ 16471aabad1fSSean Nyekjaer if (hw->enable_event) 16481aabad1fSSean Nyekjaer goto out; 16491aabad1fSSean Nyekjaer } else { 16501aabad1fSSean Nyekjaer enable_event = hw->enable_event & ~BIT(chan->channel2); 16511aabad1fSSean Nyekjaer 16521aabad1fSSean Nyekjaer /* only turn off sensor if no events is enabled */ 16531aabad1fSSean Nyekjaer if (enable_event) 16541aabad1fSSean Nyekjaer goto out; 16551aabad1fSSean Nyekjaer } 16561aabad1fSSean Nyekjaer 16571aabad1fSSean Nyekjaer /* stop here if no changes have been made */ 16581aabad1fSSean Nyekjaer if (hw->enable_event == enable_event) 1659b5969abfSSean Nyekjaer return 0; 1660b5969abfSSean Nyekjaer 1661b5969abfSSean Nyekjaer err = st_lsm6dsx_event_setup(hw, state); 1662b5969abfSSean Nyekjaer if (err < 0) 1663b5969abfSSean Nyekjaer return err; 1664b5969abfSSean Nyekjaer 1665d278d447SLorenzo Bianconi mutex_lock(&hw->conf_lock); 1666b5969abfSSean Nyekjaer err = st_lsm6dsx_sensor_set_enable(sensor, state); 1667d278d447SLorenzo Bianconi mutex_unlock(&hw->conf_lock); 1668b5969abfSSean Nyekjaer if (err < 0) 1669b5969abfSSean Nyekjaer return err; 1670b5969abfSSean Nyekjaer 16711aabad1fSSean Nyekjaer out: 16721aabad1fSSean Nyekjaer hw->enable_event = enable_event; 1673b5969abfSSean Nyekjaer 1674b5969abfSSean Nyekjaer return 0; 1675b5969abfSSean Nyekjaer } 1676b5969abfSSean Nyekjaer 1677d40464f3SLorenzo Bianconi int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val) 1678290a6ce1SLorenzo Bianconi { 1679290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1680290a6ce1SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 16818f2a88a2SLorenzo Bianconi int err; 1682290a6ce1SLorenzo Bianconi 16838f2a88a2SLorenzo Bianconi if (val < 1 || val > hw->settings->max_fifo_size) 1684290a6ce1SLorenzo Bianconi return -EINVAL; 1685290a6ce1SLorenzo Bianconi 1686335eaedcSLorenzo Bianconi mutex_lock(&hw->conf_lock); 1687335eaedcSLorenzo Bianconi 1688290a6ce1SLorenzo Bianconi err = st_lsm6dsx_update_watermark(sensor, val); 1689335eaedcSLorenzo Bianconi 1690335eaedcSLorenzo Bianconi mutex_unlock(&hw->conf_lock); 1691335eaedcSLorenzo Bianconi 1692290a6ce1SLorenzo Bianconi if (err < 0) 1693290a6ce1SLorenzo Bianconi return err; 1694290a6ce1SLorenzo Bianconi 1695290a6ce1SLorenzo Bianconi sensor->watermark = val; 1696290a6ce1SLorenzo Bianconi 1697290a6ce1SLorenzo Bianconi return 0; 1698290a6ce1SLorenzo Bianconi } 1699290a6ce1SLorenzo Bianconi 1700290a6ce1SLorenzo Bianconi static ssize_t 1701290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev, 1702290a6ce1SLorenzo Bianconi struct device_attribute *attr, 1703290a6ce1SLorenzo Bianconi char *buf) 1704290a6ce1SLorenzo Bianconi { 1705290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); 1706290a6ce1SLorenzo Bianconi enum st_lsm6dsx_sensor_id id = sensor->id; 170740dd7343SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1708290a6ce1SLorenzo Bianconi int i, len = 0; 1709290a6ce1SLorenzo Bianconi 1710290a6ce1SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) 1711290a6ce1SLorenzo Bianconi len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", 171240dd7343SLorenzo Bianconi hw->settings->odr_table[id].odr_avl[i].hz); 1713290a6ce1SLorenzo Bianconi buf[len - 1] = '\n'; 1714290a6ce1SLorenzo Bianconi 1715290a6ce1SLorenzo Bianconi return len; 1716290a6ce1SLorenzo Bianconi } 1717290a6ce1SLorenzo Bianconi 1718290a6ce1SLorenzo Bianconi static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev, 1719290a6ce1SLorenzo Bianconi struct device_attribute *attr, 1720290a6ce1SLorenzo Bianconi char *buf) 1721290a6ce1SLorenzo Bianconi { 1722290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); 17230f7e1728SLorenzo Bianconi const struct st_lsm6dsx_fs_table_entry *fs_table; 1724640aca3fSLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1725290a6ce1SLorenzo Bianconi int i, len = 0; 1726290a6ce1SLorenzo Bianconi 172785ae3aeeSLorenzo Bianconi fs_table = &hw->settings->fs_table[sensor->id]; 172885ae3aeeSLorenzo Bianconi for (i = 0; i < fs_table->fs_len; i++) 1729290a6ce1SLorenzo Bianconi len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", 17300f7e1728SLorenzo Bianconi fs_table->fs_avl[i].gain); 1731290a6ce1SLorenzo Bianconi buf[len - 1] = '\n'; 1732290a6ce1SLorenzo Bianconi 1733290a6ce1SLorenzo Bianconi return len; 1734290a6ce1SLorenzo Bianconi } 1735290a6ce1SLorenzo Bianconi 1736290a6ce1SLorenzo Bianconi static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail); 1737290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_accel_scale_available, 0444, 1738290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_scale_avail, NULL, 0); 1739290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444, 1740290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_scale_avail, NULL, 0); 1741290a6ce1SLorenzo Bianconi 1742290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_acc_attributes[] = { 1743290a6ce1SLorenzo Bianconi &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 1744290a6ce1SLorenzo Bianconi &iio_dev_attr_in_accel_scale_available.dev_attr.attr, 1745290a6ce1SLorenzo Bianconi NULL, 1746290a6ce1SLorenzo Bianconi }; 1747290a6ce1SLorenzo Bianconi 1748290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_acc_attribute_group = { 1749290a6ce1SLorenzo Bianconi .attrs = st_lsm6dsx_acc_attributes, 1750290a6ce1SLorenzo Bianconi }; 1751290a6ce1SLorenzo Bianconi 1752290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_acc_info = { 1753290a6ce1SLorenzo Bianconi .attrs = &st_lsm6dsx_acc_attribute_group, 1754290a6ce1SLorenzo Bianconi .read_raw = st_lsm6dsx_read_raw, 1755290a6ce1SLorenzo Bianconi .write_raw = st_lsm6dsx_write_raw, 1756b5969abfSSean Nyekjaer .read_event_value = st_lsm6dsx_read_event, 1757b5969abfSSean Nyekjaer .write_event_value = st_lsm6dsx_write_event, 1758b5969abfSSean Nyekjaer .read_event_config = st_lsm6dsx_read_event_config, 1759b5969abfSSean Nyekjaer .write_event_config = st_lsm6dsx_write_event_config, 1760290a6ce1SLorenzo Bianconi .hwfifo_set_watermark = st_lsm6dsx_set_watermark, 1761290a6ce1SLorenzo Bianconi }; 1762290a6ce1SLorenzo Bianconi 1763290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_gyro_attributes[] = { 1764290a6ce1SLorenzo Bianconi &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 1765290a6ce1SLorenzo Bianconi &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr, 1766290a6ce1SLorenzo Bianconi NULL, 1767290a6ce1SLorenzo Bianconi }; 1768290a6ce1SLorenzo Bianconi 1769290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_gyro_attribute_group = { 1770290a6ce1SLorenzo Bianconi .attrs = st_lsm6dsx_gyro_attributes, 1771290a6ce1SLorenzo Bianconi }; 1772290a6ce1SLorenzo Bianconi 1773290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_gyro_info = { 1774290a6ce1SLorenzo Bianconi .attrs = &st_lsm6dsx_gyro_attribute_group, 1775290a6ce1SLorenzo Bianconi .read_raw = st_lsm6dsx_read_raw, 1776290a6ce1SLorenzo Bianconi .write_raw = st_lsm6dsx_write_raw, 1777290a6ce1SLorenzo Bianconi .hwfifo_set_watermark = st_lsm6dsx_set_watermark, 1778290a6ce1SLorenzo Bianconi }; 1779290a6ce1SLorenzo Bianconi 1780dba32904SLorenzo Bianconi static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) 1781dba32904SLorenzo Bianconi { 1782dba32904SLorenzo Bianconi struct device_node *np = hw->dev->of_node; 1783dba32904SLorenzo Bianconi 1784dba32904SLorenzo Bianconi if (!np) 1785dba32904SLorenzo Bianconi return -EINVAL; 1786dba32904SLorenzo Bianconi 1787bf235277SLorenzo Bianconi return of_property_read_u32(np, "st,drdy-int-pin", drdy_pin); 1788dba32904SLorenzo Bianconi } 1789dba32904SLorenzo Bianconi 17907e906103SLorenzo Bianconi static int 17917e906103SLorenzo Bianconi st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, 17927e906103SLorenzo Bianconi const struct st_lsm6dsx_reg **drdy_reg) 1793dba32904SLorenzo Bianconi { 1794dba32904SLorenzo Bianconi int err = 0, drdy_pin; 1795dba32904SLorenzo Bianconi 1796dba32904SLorenzo Bianconi if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) { 1797dba32904SLorenzo Bianconi struct st_sensors_platform_data *pdata; 1798dba32904SLorenzo Bianconi struct device *dev = hw->dev; 1799dba32904SLorenzo Bianconi 1800dba32904SLorenzo Bianconi pdata = (struct st_sensors_platform_data *)dev->platform_data; 1801dba32904SLorenzo Bianconi drdy_pin = pdata ? pdata->drdy_int_pin : 1; 1802dba32904SLorenzo Bianconi } 1803dba32904SLorenzo Bianconi 1804dba32904SLorenzo Bianconi switch (drdy_pin) { 1805dba32904SLorenzo Bianconi case 1: 18067e906103SLorenzo Bianconi hw->irq_routing = &hw->settings->irq_config.irq1_func; 18077e906103SLorenzo Bianconi *drdy_reg = &hw->settings->irq_config.irq1; 1808dba32904SLorenzo Bianconi break; 1809dba32904SLorenzo Bianconi case 2: 18107e906103SLorenzo Bianconi hw->irq_routing = &hw->settings->irq_config.irq2_func; 18117e906103SLorenzo Bianconi *drdy_reg = &hw->settings->irq_config.irq2; 1812dba32904SLorenzo Bianconi break; 1813dba32904SLorenzo Bianconi default: 1814dba32904SLorenzo Bianconi dev_err(hw->dev, "unsupported data ready pin\n"); 1815dba32904SLorenzo Bianconi err = -EINVAL; 1816dba32904SLorenzo Bianconi break; 1817dba32904SLorenzo Bianconi } 1818dba32904SLorenzo Bianconi 1819dba32904SLorenzo Bianconi return err; 1820dba32904SLorenzo Bianconi } 1821dba32904SLorenzo Bianconi 1822c91c1c84SLorenzo Bianconi static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw) 1823c91c1c84SLorenzo Bianconi { 1824c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 1825c91c1c84SLorenzo Bianconi struct device_node *np = hw->dev->of_node; 1826c91c1c84SLorenzo Bianconi struct st_sensors_platform_data *pdata; 1827c91c1c84SLorenzo Bianconi unsigned int data; 1828c91c1c84SLorenzo Bianconi int err = 0; 1829c91c1c84SLorenzo Bianconi 1830c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 1831c91c1c84SLorenzo Bianconi 1832c91c1c84SLorenzo Bianconi pdata = (struct st_sensors_platform_data *)hw->dev->platform_data; 1833c91c1c84SLorenzo Bianconi if ((np && of_property_read_bool(np, "st,pullups")) || 1834c91c1c84SLorenzo Bianconi (pdata && pdata->pullups)) { 1835c91c1c84SLorenzo Bianconi err = st_lsm6dsx_set_page(hw, true); 1836c91c1c84SLorenzo Bianconi if (err < 0) 1837c91c1c84SLorenzo Bianconi return err; 1838c91c1c84SLorenzo Bianconi 1839c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask); 1840c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 1841c91c1c84SLorenzo Bianconi hub_settings->pullup_en.addr, 1842c91c1c84SLorenzo Bianconi hub_settings->pullup_en.mask, data); 1843c91c1c84SLorenzo Bianconi 1844c91c1c84SLorenzo Bianconi st_lsm6dsx_set_page(hw, false); 1845c91c1c84SLorenzo Bianconi 1846c91c1c84SLorenzo Bianconi if (err < 0) 1847c91c1c84SLorenzo Bianconi return err; 1848c91c1c84SLorenzo Bianconi } 1849c91c1c84SLorenzo Bianconi 1850c91c1c84SLorenzo Bianconi if (hub_settings->aux_sens.addr) { 1851c91c1c84SLorenzo Bianconi /* configure aux sensors */ 1852c91c1c84SLorenzo Bianconi err = st_lsm6dsx_set_page(hw, true); 1853c91c1c84SLorenzo Bianconi if (err < 0) 1854c91c1c84SLorenzo Bianconi return err; 1855c91c1c84SLorenzo Bianconi 1856c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask); 1857c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 1858c91c1c84SLorenzo Bianconi hub_settings->aux_sens.addr, 1859c91c1c84SLorenzo Bianconi hub_settings->aux_sens.mask, data); 1860c91c1c84SLorenzo Bianconi 1861c91c1c84SLorenzo Bianconi st_lsm6dsx_set_page(hw, false); 1862c91c1c84SLorenzo Bianconi } 1863c91c1c84SLorenzo Bianconi 1864c91c1c84SLorenzo Bianconi return err; 1865c91c1c84SLorenzo Bianconi } 1866c91c1c84SLorenzo Bianconi 186721345107SLorenzo Bianconi static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw) 186821345107SLorenzo Bianconi { 186921345107SLorenzo Bianconi const struct st_lsm6dsx_hw_ts_settings *ts_settings; 187021345107SLorenzo Bianconi int err, val; 187121345107SLorenzo Bianconi 187221345107SLorenzo Bianconi ts_settings = &hw->settings->ts_settings; 187321345107SLorenzo Bianconi /* enable hw timestamp generation if necessary */ 187421345107SLorenzo Bianconi if (ts_settings->timer_en.addr) { 187521345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask); 187621345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 187721345107SLorenzo Bianconi ts_settings->timer_en.addr, 187821345107SLorenzo Bianconi ts_settings->timer_en.mask, val); 187921345107SLorenzo Bianconi if (err < 0) 188021345107SLorenzo Bianconi return err; 188121345107SLorenzo Bianconi } 188221345107SLorenzo Bianconi 188321345107SLorenzo Bianconi /* enable high resolution for hw ts timer if necessary */ 188421345107SLorenzo Bianconi if (ts_settings->hr_timer.addr) { 188521345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask); 188621345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 188721345107SLorenzo Bianconi ts_settings->hr_timer.addr, 188821345107SLorenzo Bianconi ts_settings->hr_timer.mask, val); 188921345107SLorenzo Bianconi if (err < 0) 189021345107SLorenzo Bianconi return err; 189121345107SLorenzo Bianconi } 189221345107SLorenzo Bianconi 189321345107SLorenzo Bianconi /* enable ts queueing in FIFO if necessary */ 189421345107SLorenzo Bianconi if (ts_settings->fifo_en.addr) { 189521345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask); 189621345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 189721345107SLorenzo Bianconi ts_settings->fifo_en.addr, 189821345107SLorenzo Bianconi ts_settings->fifo_en.mask, val); 189921345107SLorenzo Bianconi if (err < 0) 190021345107SLorenzo Bianconi return err; 190121345107SLorenzo Bianconi } 1902cb3b6b8eSMario Tesi 1903cb3b6b8eSMario Tesi /* calibrate timestamp sensitivity */ 1904cb3b6b8eSMario Tesi hw->ts_gain = ST_LSM6DSX_TS_SENSITIVITY; 1905cb3b6b8eSMario Tesi if (ts_settings->freq_fine) { 1906cb3b6b8eSMario Tesi err = regmap_read(hw->regmap, ts_settings->freq_fine, &val); 1907cb3b6b8eSMario Tesi if (err < 0) 1908cb3b6b8eSMario Tesi return err; 1909cb3b6b8eSMario Tesi 1910cb3b6b8eSMario Tesi /* 1911cb3b6b8eSMario Tesi * linearize the AN5192 formula: 1912cb3b6b8eSMario Tesi * 1 / (1 + x) ~= 1 - x (Taylor’s Series) 1913cb3b6b8eSMario Tesi * ttrim[s] = 1 / (40000 * (1 + 0.0015 * val)) 1914cb3b6b8eSMario Tesi * ttrim[ns] ~= 25000 - 37.5 * val 1915cb3b6b8eSMario Tesi * ttrim[ns] ~= 25000 - (37500 * val) / 1000 1916cb3b6b8eSMario Tesi */ 1917cb3b6b8eSMario Tesi hw->ts_gain -= ((s8)val * 37500) / 1000; 1918cb3b6b8eSMario Tesi } 1919cb3b6b8eSMario Tesi 192021345107SLorenzo Bianconi return 0; 192121345107SLorenzo Bianconi } 192221345107SLorenzo Bianconi 1923290a6ce1SLorenzo Bianconi static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) 1924290a6ce1SLorenzo Bianconi { 19257e906103SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 1926290a6ce1SLorenzo Bianconi int err; 1927290a6ce1SLorenzo Bianconi 192819435425SLorenzo Bianconi /* device sw reset */ 192966b662a1SLorenzo Bianconi reg = &hw->settings->reset; 193066b662a1SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 193166b662a1SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 1932290a6ce1SLorenzo Bianconi if (err < 0) 1933290a6ce1SLorenzo Bianconi return err; 1934290a6ce1SLorenzo Bianconi 193519435425SLorenzo Bianconi msleep(50); 193619435425SLorenzo Bianconi 193719435425SLorenzo Bianconi /* reload trimming parameter */ 193866b662a1SLorenzo Bianconi reg = &hw->settings->boot; 193966b662a1SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 194066b662a1SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 194119435425SLorenzo Bianconi if (err < 0) 194219435425SLorenzo Bianconi return err; 194319435425SLorenzo Bianconi 194419435425SLorenzo Bianconi msleep(50); 1945290a6ce1SLorenzo Bianconi 1946290a6ce1SLorenzo Bianconi /* enable Block Data Update */ 194766b662a1SLorenzo Bianconi reg = &hw->settings->bdu; 194866b662a1SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 194966b662a1SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 1950290a6ce1SLorenzo Bianconi if (err < 0) 1951290a6ce1SLorenzo Bianconi return err; 1952290a6ce1SLorenzo Bianconi 1953290a6ce1SLorenzo Bianconi /* enable FIFO watermak interrupt */ 19547e906103SLorenzo Bianconi err = st_lsm6dsx_get_drdy_reg(hw, ®); 1955290a6ce1SLorenzo Bianconi if (err < 0) 1956290a6ce1SLorenzo Bianconi return err; 1957290a6ce1SLorenzo Bianconi 19587e906103SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 19597e906103SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 196021345107SLorenzo Bianconi if (err < 0) 196121345107SLorenzo Bianconi return err; 196221345107SLorenzo Bianconi 19639db02d32SLorenzo Bianconi /* enable Latched interrupts for device events */ 19647e906103SLorenzo Bianconi if (hw->settings->irq_config.lir.addr) { 19657e906103SLorenzo Bianconi reg = &hw->settings->irq_config.lir; 19667e906103SLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 19677e906103SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 19689db02d32SLorenzo Bianconi if (err < 0) 19699db02d32SLorenzo Bianconi return err; 197022ea5651SLorenzo Bianconi 197122ea5651SLorenzo Bianconi /* enable clear on read for latched interrupts */ 19727e906103SLorenzo Bianconi if (hw->settings->irq_config.clear_on_read.addr) { 19737e906103SLorenzo Bianconi reg = &hw->settings->irq_config.clear_on_read; 197422ea5651SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 19757e906103SLorenzo Bianconi reg->addr, reg->mask, 19767e906103SLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 197722ea5651SLorenzo Bianconi if (err < 0) 197822ea5651SLorenzo Bianconi return err; 197922ea5651SLorenzo Bianconi } 19809db02d32SLorenzo Bianconi } 19819db02d32SLorenzo Bianconi 1982960506edSLorenzo Bianconi /* enable drdy-mas if available */ 1983960506edSLorenzo Bianconi if (hw->settings->drdy_mask.addr) { 1984960506edSLorenzo Bianconi reg = &hw->settings->drdy_mask; 1985960506edSLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 1986960506edSLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 1987960506edSLorenzo Bianconi if (err < 0) 1988960506edSLorenzo Bianconi return err; 1989960506edSLorenzo Bianconi } 1990960506edSLorenzo Bianconi 1991c91c1c84SLorenzo Bianconi err = st_lsm6dsx_init_shub(hw); 1992c91c1c84SLorenzo Bianconi if (err < 0) 1993c91c1c84SLorenzo Bianconi return err; 1994c91c1c84SLorenzo Bianconi 199521345107SLorenzo Bianconi return st_lsm6dsx_init_hw_timer(hw); 1996290a6ce1SLorenzo Bianconi } 1997290a6ce1SLorenzo Bianconi 1998290a6ce1SLorenzo Bianconi static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, 1999510c0106SLorenzo Bianconi enum st_lsm6dsx_sensor_id id, 2000510c0106SLorenzo Bianconi const char *name) 2001290a6ce1SLorenzo Bianconi { 2002290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 2003290a6ce1SLorenzo Bianconi struct iio_dev *iio_dev; 2004290a6ce1SLorenzo Bianconi 2005290a6ce1SLorenzo Bianconi iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor)); 2006290a6ce1SLorenzo Bianconi if (!iio_dev) 2007290a6ce1SLorenzo Bianconi return NULL; 2008290a6ce1SLorenzo Bianconi 2009290a6ce1SLorenzo Bianconi iio_dev->modes = INDIO_DIRECT_MODE; 2010290a6ce1SLorenzo Bianconi iio_dev->dev.parent = hw->dev; 2011290a6ce1SLorenzo Bianconi iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks; 2012f48bc49bSLorenzo Bianconi iio_dev->channels = hw->settings->channels[id].chan; 2013f48bc49bSLorenzo Bianconi iio_dev->num_channels = hw->settings->channels[id].len; 2014290a6ce1SLorenzo Bianconi 2015290a6ce1SLorenzo Bianconi sensor = iio_priv(iio_dev); 2016290a6ce1SLorenzo Bianconi sensor->id = id; 2017290a6ce1SLorenzo Bianconi sensor->hw = hw; 201840dd7343SLorenzo Bianconi sensor->odr = hw->settings->odr_table[id].odr_avl[0].hz; 2019640aca3fSLorenzo Bianconi sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain; 2020290a6ce1SLorenzo Bianconi sensor->watermark = 1; 2021290a6ce1SLorenzo Bianconi 2022290a6ce1SLorenzo Bianconi switch (id) { 2023290a6ce1SLorenzo Bianconi case ST_LSM6DSX_ID_ACC: 2024290a6ce1SLorenzo Bianconi iio_dev->info = &st_lsm6dsx_acc_info; 2025510c0106SLorenzo Bianconi scnprintf(sensor->name, sizeof(sensor->name), "%s_accel", 2026510c0106SLorenzo Bianconi name); 2027290a6ce1SLorenzo Bianconi break; 2028290a6ce1SLorenzo Bianconi case ST_LSM6DSX_ID_GYRO: 2029290a6ce1SLorenzo Bianconi iio_dev->info = &st_lsm6dsx_gyro_info; 2030510c0106SLorenzo Bianconi scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro", 2031510c0106SLorenzo Bianconi name); 2032290a6ce1SLorenzo Bianconi break; 2033290a6ce1SLorenzo Bianconi default: 2034290a6ce1SLorenzo Bianconi return NULL; 2035290a6ce1SLorenzo Bianconi } 2036510c0106SLorenzo Bianconi iio_dev->name = sensor->name; 2037290a6ce1SLorenzo Bianconi 2038290a6ce1SLorenzo Bianconi return iio_dev; 2039290a6ce1SLorenzo Bianconi } 2040290a6ce1SLorenzo Bianconi 2041615bd378SLorenzo Bianconi static bool 2042615bd378SLorenzo Bianconi st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw) 20431aabad1fSSean Nyekjaer { 2044615bd378SLorenzo Bianconi const struct st_lsm6dsx_event_settings *event_settings; 2045615bd378SLorenzo Bianconi int err, data; 2046615bd378SLorenzo Bianconi s64 timestamp; 20471aabad1fSSean Nyekjaer 2048615bd378SLorenzo Bianconi if (!hw->enable_event) 2049615bd378SLorenzo Bianconi return false; 2050615bd378SLorenzo Bianconi 2051615bd378SLorenzo Bianconi event_settings = &hw->settings->event_settings; 2052615bd378SLorenzo Bianconi err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg, 2053615bd378SLorenzo Bianconi &data, sizeof(data)); 2054615bd378SLorenzo Bianconi if (err < 0) 2055615bd378SLorenzo Bianconi return false; 2056615bd378SLorenzo Bianconi 2057615bd378SLorenzo Bianconi timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]); 20581aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_z_mask) && 20591aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_Z))) 20601aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 20611aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 20621aabad1fSSean Nyekjaer 0, 20631aabad1fSSean Nyekjaer IIO_MOD_Z, 20641aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 20651aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 20661aabad1fSSean Nyekjaer timestamp); 20671aabad1fSSean Nyekjaer 20681aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_y_mask) && 20691aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_Y))) 20701aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 20711aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 20721aabad1fSSean Nyekjaer 0, 20731aabad1fSSean Nyekjaer IIO_MOD_Y, 20741aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 20751aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 20761aabad1fSSean Nyekjaer timestamp); 20771aabad1fSSean Nyekjaer 20781aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_x_mask) && 20791aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_X))) 20801aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 20811aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 20821aabad1fSSean Nyekjaer 0, 20831aabad1fSSean Nyekjaer IIO_MOD_X, 20841aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 20851aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 20861aabad1fSSean Nyekjaer timestamp); 2087615bd378SLorenzo Bianconi 2088615bd378SLorenzo Bianconi return data & event_settings->wakeup_src_status_mask; 20891aabad1fSSean Nyekjaer } 20901aabad1fSSean Nyekjaer 20916ee6a368SSean Nyekjaer static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) 20926ee6a368SSean Nyekjaer { 20936ee6a368SSean Nyekjaer struct st_lsm6dsx_hw *hw = private; 2094615bd378SLorenzo Bianconi bool event; 20956ee6a368SSean Nyekjaer int count; 20961aabad1fSSean Nyekjaer 2097615bd378SLorenzo Bianconi event = st_lsm6dsx_report_motion_event(hw); 20986ee6a368SSean Nyekjaer 2099a912ee4cSLorenzo Bianconi if (!hw->settings->fifo_ops.read_fifo) 2100a912ee4cSLorenzo Bianconi return event ? IRQ_HANDLED : IRQ_NONE; 2101a912ee4cSLorenzo Bianconi 21026ee6a368SSean Nyekjaer mutex_lock(&hw->fifo_lock); 21036ee6a368SSean Nyekjaer count = hw->settings->fifo_ops.read_fifo(hw); 21046ee6a368SSean Nyekjaer mutex_unlock(&hw->fifo_lock); 21056ee6a368SSean Nyekjaer 2106615bd378SLorenzo Bianconi return count || event ? IRQ_HANDLED : IRQ_NONE; 21076ee6a368SSean Nyekjaer } 21086ee6a368SSean Nyekjaer 21096ee6a368SSean Nyekjaer static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) 21106ee6a368SSean Nyekjaer { 21116ee6a368SSean Nyekjaer struct device_node *np = hw->dev->of_node; 211231fe8d4eSLorenzo Bianconi struct st_sensors_platform_data *pdata; 211331fe8d4eSLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 21146ee6a368SSean Nyekjaer unsigned long irq_type; 21156ee6a368SSean Nyekjaer bool irq_active_low; 21166ee6a368SSean Nyekjaer int err; 21176ee6a368SSean Nyekjaer 21186ee6a368SSean Nyekjaer irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq)); 21196ee6a368SSean Nyekjaer 21206ee6a368SSean Nyekjaer switch (irq_type) { 21216ee6a368SSean Nyekjaer case IRQF_TRIGGER_HIGH: 21226ee6a368SSean Nyekjaer case IRQF_TRIGGER_RISING: 21236ee6a368SSean Nyekjaer irq_active_low = false; 21246ee6a368SSean Nyekjaer break; 21256ee6a368SSean Nyekjaer case IRQF_TRIGGER_LOW: 21266ee6a368SSean Nyekjaer case IRQF_TRIGGER_FALLING: 21276ee6a368SSean Nyekjaer irq_active_low = true; 21286ee6a368SSean Nyekjaer break; 21296ee6a368SSean Nyekjaer default: 21306ee6a368SSean Nyekjaer dev_info(hw->dev, "mode %lx unsupported\n", irq_type); 21316ee6a368SSean Nyekjaer return -EINVAL; 21326ee6a368SSean Nyekjaer } 21336ee6a368SSean Nyekjaer 213431fe8d4eSLorenzo Bianconi reg = &hw->settings->irq_config.hla; 213531fe8d4eSLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 213631fe8d4eSLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(irq_active_low, 213731fe8d4eSLorenzo Bianconi reg->mask)); 21386ee6a368SSean Nyekjaer if (err < 0) 21396ee6a368SSean Nyekjaer return err; 21406ee6a368SSean Nyekjaer 21416ee6a368SSean Nyekjaer pdata = (struct st_sensors_platform_data *)hw->dev->platform_data; 21426ee6a368SSean Nyekjaer if ((np && of_property_read_bool(np, "drive-open-drain")) || 21436ee6a368SSean Nyekjaer (pdata && pdata->open_drain)) { 214431fe8d4eSLorenzo Bianconi reg = &hw->settings->irq_config.od; 214531fe8d4eSLorenzo Bianconi err = regmap_update_bits(hw->regmap, reg->addr, reg->mask, 214631fe8d4eSLorenzo Bianconi ST_LSM6DSX_SHIFT_VAL(1, reg->mask)); 21476ee6a368SSean Nyekjaer if (err < 0) 21486ee6a368SSean Nyekjaer return err; 21496ee6a368SSean Nyekjaer 21506ee6a368SSean Nyekjaer irq_type |= IRQF_SHARED; 21516ee6a368SSean Nyekjaer } 21526ee6a368SSean Nyekjaer 21536ee6a368SSean Nyekjaer err = devm_request_threaded_irq(hw->dev, hw->irq, 2154a3aa17d4SSean Nyekjaer NULL, 21556ee6a368SSean Nyekjaer st_lsm6dsx_handler_thread, 21566ee6a368SSean Nyekjaer irq_type | IRQF_ONESHOT, 21576ee6a368SSean Nyekjaer "lsm6dsx", hw); 21586ee6a368SSean Nyekjaer if (err) { 21596ee6a368SSean Nyekjaer dev_err(hw->dev, "failed to request trigger irq %d\n", 21606ee6a368SSean Nyekjaer hw->irq); 21616ee6a368SSean Nyekjaer return err; 21626ee6a368SSean Nyekjaer } 21636ee6a368SSean Nyekjaer 21646ee6a368SSean Nyekjaer return 0; 21656ee6a368SSean Nyekjaer } 21666ee6a368SSean Nyekjaer 216781956a93SLorenzo Bianconi int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, 216851a8b707SLorenzo Bianconi struct regmap *regmap) 2169290a6ce1SLorenzo Bianconi { 2170b7a73b33SLorenzo Bianconi struct st_sensors_platform_data *pdata = dev->platform_data; 2171c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 2172b7a73b33SLorenzo Bianconi struct device_node *np = dev->of_node; 2173290a6ce1SLorenzo Bianconi struct st_lsm6dsx_hw *hw; 217481956a93SLorenzo Bianconi const char *name = NULL; 2175290a6ce1SLorenzo Bianconi int i, err; 2176290a6ce1SLorenzo Bianconi 2177290a6ce1SLorenzo Bianconi hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); 2178290a6ce1SLorenzo Bianconi if (!hw) 2179290a6ce1SLorenzo Bianconi return -ENOMEM; 2180290a6ce1SLorenzo Bianconi 2181290a6ce1SLorenzo Bianconi dev_set_drvdata(dev, (void *)hw); 2182290a6ce1SLorenzo Bianconi 2183290a6ce1SLorenzo Bianconi mutex_init(&hw->fifo_lock); 2184335eaedcSLorenzo Bianconi mutex_init(&hw->conf_lock); 2185739aff87SLorenzo Bianconi mutex_init(&hw->page_lock); 2186290a6ce1SLorenzo Bianconi 218791a6b841SLorenzo Bianconi hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL); 218891a6b841SLorenzo Bianconi if (!hw->buff) 218991a6b841SLorenzo Bianconi return -ENOMEM; 219091a6b841SLorenzo Bianconi 2191290a6ce1SLorenzo Bianconi hw->dev = dev; 2192290a6ce1SLorenzo Bianconi hw->irq = irq; 219351a8b707SLorenzo Bianconi hw->regmap = regmap; 2194290a6ce1SLorenzo Bianconi 219581956a93SLorenzo Bianconi err = st_lsm6dsx_check_whoami(hw, hw_id, &name); 2196290a6ce1SLorenzo Bianconi if (err < 0) 2197290a6ce1SLorenzo Bianconi return err; 2198290a6ce1SLorenzo Bianconi 21996ffb55e5SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) { 2200510c0106SLorenzo Bianconi hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name); 2201290a6ce1SLorenzo Bianconi if (!hw->iio_devs[i]) 2202290a6ce1SLorenzo Bianconi return -ENOMEM; 2203290a6ce1SLorenzo Bianconi } 2204290a6ce1SLorenzo Bianconi 2205290a6ce1SLorenzo Bianconi err = st_lsm6dsx_init_device(hw); 2206290a6ce1SLorenzo Bianconi if (err < 0) 2207290a6ce1SLorenzo Bianconi return err; 2208290a6ce1SLorenzo Bianconi 2209c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 2210c91c1c84SLorenzo Bianconi if (hub_settings->master_en.addr) { 2211c91c1c84SLorenzo Bianconi err = st_lsm6dsx_shub_probe(hw, name); 2212c91c1c84SLorenzo Bianconi if (err < 0) 2213c91c1c84SLorenzo Bianconi return err; 2214c91c1c84SLorenzo Bianconi } 2215c91c1c84SLorenzo Bianconi 2216290a6ce1SLorenzo Bianconi if (hw->irq > 0) { 22176ee6a368SSean Nyekjaer err = st_lsm6dsx_irq_setup(hw); 22186ee6a368SSean Nyekjaer if (err < 0) 22196ee6a368SSean Nyekjaer return err; 22206ee6a368SSean Nyekjaer 2221290a6ce1SLorenzo Bianconi err = st_lsm6dsx_fifo_setup(hw); 2222290a6ce1SLorenzo Bianconi if (err < 0) 2223290a6ce1SLorenzo Bianconi return err; 2224290a6ce1SLorenzo Bianconi } 2225290a6ce1SLorenzo Bianconi 2226290a6ce1SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 22276ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 22286ffb55e5SLorenzo Bianconi continue; 22296ffb55e5SLorenzo Bianconi 2230290a6ce1SLorenzo Bianconi err = devm_iio_device_register(hw->dev, hw->iio_devs[i]); 2231290a6ce1SLorenzo Bianconi if (err) 2232290a6ce1SLorenzo Bianconi return err; 2233290a6ce1SLorenzo Bianconi } 2234290a6ce1SLorenzo Bianconi 2235b7a73b33SLorenzo Bianconi if ((np && of_property_read_bool(np, "wakeup-source")) || 2236b7a73b33SLorenzo Bianconi (pdata && pdata->wakeup_source)) 22374c997dfaSSean Nyekjaer device_init_wakeup(dev, true); 22384c997dfaSSean Nyekjaer 2239290a6ce1SLorenzo Bianconi return 0; 2240290a6ce1SLorenzo Bianconi } 2241290a6ce1SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_probe); 2242290a6ce1SLorenzo Bianconi 22433cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_suspend(struct device *dev) 2244d3f77058SLorenzo Bianconi { 2245d3f77058SLorenzo Bianconi struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); 2246d3f77058SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 2247d3f77058SLorenzo Bianconi int i, err = 0; 2248d3f77058SLorenzo Bianconi 2249d3f77058SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 22506ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 22516ffb55e5SLorenzo Bianconi continue; 22526ffb55e5SLorenzo Bianconi 2253d3f77058SLorenzo Bianconi sensor = iio_priv(hw->iio_devs[i]); 2254d3f77058SLorenzo Bianconi if (!(hw->enable_mask & BIT(sensor->id))) 2255d3f77058SLorenzo Bianconi continue; 2256d3f77058SLorenzo Bianconi 22574c997dfaSSean Nyekjaer if (device_may_wakeup(dev) && 22584c997dfaSSean Nyekjaer sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) { 22594c997dfaSSean Nyekjaer /* Enable wake from IRQ */ 22604c997dfaSSean Nyekjaer enable_irq_wake(hw->irq); 22614c997dfaSSean Nyekjaer continue; 22624c997dfaSSean Nyekjaer } 22634c997dfaSSean Nyekjaer 2264bce0d57dSLorenzo Bianconi if (sensor->id == ST_LSM6DSX_ID_EXT0 || 2265bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT1 || 2266bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT2) 2267bce0d57dSLorenzo Bianconi err = st_lsm6dsx_shub_set_enable(sensor, false); 2268bce0d57dSLorenzo Bianconi else 2269bce0d57dSLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, false); 2270d3f77058SLorenzo Bianconi if (err < 0) 2271d3f77058SLorenzo Bianconi return err; 2272bce0d57dSLorenzo Bianconi 2273bce0d57dSLorenzo Bianconi hw->suspend_mask |= BIT(sensor->id); 2274d3f77058SLorenzo Bianconi } 2275d3f77058SLorenzo Bianconi 2276d3f77058SLorenzo Bianconi if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS) 2277d3f77058SLorenzo Bianconi err = st_lsm6dsx_flush_fifo(hw); 2278d3f77058SLorenzo Bianconi 2279d3f77058SLorenzo Bianconi return err; 2280d3f77058SLorenzo Bianconi } 2281d3f77058SLorenzo Bianconi 22823cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_resume(struct device *dev) 2283d3f77058SLorenzo Bianconi { 2284d3f77058SLorenzo Bianconi struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); 2285d3f77058SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 2286d3f77058SLorenzo Bianconi int i, err = 0; 2287d3f77058SLorenzo Bianconi 2288d3f77058SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 22896ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 22906ffb55e5SLorenzo Bianconi continue; 22916ffb55e5SLorenzo Bianconi 2292d3f77058SLorenzo Bianconi sensor = iio_priv(hw->iio_devs[i]); 22934c997dfaSSean Nyekjaer if (device_may_wakeup(dev) && 22944c997dfaSSean Nyekjaer sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) 22954c997dfaSSean Nyekjaer disable_irq_wake(hw->irq); 22964c997dfaSSean Nyekjaer 2297bce0d57dSLorenzo Bianconi if (!(hw->suspend_mask & BIT(sensor->id))) 2298d3f77058SLorenzo Bianconi continue; 2299d3f77058SLorenzo Bianconi 2300bce0d57dSLorenzo Bianconi if (sensor->id == ST_LSM6DSX_ID_EXT0 || 2301bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT1 || 2302bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT2) 2303bce0d57dSLorenzo Bianconi err = st_lsm6dsx_shub_set_enable(sensor, true); 2304bce0d57dSLorenzo Bianconi else 2305bce0d57dSLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, true); 2306d3f77058SLorenzo Bianconi if (err < 0) 2307d3f77058SLorenzo Bianconi return err; 2308bce0d57dSLorenzo Bianconi 2309bce0d57dSLorenzo Bianconi hw->suspend_mask &= ~BIT(sensor->id); 2310d3f77058SLorenzo Bianconi } 2311d3f77058SLorenzo Bianconi 2312d3f77058SLorenzo Bianconi if (hw->enable_mask) 2313d3f77058SLorenzo Bianconi err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT); 2314d3f77058SLorenzo Bianconi 2315d3f77058SLorenzo Bianconi return err; 2316d3f77058SLorenzo Bianconi } 2317d3f77058SLorenzo Bianconi 2318d3f77058SLorenzo Bianconi const struct dev_pm_ops st_lsm6dsx_pm_ops = { 2319d3f77058SLorenzo Bianconi SET_SYSTEM_SLEEP_PM_OPS(st_lsm6dsx_suspend, st_lsm6dsx_resume) 2320d3f77058SLorenzo Bianconi }; 2321d3f77058SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_pm_ops); 2322d3f77058SLorenzo Bianconi 2323290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>"); 2324290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 2325290a6ce1SLorenzo Bianconi MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver"); 2326290a6ce1SLorenzo Bianconi MODULE_LICENSE("GPL v2"); 2327