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_FIFO_FTH_IRQ_MASK BIT(3) 65290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_WHOAMI_ADDR 0x0f 66290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_RESET_MASK BIT(0) 6719435425SLorenzo Bianconi #define ST_LSM6DSX_REG_BOOT_MASK BIT(7) 68290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_BDU_ADDR 0x12 69290a6ce1SLorenzo Bianconi #define ST_LSM6DSX_REG_BDU_MASK BIT(6) 70290a6ce1SLorenzo Bianconi 716ee6a368SSean Nyekjaer #define ST_LSM6DSX_REG_HLACTIVE_ADDR 0x12 726ee6a368SSean Nyekjaer #define ST_LSM6DSX_REG_HLACTIVE_MASK BIT(5) 736ee6a368SSean Nyekjaer #define ST_LSM6DSX_REG_PP_OD_ADDR 0x12 746ee6a368SSean Nyekjaer #define ST_LSM6DSX_REG_PP_OD_MASK BIT(4) 756ee6a368SSean Nyekjaer 76f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = { 77b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x28, IIO_MOD_X, 0), 78b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1), 79b5969abfSSean Nyekjaer ST_LSM6DSX_CHANNEL_ACC(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2), 80f48bc49bSLorenzo Bianconi IIO_CHAN_SOFT_TIMESTAMP(3), 81f48bc49bSLorenzo Bianconi }; 82f48bc49bSLorenzo Bianconi 83f48bc49bSLorenzo Bianconi static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = { 84f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0), 85f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1), 86f48bc49bSLorenzo Bianconi ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2), 87f48bc49bSLorenzo Bianconi IIO_CHAN_SOFT_TIMESTAMP(3), 88f48bc49bSLorenzo Bianconi }; 89f48bc49bSLorenzo Bianconi 9052f4b1f1SMartin Kepplinger static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = { 9152f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0), 9252f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1), 9352f4b1f1SMartin Kepplinger ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2), 9452f4b1f1SMartin Kepplinger IIO_CHAN_SOFT_TIMESTAMP(3), 9552f4b1f1SMartin Kepplinger }; 9652f4b1f1SMartin Kepplinger 97290a6ce1SLorenzo Bianconi static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { 98290a6ce1SLorenzo Bianconi { 9952f4b1f1SMartin Kepplinger .wai = 0x68, 10052f4b1f1SMartin Kepplinger .int1_addr = 0x0c, 10152f4b1f1SMartin Kepplinger .int2_addr = 0x0d, 10252f4b1f1SMartin Kepplinger .reset_addr = 0x22, 10352f4b1f1SMartin Kepplinger .max_fifo_size = 32, 10452f4b1f1SMartin Kepplinger .id = { 10552f4b1f1SMartin Kepplinger { 10652f4b1f1SMartin Kepplinger .hw_id = ST_LSM9DS1_ID, 10752f4b1f1SMartin Kepplinger .name = ST_LSM9DS1_DEV_NAME, 10852f4b1f1SMartin Kepplinger }, 10952f4b1f1SMartin Kepplinger }, 11052f4b1f1SMartin Kepplinger .channels = { 11152f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 11252f4b1f1SMartin Kepplinger .chan = st_lsm6dsx_acc_channels, 11352f4b1f1SMartin Kepplinger .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 11452f4b1f1SMartin Kepplinger }, 11552f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 11652f4b1f1SMartin Kepplinger .chan = st_lsm6ds0_gyro_channels, 11752f4b1f1SMartin Kepplinger .len = ARRAY_SIZE(st_lsm6ds0_gyro_channels), 11852f4b1f1SMartin Kepplinger }, 11952f4b1f1SMartin Kepplinger }, 12052f4b1f1SMartin Kepplinger .odr_table = { 12152f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 12252f4b1f1SMartin Kepplinger .reg = { 12352f4b1f1SMartin Kepplinger .addr = 0x20, 12452f4b1f1SMartin Kepplinger .mask = GENMASK(7, 5), 12552f4b1f1SMartin Kepplinger }, 12652f4b1f1SMartin Kepplinger .odr_avl[0] = { 10, 0x01 }, 12752f4b1f1SMartin Kepplinger .odr_avl[1] = { 50, 0x02 }, 12852f4b1f1SMartin Kepplinger .odr_avl[2] = { 119, 0x03 }, 12952f4b1f1SMartin Kepplinger .odr_avl[3] = { 238, 0x04 }, 13052f4b1f1SMartin Kepplinger .odr_avl[4] = { 476, 0x05 }, 13152f4b1f1SMartin Kepplinger .odr_avl[5] = { 952, 0x06 }, 13252f4b1f1SMartin Kepplinger }, 13352f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 13452f4b1f1SMartin Kepplinger .reg = { 13552f4b1f1SMartin Kepplinger .addr = 0x10, 13652f4b1f1SMartin Kepplinger .mask = GENMASK(7, 5), 13752f4b1f1SMartin Kepplinger }, 13852f4b1f1SMartin Kepplinger .odr_avl[0] = { 15, 0x01 }, 13952f4b1f1SMartin Kepplinger .odr_avl[1] = { 60, 0x02 }, 14052f4b1f1SMartin Kepplinger .odr_avl[2] = { 119, 0x03 }, 14152f4b1f1SMartin Kepplinger .odr_avl[3] = { 238, 0x04 }, 14252f4b1f1SMartin Kepplinger .odr_avl[4] = { 476, 0x05 }, 14352f4b1f1SMartin Kepplinger .odr_avl[5] = { 952, 0x06 }, 14452f4b1f1SMartin Kepplinger }, 14552f4b1f1SMartin Kepplinger }, 14652f4b1f1SMartin Kepplinger .fs_table = { 14752f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_ACC] = { 14852f4b1f1SMartin Kepplinger .reg = { 14952f4b1f1SMartin Kepplinger .addr = 0x20, 15052f4b1f1SMartin Kepplinger .mask = GENMASK(4, 3), 15152f4b1f1SMartin Kepplinger }, 1526fa02948SLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 1536fa02948SLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 1546fa02948SLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 1556fa02948SLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 }, 15685ae3aeeSLorenzo Bianconi .fs_len = 4, 15752f4b1f1SMartin Kepplinger }, 15852f4b1f1SMartin Kepplinger [ST_LSM6DSX_ID_GYRO] = { 15952f4b1f1SMartin Kepplinger .reg = { 16052f4b1f1SMartin Kepplinger .addr = 0x10, 16152f4b1f1SMartin Kepplinger .mask = GENMASK(4, 3), 16252f4b1f1SMartin Kepplinger }, 16352f4b1f1SMartin Kepplinger .fs_avl[0] = { IIO_DEGREE_TO_RAD(245), 0x0 }, 16452f4b1f1SMartin Kepplinger .fs_avl[1] = { IIO_DEGREE_TO_RAD(500), 0x1 }, 1650f7e1728SLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(2000), 0x3 }, 16685ae3aeeSLorenzo Bianconi .fs_len = 3, 16752f4b1f1SMartin Kepplinger }, 16852f4b1f1SMartin Kepplinger }, 16952f4b1f1SMartin Kepplinger }, 17052f4b1f1SMartin Kepplinger { 171d068e4a0SLorenzo Bianconi .wai = 0x69, 1725022c5a4SMartin Kepplinger .int1_addr = 0x0d, 1735022c5a4SMartin Kepplinger .int2_addr = 0x0e, 174b5969abfSSean Nyekjaer .int1_func_addr = 0x5e, 175b5969abfSSean Nyekjaer .int2_func_addr = 0x5f, 176b5969abfSSean Nyekjaer .int_func_mask = BIT(5), 1775022c5a4SMartin Kepplinger .reset_addr = 0x12, 1788f2a88a2SLorenzo Bianconi .max_fifo_size = 1365, 179d068e4a0SLorenzo Bianconi .id = { 18081956a93SLorenzo Bianconi { 18181956a93SLorenzo Bianconi .hw_id = ST_LSM6DS3_ID, 18281956a93SLorenzo Bianconi .name = ST_LSM6DS3_DEV_NAME, 18381956a93SLorenzo Bianconi }, 184d068e4a0SLorenzo Bianconi }, 185f48bc49bSLorenzo Bianconi .channels = { 186f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 187f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 188f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 189f48bc49bSLorenzo Bianconi }, 190f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 191f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 192f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 193f48bc49bSLorenzo Bianconi }, 194f48bc49bSLorenzo Bianconi }, 19540dd7343SLorenzo Bianconi .odr_table = { 19640dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 19740dd7343SLorenzo Bianconi .reg = { 19840dd7343SLorenzo Bianconi .addr = 0x10, 19940dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 20040dd7343SLorenzo Bianconi }, 20140dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 20240dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 20340dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 20440dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 20540dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 20640dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 20740dd7343SLorenzo Bianconi }, 20840dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 20940dd7343SLorenzo Bianconi .reg = { 21040dd7343SLorenzo Bianconi .addr = 0x11, 21140dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 21240dd7343SLorenzo Bianconi }, 21340dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 21440dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 21540dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 21640dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 21740dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 21840dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 21940dd7343SLorenzo Bianconi }, 22040dd7343SLorenzo Bianconi }, 221640aca3fSLorenzo Bianconi .fs_table = { 222640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 223640aca3fSLorenzo Bianconi .reg = { 224640aca3fSLorenzo Bianconi .addr = 0x10, 225640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 226640aca3fSLorenzo Bianconi }, 227640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 228640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 229640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 230640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 23185ae3aeeSLorenzo Bianconi .fs_len = 4, 232640aca3fSLorenzo Bianconi }, 233640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 234640aca3fSLorenzo Bianconi .reg = { 235640aca3fSLorenzo Bianconi .addr = 0x11, 236640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 237640aca3fSLorenzo Bianconi }, 238640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 239640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 240640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 241640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 24285ae3aeeSLorenzo Bianconi .fs_len = 4, 243640aca3fSLorenzo Bianconi }, 244640aca3fSLorenzo Bianconi }, 2457ca3ac9eSLorenzo Bianconi .decimator = { 2467ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 2477ca3ac9eSLorenzo Bianconi .addr = 0x08, 2487ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 2497ca3ac9eSLorenzo Bianconi }, 2507ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 2517ca3ac9eSLorenzo Bianconi .addr = 0x08, 2527ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 2537ca3ac9eSLorenzo Bianconi }, 2547ca3ac9eSLorenzo Bianconi }, 2559db02d32SLorenzo Bianconi .lir = { 2569db02d32SLorenzo Bianconi .addr = 0x58, 2579db02d32SLorenzo Bianconi .mask = BIT(0), 2589db02d32SLorenzo Bianconi }, 25992617c15SLorenzo Bianconi .fifo_ops = { 2603b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 26150ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 26292617c15SLorenzo Bianconi .fifo_th = { 26392617c15SLorenzo Bianconi .addr = 0x06, 26492617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 26592617c15SLorenzo Bianconi }, 26692617c15SLorenzo Bianconi .fifo_diff = { 26792617c15SLorenzo Bianconi .addr = 0x3a, 26892617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 26992617c15SLorenzo Bianconi }, 27092617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 27192617c15SLorenzo Bianconi }, 27221345107SLorenzo Bianconi .ts_settings = { 27321345107SLorenzo Bianconi .timer_en = { 27421345107SLorenzo Bianconi .addr = 0x58, 27521345107SLorenzo Bianconi .mask = BIT(7), 27621345107SLorenzo Bianconi }, 27721345107SLorenzo Bianconi .hr_timer = { 27821345107SLorenzo Bianconi .addr = 0x5c, 27921345107SLorenzo Bianconi .mask = BIT(4), 28021345107SLorenzo Bianconi }, 28121345107SLorenzo Bianconi .fifo_en = { 28221345107SLorenzo Bianconi .addr = 0x07, 28321345107SLorenzo Bianconi .mask = BIT(7), 28421345107SLorenzo Bianconi }, 28521345107SLorenzo Bianconi .decimator = { 28621345107SLorenzo Bianconi .addr = 0x09, 28721345107SLorenzo Bianconi .mask = GENMASK(5, 3), 28821345107SLorenzo Bianconi }, 28921345107SLorenzo Bianconi }, 290b5969abfSSean Nyekjaer .event_settings = { 291b5969abfSSean Nyekjaer .wakeup_reg = { 292b5969abfSSean Nyekjaer .addr = 0x5B, 293b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 294b5969abfSSean Nyekjaer }, 2951aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 2961aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 2971aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 2981aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 2991aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 300b5969abfSSean Nyekjaer }, 301290a6ce1SLorenzo Bianconi }, 302290a6ce1SLorenzo Bianconi { 303df47710aSLorenzo Bianconi .wai = 0x69, 3045022c5a4SMartin Kepplinger .int1_addr = 0x0d, 3055022c5a4SMartin Kepplinger .int2_addr = 0x0e, 306b5969abfSSean Nyekjaer .int1_func_addr = 0x5e, 307b5969abfSSean Nyekjaer .int2_func_addr = 0x5f, 308b5969abfSSean Nyekjaer .int_func_mask = BIT(5), 3095022c5a4SMartin Kepplinger .reset_addr = 0x12, 3108f2a88a2SLorenzo Bianconi .max_fifo_size = 682, 311df47710aSLorenzo Bianconi .id = { 31281956a93SLorenzo Bianconi { 31381956a93SLorenzo Bianconi .hw_id = ST_LSM6DS3H_ID, 31481956a93SLorenzo Bianconi .name = ST_LSM6DS3H_DEV_NAME, 31581956a93SLorenzo Bianconi }, 316df47710aSLorenzo Bianconi }, 317f48bc49bSLorenzo Bianconi .channels = { 318f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 319f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 320f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 321f48bc49bSLorenzo Bianconi }, 322f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 323f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 324f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 325f48bc49bSLorenzo Bianconi }, 326f48bc49bSLorenzo Bianconi }, 32740dd7343SLorenzo Bianconi .odr_table = { 32840dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 32940dd7343SLorenzo Bianconi .reg = { 33040dd7343SLorenzo Bianconi .addr = 0x10, 33140dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 33240dd7343SLorenzo Bianconi }, 33340dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 33440dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 33540dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 33640dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 33740dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 33840dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 33940dd7343SLorenzo Bianconi }, 34040dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 34140dd7343SLorenzo Bianconi .reg = { 34240dd7343SLorenzo Bianconi .addr = 0x11, 34340dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 34440dd7343SLorenzo Bianconi }, 34540dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 34640dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 34740dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 34840dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 34940dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 35040dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 35140dd7343SLorenzo Bianconi }, 35240dd7343SLorenzo Bianconi }, 353640aca3fSLorenzo Bianconi .fs_table = { 354640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 355640aca3fSLorenzo Bianconi .reg = { 356640aca3fSLorenzo Bianconi .addr = 0x10, 357640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 358640aca3fSLorenzo Bianconi }, 359640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 360640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 361640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 362640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 36385ae3aeeSLorenzo Bianconi .fs_len = 4, 364640aca3fSLorenzo Bianconi }, 365640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 366640aca3fSLorenzo Bianconi .reg = { 367640aca3fSLorenzo Bianconi .addr = 0x11, 368640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 369640aca3fSLorenzo Bianconi }, 370640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 371640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 372640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 373640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 37485ae3aeeSLorenzo Bianconi .fs_len = 4, 375640aca3fSLorenzo Bianconi }, 376640aca3fSLorenzo Bianconi }, 3777ca3ac9eSLorenzo Bianconi .decimator = { 3787ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 3797ca3ac9eSLorenzo Bianconi .addr = 0x08, 3807ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 3817ca3ac9eSLorenzo Bianconi }, 3827ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 3837ca3ac9eSLorenzo Bianconi .addr = 0x08, 3847ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 3857ca3ac9eSLorenzo Bianconi }, 3867ca3ac9eSLorenzo Bianconi }, 3879db02d32SLorenzo Bianconi .lir = { 3889db02d32SLorenzo Bianconi .addr = 0x58, 3899db02d32SLorenzo Bianconi .mask = BIT(0), 3909db02d32SLorenzo Bianconi }, 39192617c15SLorenzo Bianconi .fifo_ops = { 3923b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 39350ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 39492617c15SLorenzo Bianconi .fifo_th = { 39592617c15SLorenzo Bianconi .addr = 0x06, 39692617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 39792617c15SLorenzo Bianconi }, 39892617c15SLorenzo Bianconi .fifo_diff = { 39992617c15SLorenzo Bianconi .addr = 0x3a, 40092617c15SLorenzo Bianconi .mask = GENMASK(11, 0), 40192617c15SLorenzo Bianconi }, 40292617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 40392617c15SLorenzo Bianconi }, 40421345107SLorenzo Bianconi .ts_settings = { 40521345107SLorenzo Bianconi .timer_en = { 40621345107SLorenzo Bianconi .addr = 0x58, 40721345107SLorenzo Bianconi .mask = BIT(7), 40821345107SLorenzo Bianconi }, 40921345107SLorenzo Bianconi .hr_timer = { 41021345107SLorenzo Bianconi .addr = 0x5c, 41121345107SLorenzo Bianconi .mask = BIT(4), 41221345107SLorenzo Bianconi }, 41321345107SLorenzo Bianconi .fifo_en = { 41421345107SLorenzo Bianconi .addr = 0x07, 41521345107SLorenzo Bianconi .mask = BIT(7), 41621345107SLorenzo Bianconi }, 41721345107SLorenzo Bianconi .decimator = { 41821345107SLorenzo Bianconi .addr = 0x09, 41921345107SLorenzo Bianconi .mask = GENMASK(5, 3), 42021345107SLorenzo Bianconi }, 42121345107SLorenzo Bianconi }, 422b5969abfSSean Nyekjaer .event_settings = { 423b5969abfSSean Nyekjaer .wakeup_reg = { 424b5969abfSSean Nyekjaer .addr = 0x5B, 425b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 426b5969abfSSean Nyekjaer }, 4271aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 4281aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 4291aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 4301aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 4311aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 432b5969abfSSean Nyekjaer }, 433df47710aSLorenzo Bianconi }, 434df47710aSLorenzo Bianconi { 435d068e4a0SLorenzo Bianconi .wai = 0x6a, 4365022c5a4SMartin Kepplinger .int1_addr = 0x0d, 4375022c5a4SMartin Kepplinger .int2_addr = 0x0e, 438b5969abfSSean Nyekjaer .int1_func_addr = 0x5e, 439b5969abfSSean Nyekjaer .int2_func_addr = 0x5f, 440b5969abfSSean Nyekjaer .int_func_mask = BIT(5), 4415022c5a4SMartin Kepplinger .reset_addr = 0x12, 4428f2a88a2SLorenzo Bianconi .max_fifo_size = 682, 443d068e4a0SLorenzo Bianconi .id = { 44481956a93SLorenzo Bianconi { 44581956a93SLorenzo Bianconi .hw_id = ST_LSM6DSL_ID, 44681956a93SLorenzo Bianconi .name = ST_LSM6DSL_DEV_NAME, 44781956a93SLorenzo Bianconi }, { 44881956a93SLorenzo Bianconi .hw_id = ST_LSM6DSM_ID, 44981956a93SLorenzo Bianconi .name = ST_LSM6DSM_DEV_NAME, 45081956a93SLorenzo Bianconi }, { 45181956a93SLorenzo Bianconi .hw_id = ST_ISM330DLC_ID, 45281956a93SLorenzo Bianconi .name = ST_ISM330DLC_DEV_NAME, 453dbcd2088SLorenzo Bianconi }, { 454dbcd2088SLorenzo Bianconi .hw_id = ST_LSM6DS3TRC_ID, 455dbcd2088SLorenzo Bianconi .name = ST_LSM6DS3TRC_DEV_NAME, 45681956a93SLorenzo Bianconi }, 457d068e4a0SLorenzo Bianconi }, 458f48bc49bSLorenzo Bianconi .channels = { 459f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 460f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 461f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 462f48bc49bSLorenzo Bianconi }, 463f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 464f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 465f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 466f48bc49bSLorenzo Bianconi }, 467f48bc49bSLorenzo Bianconi }, 46840dd7343SLorenzo Bianconi .odr_table = { 46940dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 47040dd7343SLorenzo Bianconi .reg = { 47140dd7343SLorenzo Bianconi .addr = 0x10, 47240dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 47340dd7343SLorenzo Bianconi }, 47440dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 47540dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 47640dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 47740dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 47840dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 47940dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 48040dd7343SLorenzo Bianconi }, 48140dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 48240dd7343SLorenzo Bianconi .reg = { 48340dd7343SLorenzo Bianconi .addr = 0x11, 48440dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 48540dd7343SLorenzo Bianconi }, 48640dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 48740dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 48840dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 48940dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 49040dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 49140dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 49240dd7343SLorenzo Bianconi }, 49340dd7343SLorenzo Bianconi }, 494640aca3fSLorenzo Bianconi .fs_table = { 495640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 496640aca3fSLorenzo Bianconi .reg = { 497640aca3fSLorenzo Bianconi .addr = 0x10, 498640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 499640aca3fSLorenzo Bianconi }, 500640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 501640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 502640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 503640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 50485ae3aeeSLorenzo Bianconi .fs_len = 4, 505640aca3fSLorenzo Bianconi }, 506640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 507640aca3fSLorenzo Bianconi .reg = { 508640aca3fSLorenzo Bianconi .addr = 0x11, 509640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 510640aca3fSLorenzo Bianconi }, 511640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 512640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 513640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 514640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 51585ae3aeeSLorenzo Bianconi .fs_len = 4, 516640aca3fSLorenzo Bianconi }, 517640aca3fSLorenzo Bianconi }, 5187ca3ac9eSLorenzo Bianconi .decimator = { 5197ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 5207ca3ac9eSLorenzo Bianconi .addr = 0x08, 5217ca3ac9eSLorenzo Bianconi .mask = GENMASK(2, 0), 5227ca3ac9eSLorenzo Bianconi }, 5237ca3ac9eSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 5247ca3ac9eSLorenzo Bianconi .addr = 0x08, 5257ca3ac9eSLorenzo Bianconi .mask = GENMASK(5, 3), 5267ca3ac9eSLorenzo Bianconi }, 5277ca3ac9eSLorenzo Bianconi }, 5289db02d32SLorenzo Bianconi .lir = { 5299db02d32SLorenzo Bianconi .addr = 0x58, 5309db02d32SLorenzo Bianconi .mask = BIT(0), 5319db02d32SLorenzo Bianconi }, 53292617c15SLorenzo Bianconi .fifo_ops = { 5333b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 53450ff457dSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_fifo, 53592617c15SLorenzo Bianconi .fifo_th = { 53692617c15SLorenzo Bianconi .addr = 0x06, 537be75eb86SLorenzo Bianconi .mask = GENMASK(10, 0), 53892617c15SLorenzo Bianconi }, 53992617c15SLorenzo Bianconi .fifo_diff = { 54092617c15SLorenzo Bianconi .addr = 0x3a, 541be75eb86SLorenzo Bianconi .mask = GENMASK(10, 0), 54292617c15SLorenzo Bianconi }, 54392617c15SLorenzo Bianconi .th_wl = 3, /* 1LSB = 2B */ 54492617c15SLorenzo Bianconi }, 54521345107SLorenzo Bianconi .ts_settings = { 54621345107SLorenzo Bianconi .timer_en = { 54721345107SLorenzo Bianconi .addr = 0x19, 54821345107SLorenzo Bianconi .mask = BIT(5), 54921345107SLorenzo Bianconi }, 55021345107SLorenzo Bianconi .hr_timer = { 55121345107SLorenzo Bianconi .addr = 0x5c, 55221345107SLorenzo Bianconi .mask = BIT(4), 55321345107SLorenzo Bianconi }, 55421345107SLorenzo Bianconi .fifo_en = { 55521345107SLorenzo Bianconi .addr = 0x07, 55621345107SLorenzo Bianconi .mask = BIT(7), 55721345107SLorenzo Bianconi }, 55821345107SLorenzo Bianconi .decimator = { 55921345107SLorenzo Bianconi .addr = 0x09, 56021345107SLorenzo Bianconi .mask = GENMASK(5, 3), 56121345107SLorenzo Bianconi }, 56221345107SLorenzo Bianconi }, 563b5969abfSSean Nyekjaer .event_settings = { 564b5969abfSSean Nyekjaer .enable_reg = { 565b5969abfSSean Nyekjaer .addr = 0x58, 566b5969abfSSean Nyekjaer .mask = BIT(7), 567b5969abfSSean Nyekjaer }, 568b5969abfSSean Nyekjaer .wakeup_reg = { 569b5969abfSSean Nyekjaer .addr = 0x5B, 570b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 571b5969abfSSean Nyekjaer }, 5721aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 5731aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 5741aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 5751aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 5761aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 577b5969abfSSean Nyekjaer }, 578290a6ce1SLorenzo Bianconi }, 579801a6e0aSLorenzo Bianconi { 580801a6e0aSLorenzo Bianconi .wai = 0x6c, 5815022c5a4SMartin Kepplinger .int1_addr = 0x0d, 5825022c5a4SMartin Kepplinger .int2_addr = 0x0e, 5835022c5a4SMartin Kepplinger .reset_addr = 0x12, 584801a6e0aSLorenzo Bianconi .max_fifo_size = 512, 585801a6e0aSLorenzo Bianconi .id = { 58681956a93SLorenzo Bianconi { 58781956a93SLorenzo Bianconi .hw_id = ST_LSM6DSO_ID, 58881956a93SLorenzo Bianconi .name = ST_LSM6DSO_DEV_NAME, 58981956a93SLorenzo Bianconi }, { 59081956a93SLorenzo Bianconi .hw_id = ST_LSM6DSOX_ID, 59181956a93SLorenzo Bianconi .name = ST_LSM6DSOX_DEV_NAME, 59281956a93SLorenzo Bianconi }, 593801a6e0aSLorenzo Bianconi }, 594f48bc49bSLorenzo Bianconi .channels = { 595f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 596f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 597f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 598f48bc49bSLorenzo Bianconi }, 599f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 600f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 601f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 602f48bc49bSLorenzo Bianconi }, 603f48bc49bSLorenzo Bianconi }, 60440dd7343SLorenzo Bianconi .odr_table = { 60540dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 60640dd7343SLorenzo Bianconi .reg = { 60740dd7343SLorenzo Bianconi .addr = 0x10, 60840dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 60940dd7343SLorenzo Bianconi }, 61040dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 61140dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 61240dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 61340dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 61440dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 61540dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 61640dd7343SLorenzo Bianconi }, 61740dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 61840dd7343SLorenzo Bianconi .reg = { 61940dd7343SLorenzo Bianconi .addr = 0x11, 62040dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 62140dd7343SLorenzo Bianconi }, 62240dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 62340dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 62440dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 62540dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 62640dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 62740dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 62840dd7343SLorenzo Bianconi }, 62940dd7343SLorenzo Bianconi }, 630640aca3fSLorenzo Bianconi .fs_table = { 631640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 632640aca3fSLorenzo Bianconi .reg = { 633640aca3fSLorenzo Bianconi .addr = 0x10, 634640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 635640aca3fSLorenzo Bianconi }, 636640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 637640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 638640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 639640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 64085ae3aeeSLorenzo Bianconi .fs_len = 4, 641640aca3fSLorenzo Bianconi }, 642640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 643640aca3fSLorenzo Bianconi .reg = { 644640aca3fSLorenzo Bianconi .addr = 0x11, 645640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 646640aca3fSLorenzo Bianconi }, 647640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 648640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 649640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 650640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 65185ae3aeeSLorenzo Bianconi .fs_len = 4, 652640aca3fSLorenzo Bianconi }, 653640aca3fSLorenzo Bianconi }, 654801a6e0aSLorenzo Bianconi .batch = { 655801a6e0aSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 656801a6e0aSLorenzo Bianconi .addr = 0x09, 657801a6e0aSLorenzo Bianconi .mask = GENMASK(3, 0), 658801a6e0aSLorenzo Bianconi }, 659801a6e0aSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 660801a6e0aSLorenzo Bianconi .addr = 0x09, 661801a6e0aSLorenzo Bianconi .mask = GENMASK(7, 4), 662801a6e0aSLorenzo Bianconi }, 663801a6e0aSLorenzo Bianconi }, 6649db02d32SLorenzo Bianconi .lir = { 6659db02d32SLorenzo Bianconi .addr = 0x56, 6669db02d32SLorenzo Bianconi .mask = BIT(0), 6679db02d32SLorenzo Bianconi }, 66822ea5651SLorenzo Bianconi .clear_on_read = { 66922ea5651SLorenzo Bianconi .addr = 0x56, 67022ea5651SLorenzo Bianconi .mask = BIT(6), 67122ea5651SLorenzo Bianconi }, 672801a6e0aSLorenzo Bianconi .fifo_ops = { 6733b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 674801a6e0aSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 675801a6e0aSLorenzo Bianconi .fifo_th = { 676801a6e0aSLorenzo Bianconi .addr = 0x07, 677801a6e0aSLorenzo Bianconi .mask = GENMASK(8, 0), 678801a6e0aSLorenzo Bianconi }, 679801a6e0aSLorenzo Bianconi .fifo_diff = { 680801a6e0aSLorenzo Bianconi .addr = 0x3a, 68170575abeSmario tesi .mask = GENMASK(9, 0), 682801a6e0aSLorenzo Bianconi }, 683801a6e0aSLorenzo Bianconi .th_wl = 1, 684801a6e0aSLorenzo Bianconi }, 685801a6e0aSLorenzo Bianconi .ts_settings = { 686801a6e0aSLorenzo Bianconi .timer_en = { 687801a6e0aSLorenzo Bianconi .addr = 0x19, 688801a6e0aSLorenzo Bianconi .mask = BIT(5), 689801a6e0aSLorenzo Bianconi }, 690801a6e0aSLorenzo Bianconi .decimator = { 691801a6e0aSLorenzo Bianconi .addr = 0x0a, 692801a6e0aSLorenzo Bianconi .mask = GENMASK(7, 6), 693801a6e0aSLorenzo Bianconi }, 694801a6e0aSLorenzo Bianconi }, 695c91c1c84SLorenzo Bianconi .shub_settings = { 696c91c1c84SLorenzo Bianconi .page_mux = { 697c91c1c84SLorenzo Bianconi .addr = 0x01, 698c91c1c84SLorenzo Bianconi .mask = BIT(6), 699c91c1c84SLorenzo Bianconi }, 700c91c1c84SLorenzo Bianconi .master_en = { 701c91c1c84SLorenzo Bianconi .addr = 0x14, 702c91c1c84SLorenzo Bianconi .mask = BIT(2), 703c91c1c84SLorenzo Bianconi }, 704c91c1c84SLorenzo Bianconi .pullup_en = { 705c91c1c84SLorenzo Bianconi .addr = 0x14, 706c91c1c84SLorenzo Bianconi .mask = BIT(3), 707c91c1c84SLorenzo Bianconi }, 708c91c1c84SLorenzo Bianconi .aux_sens = { 709c91c1c84SLorenzo Bianconi .addr = 0x14, 710c91c1c84SLorenzo Bianconi .mask = GENMASK(1, 0), 711c91c1c84SLorenzo Bianconi }, 7126d0205fdSLorenzo Bianconi .wr_once = { 7136d0205fdSLorenzo Bianconi .addr = 0x14, 7146d0205fdSLorenzo Bianconi .mask = BIT(6), 7156d0205fdSLorenzo Bianconi }, 716c91c1c84SLorenzo Bianconi .shub_out = 0x02, 717c91c1c84SLorenzo Bianconi .slv0_addr = 0x15, 718c91c1c84SLorenzo Bianconi .dw_slv0_addr = 0x21, 7196d0205fdSLorenzo Bianconi .batch_en = BIT(3), 720c91c1c84SLorenzo Bianconi } 721801a6e0aSLorenzo Bianconi }, 7223054c4ffSLorenzo Bianconi { 7233054c4ffSLorenzo Bianconi .wai = 0x6b, 7245022c5a4SMartin Kepplinger .int1_addr = 0x0d, 7255022c5a4SMartin Kepplinger .int2_addr = 0x0e, 726b5969abfSSean Nyekjaer .int1_func_addr = 0x5e, 727b5969abfSSean Nyekjaer .int2_func_addr = 0x5f, 728b5969abfSSean Nyekjaer .int_func_mask = BIT(5), 7295022c5a4SMartin Kepplinger .reset_addr = 0x12, 7303054c4ffSLorenzo Bianconi .max_fifo_size = 512, 7313054c4ffSLorenzo Bianconi .id = { 73281956a93SLorenzo Bianconi { 73381956a93SLorenzo Bianconi .hw_id = ST_ASM330LHH_ID, 73481956a93SLorenzo Bianconi .name = ST_ASM330LHH_DEV_NAME, 73581956a93SLorenzo Bianconi }, 7363054c4ffSLorenzo Bianconi }, 737f48bc49bSLorenzo Bianconi .channels = { 738f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 739f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 740f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 741f48bc49bSLorenzo Bianconi }, 742f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 743f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 744f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 745f48bc49bSLorenzo Bianconi }, 746f48bc49bSLorenzo Bianconi }, 74740dd7343SLorenzo Bianconi .odr_table = { 74840dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 74940dd7343SLorenzo Bianconi .reg = { 75040dd7343SLorenzo Bianconi .addr = 0x10, 75140dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 75240dd7343SLorenzo Bianconi }, 75340dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 75440dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 75540dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 75640dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 75740dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 75840dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 75940dd7343SLorenzo Bianconi }, 76040dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 76140dd7343SLorenzo Bianconi .reg = { 76240dd7343SLorenzo Bianconi .addr = 0x11, 76340dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 76440dd7343SLorenzo Bianconi }, 76540dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 76640dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 76740dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 76840dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 76940dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 77040dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 77140dd7343SLorenzo Bianconi }, 77240dd7343SLorenzo Bianconi }, 773640aca3fSLorenzo Bianconi .fs_table = { 774640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 775640aca3fSLorenzo Bianconi .reg = { 776640aca3fSLorenzo Bianconi .addr = 0x10, 777640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 778640aca3fSLorenzo Bianconi }, 779640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 780640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 781640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 782640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 78385ae3aeeSLorenzo Bianconi .fs_len = 4, 784640aca3fSLorenzo Bianconi }, 785640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 786640aca3fSLorenzo Bianconi .reg = { 787640aca3fSLorenzo Bianconi .addr = 0x11, 788640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 789640aca3fSLorenzo Bianconi }, 790640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 791640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 792640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 793640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 79485ae3aeeSLorenzo Bianconi .fs_len = 4, 795640aca3fSLorenzo Bianconi }, 796640aca3fSLorenzo Bianconi }, 7973054c4ffSLorenzo Bianconi .batch = { 7983054c4ffSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 7993054c4ffSLorenzo Bianconi .addr = 0x09, 8003054c4ffSLorenzo Bianconi .mask = GENMASK(3, 0), 8013054c4ffSLorenzo Bianconi }, 8023054c4ffSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 8033054c4ffSLorenzo Bianconi .addr = 0x09, 8043054c4ffSLorenzo Bianconi .mask = GENMASK(7, 4), 8053054c4ffSLorenzo Bianconi }, 8063054c4ffSLorenzo Bianconi }, 8079db02d32SLorenzo Bianconi .lir = { 8089db02d32SLorenzo Bianconi .addr = 0x56, 8099db02d32SLorenzo Bianconi .mask = BIT(0), 8109db02d32SLorenzo Bianconi }, 81122ea5651SLorenzo Bianconi .clear_on_read = { 81222ea5651SLorenzo Bianconi .addr = 0x56, 81322ea5651SLorenzo Bianconi .mask = BIT(6), 81422ea5651SLorenzo Bianconi }, 8153054c4ffSLorenzo Bianconi .fifo_ops = { 8163b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 8173054c4ffSLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 8183054c4ffSLorenzo Bianconi .fifo_th = { 8193054c4ffSLorenzo Bianconi .addr = 0x07, 8203054c4ffSLorenzo Bianconi .mask = GENMASK(8, 0), 8213054c4ffSLorenzo Bianconi }, 8223054c4ffSLorenzo Bianconi .fifo_diff = { 8233054c4ffSLorenzo Bianconi .addr = 0x3a, 82470575abeSmario tesi .mask = GENMASK(9, 0), 8253054c4ffSLorenzo Bianconi }, 8263054c4ffSLorenzo Bianconi .th_wl = 1, 8273054c4ffSLorenzo Bianconi }, 8283054c4ffSLorenzo Bianconi .ts_settings = { 8293054c4ffSLorenzo Bianconi .timer_en = { 8303054c4ffSLorenzo Bianconi .addr = 0x19, 8313054c4ffSLorenzo Bianconi .mask = BIT(5), 8323054c4ffSLorenzo Bianconi }, 8333054c4ffSLorenzo Bianconi .decimator = { 8343054c4ffSLorenzo Bianconi .addr = 0x0a, 8353054c4ffSLorenzo Bianconi .mask = GENMASK(7, 6), 8363054c4ffSLorenzo Bianconi }, 8373054c4ffSLorenzo Bianconi }, 838b5969abfSSean Nyekjaer .event_settings = { 839b5969abfSSean Nyekjaer .enable_reg = { 840b5969abfSSean Nyekjaer .addr = 0x58, 841b5969abfSSean Nyekjaer .mask = BIT(7), 842b5969abfSSean Nyekjaer }, 843b5969abfSSean Nyekjaer .wakeup_reg = { 844b5969abfSSean Nyekjaer .addr = 0x5B, 845b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 846b5969abfSSean Nyekjaer }, 8471aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 8481aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 8491aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 8501aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 8511aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 852b5969abfSSean Nyekjaer }, 8533054c4ffSLorenzo Bianconi }, 85443901008SLorenzo Bianconi { 85543901008SLorenzo Bianconi .wai = 0x6b, 8565022c5a4SMartin Kepplinger .int1_addr = 0x0d, 8575022c5a4SMartin Kepplinger .int2_addr = 0x0e, 858b5969abfSSean Nyekjaer .int1_func_addr = 0x5e, 859b5969abfSSean Nyekjaer .int2_func_addr = 0x5f, 860b5969abfSSean Nyekjaer .int_func_mask = BIT(5), 8615022c5a4SMartin Kepplinger .reset_addr = 0x12, 86243901008SLorenzo Bianconi .max_fifo_size = 512, 86343901008SLorenzo Bianconi .id = { 86481956a93SLorenzo Bianconi { 86581956a93SLorenzo Bianconi .hw_id = ST_LSM6DSR_ID, 86681956a93SLorenzo Bianconi .name = ST_LSM6DSR_DEV_NAME, 867db947a79SLorenzo Bianconi }, { 868db947a79SLorenzo Bianconi .hw_id = ST_ISM330DHCX_ID, 869db947a79SLorenzo Bianconi .name = ST_ISM330DHCX_DEV_NAME, 87081956a93SLorenzo Bianconi }, 87143901008SLorenzo Bianconi }, 872f48bc49bSLorenzo Bianconi .channels = { 873f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 874f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_acc_channels, 875f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), 876f48bc49bSLorenzo Bianconi }, 877f48bc49bSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 878f48bc49bSLorenzo Bianconi .chan = st_lsm6dsx_gyro_channels, 879f48bc49bSLorenzo Bianconi .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels), 880f48bc49bSLorenzo Bianconi }, 881f48bc49bSLorenzo Bianconi }, 88240dd7343SLorenzo Bianconi .odr_table = { 88340dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 88440dd7343SLorenzo Bianconi .reg = { 88540dd7343SLorenzo Bianconi .addr = 0x10, 88640dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 88740dd7343SLorenzo Bianconi }, 88840dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 88940dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 89040dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 89140dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 89240dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 89340dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 89440dd7343SLorenzo Bianconi }, 89540dd7343SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 89640dd7343SLorenzo Bianconi .reg = { 89740dd7343SLorenzo Bianconi .addr = 0x11, 89840dd7343SLorenzo Bianconi .mask = GENMASK(7, 4), 89940dd7343SLorenzo Bianconi }, 90040dd7343SLorenzo Bianconi .odr_avl[0] = { 13, 0x01 }, 90140dd7343SLorenzo Bianconi .odr_avl[1] = { 26, 0x02 }, 90240dd7343SLorenzo Bianconi .odr_avl[2] = { 52, 0x03 }, 90340dd7343SLorenzo Bianconi .odr_avl[3] = { 104, 0x04 }, 90440dd7343SLorenzo Bianconi .odr_avl[4] = { 208, 0x05 }, 90540dd7343SLorenzo Bianconi .odr_avl[5] = { 416, 0x06 }, 90640dd7343SLorenzo Bianconi }, 90740dd7343SLorenzo Bianconi }, 908640aca3fSLorenzo Bianconi .fs_table = { 909640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 910640aca3fSLorenzo Bianconi .reg = { 911640aca3fSLorenzo Bianconi .addr = 0x10, 912640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 913640aca3fSLorenzo Bianconi }, 914640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, 915640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, 916640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, 917640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, 91885ae3aeeSLorenzo Bianconi .fs_len = 4, 919640aca3fSLorenzo Bianconi }, 920640aca3fSLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 921640aca3fSLorenzo Bianconi .reg = { 922640aca3fSLorenzo Bianconi .addr = 0x11, 923640aca3fSLorenzo Bianconi .mask = GENMASK(3, 2), 924640aca3fSLorenzo Bianconi }, 925640aca3fSLorenzo Bianconi .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, 926640aca3fSLorenzo Bianconi .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, 927640aca3fSLorenzo Bianconi .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, 928640aca3fSLorenzo Bianconi .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, 92985ae3aeeSLorenzo Bianconi .fs_len = 4, 930640aca3fSLorenzo Bianconi }, 931640aca3fSLorenzo Bianconi }, 93243901008SLorenzo Bianconi .batch = { 93343901008SLorenzo Bianconi [ST_LSM6DSX_ID_ACC] = { 93443901008SLorenzo Bianconi .addr = 0x09, 93543901008SLorenzo Bianconi .mask = GENMASK(3, 0), 93643901008SLorenzo Bianconi }, 93743901008SLorenzo Bianconi [ST_LSM6DSX_ID_GYRO] = { 93843901008SLorenzo Bianconi .addr = 0x09, 93943901008SLorenzo Bianconi .mask = GENMASK(7, 4), 94043901008SLorenzo Bianconi }, 94143901008SLorenzo Bianconi }, 9429db02d32SLorenzo Bianconi .lir = { 9439db02d32SLorenzo Bianconi .addr = 0x56, 9449db02d32SLorenzo Bianconi .mask = BIT(0), 9459db02d32SLorenzo Bianconi }, 94622ea5651SLorenzo Bianconi .clear_on_read = { 94722ea5651SLorenzo Bianconi .addr = 0x56, 94822ea5651SLorenzo Bianconi .mask = BIT(6), 94922ea5651SLorenzo Bianconi }, 95043901008SLorenzo Bianconi .fifo_ops = { 9513b72950dSLorenzo Bianconi .update_fifo = st_lsm6dsx_update_fifo, 95243901008SLorenzo Bianconi .read_fifo = st_lsm6dsx_read_tagged_fifo, 95343901008SLorenzo Bianconi .fifo_th = { 95443901008SLorenzo Bianconi .addr = 0x07, 95543901008SLorenzo Bianconi .mask = GENMASK(8, 0), 95643901008SLorenzo Bianconi }, 95743901008SLorenzo Bianconi .fifo_diff = { 95843901008SLorenzo Bianconi .addr = 0x3a, 95970575abeSmario tesi .mask = GENMASK(9, 0), 96043901008SLorenzo Bianconi }, 96143901008SLorenzo Bianconi .th_wl = 1, 96243901008SLorenzo Bianconi }, 96343901008SLorenzo Bianconi .ts_settings = { 96443901008SLorenzo Bianconi .timer_en = { 96543901008SLorenzo Bianconi .addr = 0x19, 96643901008SLorenzo Bianconi .mask = BIT(5), 96743901008SLorenzo Bianconi }, 96843901008SLorenzo Bianconi .decimator = { 96943901008SLorenzo Bianconi .addr = 0x0a, 97043901008SLorenzo Bianconi .mask = GENMASK(7, 6), 97143901008SLorenzo Bianconi }, 97243901008SLorenzo Bianconi }, 97343901008SLorenzo Bianconi .shub_settings = { 97443901008SLorenzo Bianconi .page_mux = { 97543901008SLorenzo Bianconi .addr = 0x01, 97643901008SLorenzo Bianconi .mask = BIT(6), 97743901008SLorenzo Bianconi }, 97843901008SLorenzo Bianconi .master_en = { 97943901008SLorenzo Bianconi .addr = 0x14, 98043901008SLorenzo Bianconi .mask = BIT(2), 98143901008SLorenzo Bianconi }, 98243901008SLorenzo Bianconi .pullup_en = { 98343901008SLorenzo Bianconi .addr = 0x14, 98443901008SLorenzo Bianconi .mask = BIT(3), 98543901008SLorenzo Bianconi }, 98643901008SLorenzo Bianconi .aux_sens = { 98743901008SLorenzo Bianconi .addr = 0x14, 98843901008SLorenzo Bianconi .mask = GENMASK(1, 0), 98943901008SLorenzo Bianconi }, 99043901008SLorenzo Bianconi .wr_once = { 99143901008SLorenzo Bianconi .addr = 0x14, 99243901008SLorenzo Bianconi .mask = BIT(6), 99343901008SLorenzo Bianconi }, 99443901008SLorenzo Bianconi .shub_out = 0x02, 99543901008SLorenzo Bianconi .slv0_addr = 0x15, 99643901008SLorenzo Bianconi .dw_slv0_addr = 0x21, 99743901008SLorenzo Bianconi .batch_en = BIT(3), 998b5969abfSSean Nyekjaer }, 999b5969abfSSean Nyekjaer .event_settings = { 1000b5969abfSSean Nyekjaer .enable_reg = { 1001b5969abfSSean Nyekjaer .addr = 0x58, 1002b5969abfSSean Nyekjaer .mask = BIT(7), 1003b5969abfSSean Nyekjaer }, 1004b5969abfSSean Nyekjaer .wakeup_reg = { 1005b5969abfSSean Nyekjaer .addr = 0x5B, 1006b5969abfSSean Nyekjaer .mask = GENMASK(5, 0), 1007b5969abfSSean Nyekjaer }, 10081aabad1fSSean Nyekjaer .wakeup_src_reg = 0x1b, 10091aabad1fSSean Nyekjaer .wakeup_src_status_mask = BIT(3), 10101aabad1fSSean Nyekjaer .wakeup_src_z_mask = BIT(0), 10111aabad1fSSean Nyekjaer .wakeup_src_y_mask = BIT(1), 10121aabad1fSSean Nyekjaer .wakeup_src_x_mask = BIT(2), 101343901008SLorenzo Bianconi } 101443901008SLorenzo Bianconi }, 1015290a6ce1SLorenzo Bianconi }; 1016290a6ce1SLorenzo Bianconi 1017c91c1c84SLorenzo Bianconi int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable) 1018c91c1c84SLorenzo Bianconi { 1019c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 1020c91c1c84SLorenzo Bianconi unsigned int data; 1021c91c1c84SLorenzo Bianconi int err; 1022c91c1c84SLorenzo Bianconi 1023c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 1024c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask); 1025c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr, 1026c91c1c84SLorenzo Bianconi hub_settings->page_mux.mask, data); 1027c91c1c84SLorenzo Bianconi usleep_range(100, 150); 1028c91c1c84SLorenzo Bianconi 1029c91c1c84SLorenzo Bianconi return err; 1030c91c1c84SLorenzo Bianconi } 1031c91c1c84SLorenzo Bianconi 103281956a93SLorenzo Bianconi static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id, 103381956a93SLorenzo Bianconi const char **name) 1034290a6ce1SLorenzo Bianconi { 103551a8b707SLorenzo Bianconi int err, i, j, data; 1036290a6ce1SLorenzo Bianconi 1037290a6ce1SLorenzo Bianconi for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) { 1038d068e4a0SLorenzo Bianconi for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) { 103981956a93SLorenzo Bianconi if (id == st_lsm6dsx_sensor_settings[i].id[j].hw_id) 1040d068e4a0SLorenzo Bianconi break; 1041d068e4a0SLorenzo Bianconi } 1042d068e4a0SLorenzo Bianconi if (j < ST_LSM6DSX_MAX_ID) 1043290a6ce1SLorenzo Bianconi break; 1044290a6ce1SLorenzo Bianconi } 1045290a6ce1SLorenzo Bianconi 1046290a6ce1SLorenzo Bianconi if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) { 1047290a6ce1SLorenzo Bianconi dev_err(hw->dev, "unsupported hw id [%02x]\n", id); 1048290a6ce1SLorenzo Bianconi return -ENODEV; 1049290a6ce1SLorenzo Bianconi } 1050290a6ce1SLorenzo Bianconi 105151a8b707SLorenzo Bianconi err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data); 1052290a6ce1SLorenzo Bianconi if (err < 0) { 1053290a6ce1SLorenzo Bianconi dev_err(hw->dev, "failed to read whoami register\n"); 1054290a6ce1SLorenzo Bianconi return err; 1055290a6ce1SLorenzo Bianconi } 1056290a6ce1SLorenzo Bianconi 1057290a6ce1SLorenzo Bianconi if (data != st_lsm6dsx_sensor_settings[i].wai) { 1058290a6ce1SLorenzo Bianconi dev_err(hw->dev, "unsupported whoami [%02x]\n", data); 1059290a6ce1SLorenzo Bianconi return -ENODEV; 1060290a6ce1SLorenzo Bianconi } 1061290a6ce1SLorenzo Bianconi 106281956a93SLorenzo Bianconi *name = st_lsm6dsx_sensor_settings[i].id[j].name; 1063290a6ce1SLorenzo Bianconi hw->settings = &st_lsm6dsx_sensor_settings[i]; 1064290a6ce1SLorenzo Bianconi 1065290a6ce1SLorenzo Bianconi return 0; 1066290a6ce1SLorenzo Bianconi } 1067290a6ce1SLorenzo Bianconi 1068290a6ce1SLorenzo Bianconi static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor, 1069290a6ce1SLorenzo Bianconi u32 gain) 1070290a6ce1SLorenzo Bianconi { 1071640aca3fSLorenzo Bianconi const struct st_lsm6dsx_fs_table_entry *fs_table; 1072739aff87SLorenzo Bianconi unsigned int data; 1073290a6ce1SLorenzo Bianconi int i, err; 1074290a6ce1SLorenzo Bianconi 1075640aca3fSLorenzo Bianconi fs_table = &sensor->hw->settings->fs_table[sensor->id]; 107685ae3aeeSLorenzo Bianconi for (i = 0; i < fs_table->fs_len; i++) { 1077640aca3fSLorenzo Bianconi if (fs_table->fs_avl[i].gain == gain) 1078290a6ce1SLorenzo Bianconi break; 107985ae3aeeSLorenzo Bianconi } 1080290a6ce1SLorenzo Bianconi 108185ae3aeeSLorenzo Bianconi if (i == fs_table->fs_len) 1082290a6ce1SLorenzo Bianconi return -EINVAL; 1083290a6ce1SLorenzo Bianconi 1084640aca3fSLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val, 1085640aca3fSLorenzo Bianconi fs_table->reg.mask); 1086640aca3fSLorenzo Bianconi err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr, 1087640aca3fSLorenzo Bianconi fs_table->reg.mask, data); 1088290a6ce1SLorenzo Bianconi if (err < 0) 1089290a6ce1SLorenzo Bianconi return err; 1090290a6ce1SLorenzo Bianconi 1091290a6ce1SLorenzo Bianconi sensor->gain = gain; 1092290a6ce1SLorenzo Bianconi 1093290a6ce1SLorenzo Bianconi return 0; 1094290a6ce1SLorenzo Bianconi } 1095290a6ce1SLorenzo Bianconi 109654a6d0c6SLorenzo Bianconi int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val) 1097290a6ce1SLorenzo Bianconi { 109840dd7343SLorenzo Bianconi const struct st_lsm6dsx_odr_table_entry *odr_table; 10992ccc1503SLorenzo Bianconi int i; 1100290a6ce1SLorenzo Bianconi 110140dd7343SLorenzo Bianconi odr_table = &sensor->hw->settings->odr_table[sensor->id]; 1102290a6ce1SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) 11036ffb55e5SLorenzo Bianconi /* 11046ffb55e5SLorenzo Bianconi * ext devices can run at different odr respect to 11056ffb55e5SLorenzo Bianconi * accel sensor 11066ffb55e5SLorenzo Bianconi */ 110740dd7343SLorenzo Bianconi if (odr_table->odr_avl[i].hz >= odr) 1108290a6ce1SLorenzo Bianconi break; 1109290a6ce1SLorenzo Bianconi 1110290a6ce1SLorenzo Bianconi if (i == ST_LSM6DSX_ODR_LIST_SIZE) 1111290a6ce1SLorenzo Bianconi return -EINVAL; 1112290a6ce1SLorenzo Bianconi 111340dd7343SLorenzo Bianconi *val = odr_table->odr_avl[i].val; 1114290a6ce1SLorenzo Bianconi 1115290a6ce1SLorenzo Bianconi return 0; 1116290a6ce1SLorenzo Bianconi } 1117290a6ce1SLorenzo Bianconi 11186ffb55e5SLorenzo Bianconi static u16 st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u16 odr, 11196ffb55e5SLorenzo Bianconi enum st_lsm6dsx_sensor_id id) 11202ccc1503SLorenzo Bianconi { 11216ffb55e5SLorenzo Bianconi struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]); 11226ffb55e5SLorenzo Bianconi 11236ffb55e5SLorenzo Bianconi if (odr > 0) { 11246ffb55e5SLorenzo Bianconi if (hw->enable_mask & BIT(id)) 11256ffb55e5SLorenzo Bianconi return max_t(u16, ref->odr, odr); 11266ffb55e5SLorenzo Bianconi else 11276ffb55e5SLorenzo Bianconi return odr; 11286ffb55e5SLorenzo Bianconi } else { 11296ffb55e5SLorenzo Bianconi return (hw->enable_mask & BIT(id)) ? ref->odr : 0; 11306ffb55e5SLorenzo Bianconi } 11316ffb55e5SLorenzo Bianconi } 11326ffb55e5SLorenzo Bianconi 11336ffb55e5SLorenzo Bianconi static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 req_odr) 11346ffb55e5SLorenzo Bianconi { 11356ffb55e5SLorenzo Bianconi struct st_lsm6dsx_sensor *ref_sensor = sensor; 113651a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 113751a8b707SLorenzo Bianconi const struct st_lsm6dsx_reg *reg; 1138739aff87SLorenzo Bianconi unsigned int data; 11396ffb55e5SLorenzo Bianconi u8 val = 0; 11402ccc1503SLorenzo Bianconi int err; 11412ccc1503SLorenzo Bianconi 11426ffb55e5SLorenzo Bianconi switch (sensor->id) { 11436ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT0: 11446ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT1: 11456ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_EXT2: 11466ffb55e5SLorenzo Bianconi case ST_LSM6DSX_ID_ACC: { 11476ffb55e5SLorenzo Bianconi u16 odr; 11486ffb55e5SLorenzo Bianconi int i; 11496ffb55e5SLorenzo Bianconi 11506ffb55e5SLorenzo Bianconi /* 11516ffb55e5SLorenzo Bianconi * i2c embedded controller relies on the accelerometer sensor as 11526ffb55e5SLorenzo Bianconi * bus read/write trigger so we need to enable accel device 11536ffb55e5SLorenzo Bianconi * at odr = max(accel_odr, ext_odr) in order to properly 11546ffb55e5SLorenzo Bianconi * communicate with i2c slave devices 11556ffb55e5SLorenzo Bianconi */ 11566ffb55e5SLorenzo Bianconi ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]); 11576ffb55e5SLorenzo Bianconi for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) { 11586ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i] || i == sensor->id) 11596ffb55e5SLorenzo Bianconi continue; 11606ffb55e5SLorenzo Bianconi 11616ffb55e5SLorenzo Bianconi odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i); 11626ffb55e5SLorenzo Bianconi if (odr != req_odr) 11636ffb55e5SLorenzo Bianconi /* device already configured */ 11646ffb55e5SLorenzo Bianconi return 0; 11656ffb55e5SLorenzo Bianconi } 11666ffb55e5SLorenzo Bianconi break; 11676ffb55e5SLorenzo Bianconi } 11686ffb55e5SLorenzo Bianconi default: 11696ffb55e5SLorenzo Bianconi break; 11706ffb55e5SLorenzo Bianconi } 11716ffb55e5SLorenzo Bianconi 11726ffb55e5SLorenzo Bianconi if (req_odr > 0) { 11736ffb55e5SLorenzo Bianconi err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val); 11742ccc1503SLorenzo Bianconi if (err < 0) 11752ccc1503SLorenzo Bianconi return err; 11766ffb55e5SLorenzo Bianconi } 11772ccc1503SLorenzo Bianconi 117840dd7343SLorenzo Bianconi reg = &hw->settings->odr_table[ref_sensor->id].reg; 1179739aff87SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask); 1180739aff87SLorenzo Bianconi return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data); 11812ccc1503SLorenzo Bianconi } 11822ccc1503SLorenzo Bianconi 118317750443SLorenzo Bianconi int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor, 118417750443SLorenzo Bianconi bool enable) 1185290a6ce1SLorenzo Bianconi { 118651a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 118717750443SLorenzo Bianconi u16 odr = enable ? sensor->odr : 0; 1188290a6ce1SLorenzo Bianconi int err; 1189290a6ce1SLorenzo Bianconi 119017750443SLorenzo Bianconi err = st_lsm6dsx_set_odr(sensor, odr); 1191290a6ce1SLorenzo Bianconi if (err < 0) 1192290a6ce1SLorenzo Bianconi return err; 1193290a6ce1SLorenzo Bianconi 119417750443SLorenzo Bianconi if (enable) 119517750443SLorenzo Bianconi hw->enable_mask |= BIT(sensor->id); 119617750443SLorenzo Bianconi else 119717750443SLorenzo Bianconi hw->enable_mask &= ~BIT(sensor->id); 1198290a6ce1SLorenzo Bianconi 1199290a6ce1SLorenzo Bianconi return 0; 1200290a6ce1SLorenzo Bianconi } 1201290a6ce1SLorenzo Bianconi 1202290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor, 1203290a6ce1SLorenzo Bianconi u8 addr, int *val) 1204290a6ce1SLorenzo Bianconi { 120551a8b707SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1206290a6ce1SLorenzo Bianconi int err, delay; 1207290a6ce1SLorenzo Bianconi __le16 data; 1208290a6ce1SLorenzo Bianconi 120917750443SLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, true); 1210290a6ce1SLorenzo Bianconi if (err < 0) 1211290a6ce1SLorenzo Bianconi return err; 1212290a6ce1SLorenzo Bianconi 1213290a6ce1SLorenzo Bianconi delay = 1000000 / sensor->odr; 1214290a6ce1SLorenzo Bianconi usleep_range(delay, 2 * delay); 1215290a6ce1SLorenzo Bianconi 1216739aff87SLorenzo Bianconi err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data)); 1217290a6ce1SLorenzo Bianconi if (err < 0) 1218290a6ce1SLorenzo Bianconi return err; 1219290a6ce1SLorenzo Bianconi 1220b5969abfSSean Nyekjaer if (!hw->enable_event) 122117750443SLorenzo Bianconi st_lsm6dsx_sensor_set_enable(sensor, false); 1222290a6ce1SLorenzo Bianconi 12237b9ebe42SLorenzo Bianconi *val = (s16)le16_to_cpu(data); 1224290a6ce1SLorenzo Bianconi 1225290a6ce1SLorenzo Bianconi return IIO_VAL_INT; 1226290a6ce1SLorenzo Bianconi } 1227290a6ce1SLorenzo Bianconi 1228290a6ce1SLorenzo Bianconi static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev, 1229290a6ce1SLorenzo Bianconi struct iio_chan_spec const *ch, 1230290a6ce1SLorenzo Bianconi int *val, int *val2, long mask) 1231290a6ce1SLorenzo Bianconi { 1232290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1233290a6ce1SLorenzo Bianconi int ret; 1234290a6ce1SLorenzo Bianconi 1235290a6ce1SLorenzo Bianconi switch (mask) { 1236290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_RAW: 1237290a6ce1SLorenzo Bianconi ret = iio_device_claim_direct_mode(iio_dev); 1238290a6ce1SLorenzo Bianconi if (ret) 1239290a6ce1SLorenzo Bianconi break; 1240290a6ce1SLorenzo Bianconi 1241290a6ce1SLorenzo Bianconi ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val); 1242290a6ce1SLorenzo Bianconi iio_device_release_direct_mode(iio_dev); 1243290a6ce1SLorenzo Bianconi break; 1244290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SAMP_FREQ: 1245290a6ce1SLorenzo Bianconi *val = sensor->odr; 1246290a6ce1SLorenzo Bianconi ret = IIO_VAL_INT; 1247290a6ce1SLorenzo Bianconi break; 1248290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SCALE: 1249290a6ce1SLorenzo Bianconi *val = 0; 1250290a6ce1SLorenzo Bianconi *val2 = sensor->gain; 1251290a6ce1SLorenzo Bianconi ret = IIO_VAL_INT_PLUS_MICRO; 1252290a6ce1SLorenzo Bianconi break; 1253290a6ce1SLorenzo Bianconi default: 1254290a6ce1SLorenzo Bianconi ret = -EINVAL; 1255290a6ce1SLorenzo Bianconi break; 1256290a6ce1SLorenzo Bianconi } 1257290a6ce1SLorenzo Bianconi 1258290a6ce1SLorenzo Bianconi return ret; 1259290a6ce1SLorenzo Bianconi } 1260290a6ce1SLorenzo Bianconi 1261290a6ce1SLorenzo Bianconi static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev, 1262290a6ce1SLorenzo Bianconi struct iio_chan_spec const *chan, 1263290a6ce1SLorenzo Bianconi int val, int val2, long mask) 1264290a6ce1SLorenzo Bianconi { 1265290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1266290a6ce1SLorenzo Bianconi int err; 1267290a6ce1SLorenzo Bianconi 1268290a6ce1SLorenzo Bianconi err = iio_device_claim_direct_mode(iio_dev); 1269290a6ce1SLorenzo Bianconi if (err) 1270290a6ce1SLorenzo Bianconi return err; 1271290a6ce1SLorenzo Bianconi 1272290a6ce1SLorenzo Bianconi switch (mask) { 1273290a6ce1SLorenzo Bianconi case IIO_CHAN_INFO_SCALE: 1274290a6ce1SLorenzo Bianconi err = st_lsm6dsx_set_full_scale(sensor, val2); 1275290a6ce1SLorenzo Bianconi break; 12762ccc1503SLorenzo Bianconi case IIO_CHAN_INFO_SAMP_FREQ: { 12772ccc1503SLorenzo Bianconi u8 data; 12782ccc1503SLorenzo Bianconi 12792ccc1503SLorenzo Bianconi err = st_lsm6dsx_check_odr(sensor, val, &data); 12805e3c3e33SLorenzo Bianconi if (!err) 12815e3c3e33SLorenzo Bianconi sensor->odr = val; 1282290a6ce1SLorenzo Bianconi break; 12832ccc1503SLorenzo Bianconi } 1284290a6ce1SLorenzo Bianconi default: 1285290a6ce1SLorenzo Bianconi err = -EINVAL; 1286290a6ce1SLorenzo Bianconi break; 1287290a6ce1SLorenzo Bianconi } 1288290a6ce1SLorenzo Bianconi 1289290a6ce1SLorenzo Bianconi iio_device_release_direct_mode(iio_dev); 1290290a6ce1SLorenzo Bianconi 1291290a6ce1SLorenzo Bianconi return err; 1292290a6ce1SLorenzo Bianconi } 1293290a6ce1SLorenzo Bianconi 1294b5969abfSSean Nyekjaer static int st_lsm6dsx_event_setup(struct st_lsm6dsx_hw *hw, int state) 1295b5969abfSSean Nyekjaer { 1296b5969abfSSean Nyekjaer int err; 1297b5969abfSSean Nyekjaer u8 enable = 0; 1298b5969abfSSean Nyekjaer 1299b5969abfSSean Nyekjaer if (!hw->settings->int1_func_addr) 1300b5969abfSSean Nyekjaer return -ENOTSUPP; 1301b5969abfSSean Nyekjaer 1302b5969abfSSean Nyekjaer enable = state ? hw->settings->event_settings.enable_reg.mask : 0; 1303b5969abfSSean Nyekjaer 1304b5969abfSSean Nyekjaer err = regmap_update_bits(hw->regmap, 1305b5969abfSSean Nyekjaer hw->settings->event_settings.enable_reg.addr, 1306b5969abfSSean Nyekjaer hw->settings->event_settings.enable_reg.mask, 1307b5969abfSSean Nyekjaer enable); 1308b5969abfSSean Nyekjaer if (err < 0) 1309b5969abfSSean Nyekjaer return err; 1310b5969abfSSean Nyekjaer 1311b5969abfSSean Nyekjaer enable = state ? hw->irq_routing.mask : 0; 1312b5969abfSSean Nyekjaer 1313b5969abfSSean Nyekjaer /* Enable wakeup interrupt */ 1314b5969abfSSean Nyekjaer return regmap_update_bits(hw->regmap, hw->irq_routing.addr, 1315b5969abfSSean Nyekjaer hw->irq_routing.mask, 1316b5969abfSSean Nyekjaer enable); 1317b5969abfSSean Nyekjaer } 1318b5969abfSSean Nyekjaer 1319b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event(struct iio_dev *iio_dev, 1320b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1321b5969abfSSean Nyekjaer enum iio_event_type type, 1322b5969abfSSean Nyekjaer enum iio_event_direction dir, 1323b5969abfSSean Nyekjaer enum iio_event_info info, 1324b5969abfSSean Nyekjaer int *val, int *val2) 1325b5969abfSSean Nyekjaer { 1326b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1327b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 1328b5969abfSSean Nyekjaer 1329b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1330b5969abfSSean Nyekjaer return -EINVAL; 1331b5969abfSSean Nyekjaer 1332b5969abfSSean Nyekjaer *val2 = 0; 1333b5969abfSSean Nyekjaer *val = hw->event_threshold; 1334b5969abfSSean Nyekjaer 1335b5969abfSSean Nyekjaer return IIO_VAL_INT; 1336b5969abfSSean Nyekjaer } 1337b5969abfSSean Nyekjaer 1338b5969abfSSean Nyekjaer static int st_lsm6dsx_write_event(struct iio_dev *iio_dev, 1339b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1340b5969abfSSean Nyekjaer enum iio_event_type type, 1341b5969abfSSean Nyekjaer enum iio_event_direction dir, 1342b5969abfSSean Nyekjaer enum iio_event_info info, 1343b5969abfSSean Nyekjaer int val, int val2) 1344b5969abfSSean Nyekjaer { 1345b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1346b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 1347b5969abfSSean Nyekjaer int err; 1348b5969abfSSean Nyekjaer 1349b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1350b5969abfSSean Nyekjaer return -EINVAL; 1351b5969abfSSean Nyekjaer 1352b5969abfSSean Nyekjaer if (val < 0 || val > 31) 1353b5969abfSSean Nyekjaer return -EINVAL; 1354b5969abfSSean Nyekjaer 1355b5969abfSSean Nyekjaer err = regmap_update_bits(hw->regmap, 1356b5969abfSSean Nyekjaer hw->settings->event_settings.wakeup_reg.addr, 1357b5969abfSSean Nyekjaer hw->settings->event_settings.wakeup_reg.mask, 1358b5969abfSSean Nyekjaer val); 1359b5969abfSSean Nyekjaer if (err) 1360b5969abfSSean Nyekjaer return -EINVAL; 1361b5969abfSSean Nyekjaer 1362b5969abfSSean Nyekjaer hw->event_threshold = val; 1363b5969abfSSean Nyekjaer 1364b5969abfSSean Nyekjaer return 0; 1365b5969abfSSean Nyekjaer } 1366b5969abfSSean Nyekjaer 1367b5969abfSSean Nyekjaer static int st_lsm6dsx_read_event_config(struct iio_dev *iio_dev, 1368b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1369b5969abfSSean Nyekjaer enum iio_event_type type, 1370b5969abfSSean Nyekjaer enum iio_event_direction dir) 1371b5969abfSSean Nyekjaer { 1372b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1373b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 1374b5969abfSSean Nyekjaer 1375b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1376b5969abfSSean Nyekjaer return -EINVAL; 1377b5969abfSSean Nyekjaer 13781aabad1fSSean Nyekjaer return !!(hw->enable_event & BIT(chan->channel2)); 1379b5969abfSSean Nyekjaer } 1380b5969abfSSean Nyekjaer 1381b5969abfSSean Nyekjaer static int st_lsm6dsx_write_event_config(struct iio_dev *iio_dev, 1382b5969abfSSean Nyekjaer const struct iio_chan_spec *chan, 1383b5969abfSSean Nyekjaer enum iio_event_type type, 1384b5969abfSSean Nyekjaer enum iio_event_direction dir, 1385b5969abfSSean Nyekjaer int state) 1386b5969abfSSean Nyekjaer { 1387b5969abfSSean Nyekjaer struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1388b5969abfSSean Nyekjaer struct st_lsm6dsx_hw *hw = sensor->hw; 13891aabad1fSSean Nyekjaer u8 enable_event; 1390b5969abfSSean Nyekjaer int err = 0; 1391b5969abfSSean Nyekjaer 1392b5969abfSSean Nyekjaer if (type != IIO_EV_TYPE_THRESH) 1393b5969abfSSean Nyekjaer return -EINVAL; 1394b5969abfSSean Nyekjaer 13951aabad1fSSean Nyekjaer if (state) { 13961aabad1fSSean Nyekjaer enable_event = hw->enable_event | BIT(chan->channel2); 13971aabad1fSSean Nyekjaer 1398b5969abfSSean Nyekjaer /* do not enable events if they are already enabled */ 13991aabad1fSSean Nyekjaer if (hw->enable_event) 14001aabad1fSSean Nyekjaer goto out; 14011aabad1fSSean Nyekjaer } else { 14021aabad1fSSean Nyekjaer enable_event = hw->enable_event & ~BIT(chan->channel2); 14031aabad1fSSean Nyekjaer 14041aabad1fSSean Nyekjaer /* only turn off sensor if no events is enabled */ 14051aabad1fSSean Nyekjaer if (enable_event) 14061aabad1fSSean Nyekjaer goto out; 14071aabad1fSSean Nyekjaer } 14081aabad1fSSean Nyekjaer 14091aabad1fSSean Nyekjaer /* stop here if no changes have been made */ 14101aabad1fSSean Nyekjaer if (hw->enable_event == enable_event) 1411b5969abfSSean Nyekjaer return 0; 1412b5969abfSSean Nyekjaer 1413b5969abfSSean Nyekjaer err = st_lsm6dsx_event_setup(hw, state); 1414b5969abfSSean Nyekjaer if (err < 0) 1415b5969abfSSean Nyekjaer return err; 1416b5969abfSSean Nyekjaer 1417b5969abfSSean Nyekjaer err = st_lsm6dsx_sensor_set_enable(sensor, state); 1418b5969abfSSean Nyekjaer if (err < 0) 1419b5969abfSSean Nyekjaer return err; 1420b5969abfSSean Nyekjaer 14211aabad1fSSean Nyekjaer out: 14221aabad1fSSean Nyekjaer hw->enable_event = enable_event; 1423b5969abfSSean Nyekjaer 1424b5969abfSSean Nyekjaer return 0; 1425b5969abfSSean Nyekjaer } 1426b5969abfSSean Nyekjaer 1427d40464f3SLorenzo Bianconi int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val) 1428290a6ce1SLorenzo Bianconi { 1429290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 1430290a6ce1SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 14318f2a88a2SLorenzo Bianconi int err; 1432290a6ce1SLorenzo Bianconi 14338f2a88a2SLorenzo Bianconi if (val < 1 || val > hw->settings->max_fifo_size) 1434290a6ce1SLorenzo Bianconi return -EINVAL; 1435290a6ce1SLorenzo Bianconi 1436335eaedcSLorenzo Bianconi mutex_lock(&hw->conf_lock); 1437335eaedcSLorenzo Bianconi 1438290a6ce1SLorenzo Bianconi err = st_lsm6dsx_update_watermark(sensor, val); 1439335eaedcSLorenzo Bianconi 1440335eaedcSLorenzo Bianconi mutex_unlock(&hw->conf_lock); 1441335eaedcSLorenzo Bianconi 1442290a6ce1SLorenzo Bianconi if (err < 0) 1443290a6ce1SLorenzo Bianconi return err; 1444290a6ce1SLorenzo Bianconi 1445290a6ce1SLorenzo Bianconi sensor->watermark = val; 1446290a6ce1SLorenzo Bianconi 1447290a6ce1SLorenzo Bianconi return 0; 1448290a6ce1SLorenzo Bianconi } 1449290a6ce1SLorenzo Bianconi 1450290a6ce1SLorenzo Bianconi static ssize_t 1451290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev, 1452290a6ce1SLorenzo Bianconi struct device_attribute *attr, 1453290a6ce1SLorenzo Bianconi char *buf) 1454290a6ce1SLorenzo Bianconi { 1455290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); 1456290a6ce1SLorenzo Bianconi enum st_lsm6dsx_sensor_id id = sensor->id; 145740dd7343SLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1458290a6ce1SLorenzo Bianconi int i, len = 0; 1459290a6ce1SLorenzo Bianconi 1460290a6ce1SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) 1461290a6ce1SLorenzo Bianconi len += scnprintf(buf + len, PAGE_SIZE - len, "%d ", 146240dd7343SLorenzo Bianconi hw->settings->odr_table[id].odr_avl[i].hz); 1463290a6ce1SLorenzo Bianconi buf[len - 1] = '\n'; 1464290a6ce1SLorenzo Bianconi 1465290a6ce1SLorenzo Bianconi return len; 1466290a6ce1SLorenzo Bianconi } 1467290a6ce1SLorenzo Bianconi 1468290a6ce1SLorenzo Bianconi static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev, 1469290a6ce1SLorenzo Bianconi struct device_attribute *attr, 1470290a6ce1SLorenzo Bianconi char *buf) 1471290a6ce1SLorenzo Bianconi { 1472290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev)); 14730f7e1728SLorenzo Bianconi const struct st_lsm6dsx_fs_table_entry *fs_table; 1474640aca3fSLorenzo Bianconi struct st_lsm6dsx_hw *hw = sensor->hw; 1475290a6ce1SLorenzo Bianconi int i, len = 0; 1476290a6ce1SLorenzo Bianconi 147785ae3aeeSLorenzo Bianconi fs_table = &hw->settings->fs_table[sensor->id]; 147885ae3aeeSLorenzo Bianconi for (i = 0; i < fs_table->fs_len; i++) 1479290a6ce1SLorenzo Bianconi len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", 14800f7e1728SLorenzo Bianconi fs_table->fs_avl[i].gain); 1481290a6ce1SLorenzo Bianconi buf[len - 1] = '\n'; 1482290a6ce1SLorenzo Bianconi 1483290a6ce1SLorenzo Bianconi return len; 1484290a6ce1SLorenzo Bianconi } 1485290a6ce1SLorenzo Bianconi 1486290a6ce1SLorenzo Bianconi static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail); 1487290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_accel_scale_available, 0444, 1488290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_scale_avail, NULL, 0); 1489290a6ce1SLorenzo Bianconi static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444, 1490290a6ce1SLorenzo Bianconi st_lsm6dsx_sysfs_scale_avail, NULL, 0); 1491290a6ce1SLorenzo Bianconi 1492290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_acc_attributes[] = { 1493290a6ce1SLorenzo Bianconi &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 1494290a6ce1SLorenzo Bianconi &iio_dev_attr_in_accel_scale_available.dev_attr.attr, 1495290a6ce1SLorenzo Bianconi NULL, 1496290a6ce1SLorenzo Bianconi }; 1497290a6ce1SLorenzo Bianconi 1498290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_acc_attribute_group = { 1499290a6ce1SLorenzo Bianconi .attrs = st_lsm6dsx_acc_attributes, 1500290a6ce1SLorenzo Bianconi }; 1501290a6ce1SLorenzo Bianconi 1502290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_acc_info = { 1503290a6ce1SLorenzo Bianconi .attrs = &st_lsm6dsx_acc_attribute_group, 1504290a6ce1SLorenzo Bianconi .read_raw = st_lsm6dsx_read_raw, 1505290a6ce1SLorenzo Bianconi .write_raw = st_lsm6dsx_write_raw, 1506b5969abfSSean Nyekjaer .read_event_value = st_lsm6dsx_read_event, 1507b5969abfSSean Nyekjaer .write_event_value = st_lsm6dsx_write_event, 1508b5969abfSSean Nyekjaer .read_event_config = st_lsm6dsx_read_event_config, 1509b5969abfSSean Nyekjaer .write_event_config = st_lsm6dsx_write_event_config, 1510290a6ce1SLorenzo Bianconi .hwfifo_set_watermark = st_lsm6dsx_set_watermark, 1511290a6ce1SLorenzo Bianconi }; 1512290a6ce1SLorenzo Bianconi 1513290a6ce1SLorenzo Bianconi static struct attribute *st_lsm6dsx_gyro_attributes[] = { 1514290a6ce1SLorenzo Bianconi &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 1515290a6ce1SLorenzo Bianconi &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr, 1516290a6ce1SLorenzo Bianconi NULL, 1517290a6ce1SLorenzo Bianconi }; 1518290a6ce1SLorenzo Bianconi 1519290a6ce1SLorenzo Bianconi static const struct attribute_group st_lsm6dsx_gyro_attribute_group = { 1520290a6ce1SLorenzo Bianconi .attrs = st_lsm6dsx_gyro_attributes, 1521290a6ce1SLorenzo Bianconi }; 1522290a6ce1SLorenzo Bianconi 1523290a6ce1SLorenzo Bianconi static const struct iio_info st_lsm6dsx_gyro_info = { 1524290a6ce1SLorenzo Bianconi .attrs = &st_lsm6dsx_gyro_attribute_group, 1525290a6ce1SLorenzo Bianconi .read_raw = st_lsm6dsx_read_raw, 1526290a6ce1SLorenzo Bianconi .write_raw = st_lsm6dsx_write_raw, 1527290a6ce1SLorenzo Bianconi .hwfifo_set_watermark = st_lsm6dsx_set_watermark, 1528290a6ce1SLorenzo Bianconi }; 1529290a6ce1SLorenzo Bianconi 1530dba32904SLorenzo Bianconi static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) 1531dba32904SLorenzo Bianconi { 1532dba32904SLorenzo Bianconi struct device_node *np = hw->dev->of_node; 1533dba32904SLorenzo Bianconi 1534dba32904SLorenzo Bianconi if (!np) 1535dba32904SLorenzo Bianconi return -EINVAL; 1536dba32904SLorenzo Bianconi 1537bf235277SLorenzo Bianconi return of_property_read_u32(np, "st,drdy-int-pin", drdy_pin); 1538dba32904SLorenzo Bianconi } 1539dba32904SLorenzo Bianconi 1540dba32904SLorenzo Bianconi static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg) 1541dba32904SLorenzo Bianconi { 1542dba32904SLorenzo Bianconi int err = 0, drdy_pin; 1543dba32904SLorenzo Bianconi 1544dba32904SLorenzo Bianconi if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) { 1545dba32904SLorenzo Bianconi struct st_sensors_platform_data *pdata; 1546dba32904SLorenzo Bianconi struct device *dev = hw->dev; 1547dba32904SLorenzo Bianconi 1548dba32904SLorenzo Bianconi pdata = (struct st_sensors_platform_data *)dev->platform_data; 1549dba32904SLorenzo Bianconi drdy_pin = pdata ? pdata->drdy_int_pin : 1; 1550dba32904SLorenzo Bianconi } 1551dba32904SLorenzo Bianconi 1552dba32904SLorenzo Bianconi switch (drdy_pin) { 1553dba32904SLorenzo Bianconi case 1: 15545022c5a4SMartin Kepplinger *drdy_reg = hw->settings->int1_addr; 1555b5969abfSSean Nyekjaer hw->irq_routing.addr = hw->settings->int1_func_addr; 1556b5969abfSSean Nyekjaer hw->irq_routing.mask = hw->settings->int_func_mask; 1557dba32904SLorenzo Bianconi break; 1558dba32904SLorenzo Bianconi case 2: 15595022c5a4SMartin Kepplinger *drdy_reg = hw->settings->int2_addr; 1560b5969abfSSean Nyekjaer hw->irq_routing.addr = hw->settings->int2_func_addr; 1561b5969abfSSean Nyekjaer hw->irq_routing.mask = hw->settings->int_func_mask; 1562dba32904SLorenzo Bianconi break; 1563dba32904SLorenzo Bianconi default: 1564dba32904SLorenzo Bianconi dev_err(hw->dev, "unsupported data ready pin\n"); 1565dba32904SLorenzo Bianconi err = -EINVAL; 1566dba32904SLorenzo Bianconi break; 1567dba32904SLorenzo Bianconi } 1568dba32904SLorenzo Bianconi 1569dba32904SLorenzo Bianconi return err; 1570dba32904SLorenzo Bianconi } 1571dba32904SLorenzo Bianconi 1572c91c1c84SLorenzo Bianconi static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw) 1573c91c1c84SLorenzo Bianconi { 1574c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 1575c91c1c84SLorenzo Bianconi struct device_node *np = hw->dev->of_node; 1576c91c1c84SLorenzo Bianconi struct st_sensors_platform_data *pdata; 1577c91c1c84SLorenzo Bianconi unsigned int data; 1578c91c1c84SLorenzo Bianconi int err = 0; 1579c91c1c84SLorenzo Bianconi 1580c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 1581c91c1c84SLorenzo Bianconi 1582c91c1c84SLorenzo Bianconi pdata = (struct st_sensors_platform_data *)hw->dev->platform_data; 1583c91c1c84SLorenzo Bianconi if ((np && of_property_read_bool(np, "st,pullups")) || 1584c91c1c84SLorenzo Bianconi (pdata && pdata->pullups)) { 1585c91c1c84SLorenzo Bianconi err = st_lsm6dsx_set_page(hw, true); 1586c91c1c84SLorenzo Bianconi if (err < 0) 1587c91c1c84SLorenzo Bianconi return err; 1588c91c1c84SLorenzo Bianconi 1589c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask); 1590c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 1591c91c1c84SLorenzo Bianconi hub_settings->pullup_en.addr, 1592c91c1c84SLorenzo Bianconi hub_settings->pullup_en.mask, data); 1593c91c1c84SLorenzo Bianconi 1594c91c1c84SLorenzo Bianconi st_lsm6dsx_set_page(hw, false); 1595c91c1c84SLorenzo Bianconi 1596c91c1c84SLorenzo Bianconi if (err < 0) 1597c91c1c84SLorenzo Bianconi return err; 1598c91c1c84SLorenzo Bianconi } 1599c91c1c84SLorenzo Bianconi 1600c91c1c84SLorenzo Bianconi if (hub_settings->aux_sens.addr) { 1601c91c1c84SLorenzo Bianconi /* configure aux sensors */ 1602c91c1c84SLorenzo Bianconi err = st_lsm6dsx_set_page(hw, true); 1603c91c1c84SLorenzo Bianconi if (err < 0) 1604c91c1c84SLorenzo Bianconi return err; 1605c91c1c84SLorenzo Bianconi 1606c91c1c84SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask); 1607c91c1c84SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 1608c91c1c84SLorenzo Bianconi hub_settings->aux_sens.addr, 1609c91c1c84SLorenzo Bianconi hub_settings->aux_sens.mask, data); 1610c91c1c84SLorenzo Bianconi 1611c91c1c84SLorenzo Bianconi st_lsm6dsx_set_page(hw, false); 1612c91c1c84SLorenzo Bianconi } 1613c91c1c84SLorenzo Bianconi 1614c91c1c84SLorenzo Bianconi return err; 1615c91c1c84SLorenzo Bianconi } 1616c91c1c84SLorenzo Bianconi 161721345107SLorenzo Bianconi static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw) 161821345107SLorenzo Bianconi { 161921345107SLorenzo Bianconi const struct st_lsm6dsx_hw_ts_settings *ts_settings; 162021345107SLorenzo Bianconi int err, val; 162121345107SLorenzo Bianconi 162221345107SLorenzo Bianconi ts_settings = &hw->settings->ts_settings; 162321345107SLorenzo Bianconi /* enable hw timestamp generation if necessary */ 162421345107SLorenzo Bianconi if (ts_settings->timer_en.addr) { 162521345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask); 162621345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 162721345107SLorenzo Bianconi ts_settings->timer_en.addr, 162821345107SLorenzo Bianconi ts_settings->timer_en.mask, val); 162921345107SLorenzo Bianconi if (err < 0) 163021345107SLorenzo Bianconi return err; 163121345107SLorenzo Bianconi } 163221345107SLorenzo Bianconi 163321345107SLorenzo Bianconi /* enable high resolution for hw ts timer if necessary */ 163421345107SLorenzo Bianconi if (ts_settings->hr_timer.addr) { 163521345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask); 163621345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 163721345107SLorenzo Bianconi ts_settings->hr_timer.addr, 163821345107SLorenzo Bianconi ts_settings->hr_timer.mask, val); 163921345107SLorenzo Bianconi if (err < 0) 164021345107SLorenzo Bianconi return err; 164121345107SLorenzo Bianconi } 164221345107SLorenzo Bianconi 164321345107SLorenzo Bianconi /* enable ts queueing in FIFO if necessary */ 164421345107SLorenzo Bianconi if (ts_settings->fifo_en.addr) { 164521345107SLorenzo Bianconi val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask); 164621345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 164721345107SLorenzo Bianconi ts_settings->fifo_en.addr, 164821345107SLorenzo Bianconi ts_settings->fifo_en.mask, val); 164921345107SLorenzo Bianconi if (err < 0) 165021345107SLorenzo Bianconi return err; 165121345107SLorenzo Bianconi } 165221345107SLorenzo Bianconi return 0; 165321345107SLorenzo Bianconi } 165421345107SLorenzo Bianconi 1655290a6ce1SLorenzo Bianconi static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw) 1656290a6ce1SLorenzo Bianconi { 165751a8b707SLorenzo Bianconi u8 drdy_int_reg; 1658290a6ce1SLorenzo Bianconi int err; 1659290a6ce1SLorenzo Bianconi 166019435425SLorenzo Bianconi /* device sw reset */ 16615022c5a4SMartin Kepplinger err = regmap_update_bits(hw->regmap, hw->settings->reset_addr, 166219435425SLorenzo Bianconi ST_LSM6DSX_REG_RESET_MASK, 166319435425SLorenzo Bianconi FIELD_PREP(ST_LSM6DSX_REG_RESET_MASK, 1)); 1664290a6ce1SLorenzo Bianconi if (err < 0) 1665290a6ce1SLorenzo Bianconi return err; 1666290a6ce1SLorenzo Bianconi 166719435425SLorenzo Bianconi msleep(50); 166819435425SLorenzo Bianconi 166919435425SLorenzo Bianconi /* reload trimming parameter */ 16705022c5a4SMartin Kepplinger err = regmap_update_bits(hw->regmap, hw->settings->reset_addr, 167119435425SLorenzo Bianconi ST_LSM6DSX_REG_BOOT_MASK, 167219435425SLorenzo Bianconi FIELD_PREP(ST_LSM6DSX_REG_BOOT_MASK, 1)); 167319435425SLorenzo Bianconi if (err < 0) 167419435425SLorenzo Bianconi return err; 167519435425SLorenzo Bianconi 167619435425SLorenzo Bianconi msleep(50); 1677290a6ce1SLorenzo Bianconi 1678290a6ce1SLorenzo Bianconi /* enable Block Data Update */ 167951a8b707SLorenzo Bianconi err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_BDU_ADDR, 168051a8b707SLorenzo Bianconi ST_LSM6DSX_REG_BDU_MASK, 168151a8b707SLorenzo Bianconi FIELD_PREP(ST_LSM6DSX_REG_BDU_MASK, 1)); 1682290a6ce1SLorenzo Bianconi if (err < 0) 1683290a6ce1SLorenzo Bianconi return err; 1684290a6ce1SLorenzo Bianconi 1685290a6ce1SLorenzo Bianconi /* enable FIFO watermak interrupt */ 1686dba32904SLorenzo Bianconi err = st_lsm6dsx_get_drdy_reg(hw, &drdy_int_reg); 1687290a6ce1SLorenzo Bianconi if (err < 0) 1688290a6ce1SLorenzo Bianconi return err; 1689290a6ce1SLorenzo Bianconi 169021345107SLorenzo Bianconi err = regmap_update_bits(hw->regmap, drdy_int_reg, 169151a8b707SLorenzo Bianconi ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK, 169251a8b707SLorenzo Bianconi FIELD_PREP(ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK, 169351a8b707SLorenzo Bianconi 1)); 169421345107SLorenzo Bianconi if (err < 0) 169521345107SLorenzo Bianconi return err; 169621345107SLorenzo Bianconi 16979db02d32SLorenzo Bianconi /* enable Latched interrupts for device events */ 16989db02d32SLorenzo Bianconi if (hw->settings->lir.addr) { 16999db02d32SLorenzo Bianconi unsigned int data; 17009db02d32SLorenzo Bianconi 17019db02d32SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(1, hw->settings->lir.mask); 17029db02d32SLorenzo Bianconi err = regmap_update_bits(hw->regmap, hw->settings->lir.addr, 17039db02d32SLorenzo Bianconi hw->settings->lir.mask, data); 17049db02d32SLorenzo Bianconi if (err < 0) 17059db02d32SLorenzo Bianconi return err; 170622ea5651SLorenzo Bianconi 170722ea5651SLorenzo Bianconi /* enable clear on read for latched interrupts */ 170822ea5651SLorenzo Bianconi if (hw->settings->clear_on_read.addr) { 170922ea5651SLorenzo Bianconi data = ST_LSM6DSX_SHIFT_VAL(1, 171022ea5651SLorenzo Bianconi hw->settings->clear_on_read.mask); 171122ea5651SLorenzo Bianconi err = regmap_update_bits(hw->regmap, 171222ea5651SLorenzo Bianconi hw->settings->clear_on_read.addr, 171322ea5651SLorenzo Bianconi hw->settings->clear_on_read.mask, 171422ea5651SLorenzo Bianconi data); 171522ea5651SLorenzo Bianconi if (err < 0) 171622ea5651SLorenzo Bianconi return err; 171722ea5651SLorenzo Bianconi } 17189db02d32SLorenzo Bianconi } 17199db02d32SLorenzo Bianconi 1720c91c1c84SLorenzo Bianconi err = st_lsm6dsx_init_shub(hw); 1721c91c1c84SLorenzo Bianconi if (err < 0) 1722c91c1c84SLorenzo Bianconi return err; 1723c91c1c84SLorenzo Bianconi 172421345107SLorenzo Bianconi return st_lsm6dsx_init_hw_timer(hw); 1725290a6ce1SLorenzo Bianconi } 1726290a6ce1SLorenzo Bianconi 1727290a6ce1SLorenzo Bianconi static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw, 1728510c0106SLorenzo Bianconi enum st_lsm6dsx_sensor_id id, 1729510c0106SLorenzo Bianconi const char *name) 1730290a6ce1SLorenzo Bianconi { 1731290a6ce1SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 1732290a6ce1SLorenzo Bianconi struct iio_dev *iio_dev; 1733290a6ce1SLorenzo Bianconi 1734290a6ce1SLorenzo Bianconi iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor)); 1735290a6ce1SLorenzo Bianconi if (!iio_dev) 1736290a6ce1SLorenzo Bianconi return NULL; 1737290a6ce1SLorenzo Bianconi 1738290a6ce1SLorenzo Bianconi iio_dev->modes = INDIO_DIRECT_MODE; 1739290a6ce1SLorenzo Bianconi iio_dev->dev.parent = hw->dev; 1740290a6ce1SLorenzo Bianconi iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks; 1741f48bc49bSLorenzo Bianconi iio_dev->channels = hw->settings->channels[id].chan; 1742f48bc49bSLorenzo Bianconi iio_dev->num_channels = hw->settings->channels[id].len; 1743290a6ce1SLorenzo Bianconi 1744290a6ce1SLorenzo Bianconi sensor = iio_priv(iio_dev); 1745290a6ce1SLorenzo Bianconi sensor->id = id; 1746290a6ce1SLorenzo Bianconi sensor->hw = hw; 174740dd7343SLorenzo Bianconi sensor->odr = hw->settings->odr_table[id].odr_avl[0].hz; 1748640aca3fSLorenzo Bianconi sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain; 1749290a6ce1SLorenzo Bianconi sensor->watermark = 1; 1750290a6ce1SLorenzo Bianconi 1751290a6ce1SLorenzo Bianconi switch (id) { 1752290a6ce1SLorenzo Bianconi case ST_LSM6DSX_ID_ACC: 1753290a6ce1SLorenzo Bianconi iio_dev->info = &st_lsm6dsx_acc_info; 1754510c0106SLorenzo Bianconi scnprintf(sensor->name, sizeof(sensor->name), "%s_accel", 1755510c0106SLorenzo Bianconi name); 1756290a6ce1SLorenzo Bianconi break; 1757290a6ce1SLorenzo Bianconi case ST_LSM6DSX_ID_GYRO: 1758290a6ce1SLorenzo Bianconi iio_dev->info = &st_lsm6dsx_gyro_info; 1759510c0106SLorenzo Bianconi scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro", 1760510c0106SLorenzo Bianconi name); 1761290a6ce1SLorenzo Bianconi break; 1762290a6ce1SLorenzo Bianconi default: 1763290a6ce1SLorenzo Bianconi return NULL; 1764290a6ce1SLorenzo Bianconi } 1765510c0106SLorenzo Bianconi iio_dev->name = sensor->name; 1766290a6ce1SLorenzo Bianconi 1767290a6ce1SLorenzo Bianconi return iio_dev; 1768290a6ce1SLorenzo Bianconi } 1769290a6ce1SLorenzo Bianconi 1770615bd378SLorenzo Bianconi static bool 1771615bd378SLorenzo Bianconi st_lsm6dsx_report_motion_event(struct st_lsm6dsx_hw *hw) 17721aabad1fSSean Nyekjaer { 1773615bd378SLorenzo Bianconi const struct st_lsm6dsx_event_settings *event_settings; 1774615bd378SLorenzo Bianconi int err, data; 1775615bd378SLorenzo Bianconi s64 timestamp; 17761aabad1fSSean Nyekjaer 1777615bd378SLorenzo Bianconi if (!hw->enable_event) 1778615bd378SLorenzo Bianconi return false; 1779615bd378SLorenzo Bianconi 1780615bd378SLorenzo Bianconi event_settings = &hw->settings->event_settings; 1781615bd378SLorenzo Bianconi err = st_lsm6dsx_read_locked(hw, event_settings->wakeup_src_reg, 1782615bd378SLorenzo Bianconi &data, sizeof(data)); 1783615bd378SLorenzo Bianconi if (err < 0) 1784615bd378SLorenzo Bianconi return false; 1785615bd378SLorenzo Bianconi 1786615bd378SLorenzo Bianconi timestamp = iio_get_time_ns(hw->iio_devs[ST_LSM6DSX_ID_ACC]); 17871aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_z_mask) && 17881aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_Z))) 17891aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 17901aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 17911aabad1fSSean Nyekjaer 0, 17921aabad1fSSean Nyekjaer IIO_MOD_Z, 17931aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 17941aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 17951aabad1fSSean Nyekjaer timestamp); 17961aabad1fSSean Nyekjaer 17971aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_y_mask) && 17981aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_Y))) 17991aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 18001aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 18011aabad1fSSean Nyekjaer 0, 18021aabad1fSSean Nyekjaer IIO_MOD_Y, 18031aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 18041aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 18051aabad1fSSean Nyekjaer timestamp); 18061aabad1fSSean Nyekjaer 18071aabad1fSSean Nyekjaer if ((data & hw->settings->event_settings.wakeup_src_x_mask) && 18081aabad1fSSean Nyekjaer (hw->enable_event & BIT(IIO_MOD_X))) 18091aabad1fSSean Nyekjaer iio_push_event(hw->iio_devs[ST_LSM6DSX_ID_ACC], 18101aabad1fSSean Nyekjaer IIO_MOD_EVENT_CODE(IIO_ACCEL, 18111aabad1fSSean Nyekjaer 0, 18121aabad1fSSean Nyekjaer IIO_MOD_X, 18131aabad1fSSean Nyekjaer IIO_EV_TYPE_THRESH, 18141aabad1fSSean Nyekjaer IIO_EV_DIR_EITHER), 18151aabad1fSSean Nyekjaer timestamp); 1816615bd378SLorenzo Bianconi 1817615bd378SLorenzo Bianconi return data & event_settings->wakeup_src_status_mask; 18181aabad1fSSean Nyekjaer } 18191aabad1fSSean Nyekjaer 18206ee6a368SSean Nyekjaer static irqreturn_t st_lsm6dsx_handler_thread(int irq, void *private) 18216ee6a368SSean Nyekjaer { 18226ee6a368SSean Nyekjaer struct st_lsm6dsx_hw *hw = private; 1823615bd378SLorenzo Bianconi bool event; 18246ee6a368SSean Nyekjaer int count; 18251aabad1fSSean Nyekjaer 1826615bd378SLorenzo Bianconi event = st_lsm6dsx_report_motion_event(hw); 18276ee6a368SSean Nyekjaer 1828a912ee4cSLorenzo Bianconi if (!hw->settings->fifo_ops.read_fifo) 1829a912ee4cSLorenzo Bianconi return event ? IRQ_HANDLED : IRQ_NONE; 1830a912ee4cSLorenzo Bianconi 18316ee6a368SSean Nyekjaer mutex_lock(&hw->fifo_lock); 18326ee6a368SSean Nyekjaer count = hw->settings->fifo_ops.read_fifo(hw); 18336ee6a368SSean Nyekjaer mutex_unlock(&hw->fifo_lock); 18346ee6a368SSean Nyekjaer 1835615bd378SLorenzo Bianconi return count || event ? IRQ_HANDLED : IRQ_NONE; 18366ee6a368SSean Nyekjaer } 18376ee6a368SSean Nyekjaer 18386ee6a368SSean Nyekjaer static int st_lsm6dsx_irq_setup(struct st_lsm6dsx_hw *hw) 18396ee6a368SSean Nyekjaer { 18406ee6a368SSean Nyekjaer struct st_sensors_platform_data *pdata; 18416ee6a368SSean Nyekjaer struct device_node *np = hw->dev->of_node; 18426ee6a368SSean Nyekjaer unsigned long irq_type; 18436ee6a368SSean Nyekjaer bool irq_active_low; 18446ee6a368SSean Nyekjaer int err; 18456ee6a368SSean Nyekjaer 18466ee6a368SSean Nyekjaer irq_type = irqd_get_trigger_type(irq_get_irq_data(hw->irq)); 18476ee6a368SSean Nyekjaer 18486ee6a368SSean Nyekjaer switch (irq_type) { 18496ee6a368SSean Nyekjaer case IRQF_TRIGGER_HIGH: 18506ee6a368SSean Nyekjaer case IRQF_TRIGGER_RISING: 18516ee6a368SSean Nyekjaer irq_active_low = false; 18526ee6a368SSean Nyekjaer break; 18536ee6a368SSean Nyekjaer case IRQF_TRIGGER_LOW: 18546ee6a368SSean Nyekjaer case IRQF_TRIGGER_FALLING: 18556ee6a368SSean Nyekjaer irq_active_low = true; 18566ee6a368SSean Nyekjaer break; 18576ee6a368SSean Nyekjaer default: 18586ee6a368SSean Nyekjaer dev_info(hw->dev, "mode %lx unsupported\n", irq_type); 18596ee6a368SSean Nyekjaer return -EINVAL; 18606ee6a368SSean Nyekjaer } 18616ee6a368SSean Nyekjaer 18626ee6a368SSean Nyekjaer err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_HLACTIVE_ADDR, 18636ee6a368SSean Nyekjaer ST_LSM6DSX_REG_HLACTIVE_MASK, 18646ee6a368SSean Nyekjaer FIELD_PREP(ST_LSM6DSX_REG_HLACTIVE_MASK, 18656ee6a368SSean Nyekjaer irq_active_low)); 18666ee6a368SSean Nyekjaer if (err < 0) 18676ee6a368SSean Nyekjaer return err; 18686ee6a368SSean Nyekjaer 18696ee6a368SSean Nyekjaer pdata = (struct st_sensors_platform_data *)hw->dev->platform_data; 18706ee6a368SSean Nyekjaer if ((np && of_property_read_bool(np, "drive-open-drain")) || 18716ee6a368SSean Nyekjaer (pdata && pdata->open_drain)) { 18726ee6a368SSean Nyekjaer err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_PP_OD_ADDR, 18736ee6a368SSean Nyekjaer ST_LSM6DSX_REG_PP_OD_MASK, 18746ee6a368SSean Nyekjaer FIELD_PREP(ST_LSM6DSX_REG_PP_OD_MASK, 18756ee6a368SSean Nyekjaer 1)); 18766ee6a368SSean Nyekjaer if (err < 0) 18776ee6a368SSean Nyekjaer return err; 18786ee6a368SSean Nyekjaer 18796ee6a368SSean Nyekjaer irq_type |= IRQF_SHARED; 18806ee6a368SSean Nyekjaer } 18816ee6a368SSean Nyekjaer 18826ee6a368SSean Nyekjaer err = devm_request_threaded_irq(hw->dev, hw->irq, 1883a3aa17d4SSean Nyekjaer NULL, 18846ee6a368SSean Nyekjaer st_lsm6dsx_handler_thread, 18856ee6a368SSean Nyekjaer irq_type | IRQF_ONESHOT, 18866ee6a368SSean Nyekjaer "lsm6dsx", hw); 18876ee6a368SSean Nyekjaer if (err) { 18886ee6a368SSean Nyekjaer dev_err(hw->dev, "failed to request trigger irq %d\n", 18896ee6a368SSean Nyekjaer hw->irq); 18906ee6a368SSean Nyekjaer return err; 18916ee6a368SSean Nyekjaer } 18926ee6a368SSean Nyekjaer 18936ee6a368SSean Nyekjaer return 0; 18946ee6a368SSean Nyekjaer } 18956ee6a368SSean Nyekjaer 189681956a93SLorenzo Bianconi int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id, 189751a8b707SLorenzo Bianconi struct regmap *regmap) 1898290a6ce1SLorenzo Bianconi { 1899c91c1c84SLorenzo Bianconi const struct st_lsm6dsx_shub_settings *hub_settings; 1900290a6ce1SLorenzo Bianconi struct st_lsm6dsx_hw *hw; 190181956a93SLorenzo Bianconi const char *name = NULL; 1902290a6ce1SLorenzo Bianconi int i, err; 1903290a6ce1SLorenzo Bianconi 1904290a6ce1SLorenzo Bianconi hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL); 1905290a6ce1SLorenzo Bianconi if (!hw) 1906290a6ce1SLorenzo Bianconi return -ENOMEM; 1907290a6ce1SLorenzo Bianconi 1908290a6ce1SLorenzo Bianconi dev_set_drvdata(dev, (void *)hw); 1909290a6ce1SLorenzo Bianconi 1910290a6ce1SLorenzo Bianconi mutex_init(&hw->fifo_lock); 1911335eaedcSLorenzo Bianconi mutex_init(&hw->conf_lock); 1912739aff87SLorenzo Bianconi mutex_init(&hw->page_lock); 1913290a6ce1SLorenzo Bianconi 191491a6b841SLorenzo Bianconi hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL); 191591a6b841SLorenzo Bianconi if (!hw->buff) 191691a6b841SLorenzo Bianconi return -ENOMEM; 191791a6b841SLorenzo Bianconi 1918290a6ce1SLorenzo Bianconi hw->dev = dev; 1919290a6ce1SLorenzo Bianconi hw->irq = irq; 192051a8b707SLorenzo Bianconi hw->regmap = regmap; 1921290a6ce1SLorenzo Bianconi 192281956a93SLorenzo Bianconi err = st_lsm6dsx_check_whoami(hw, hw_id, &name); 1923290a6ce1SLorenzo Bianconi if (err < 0) 1924290a6ce1SLorenzo Bianconi return err; 1925290a6ce1SLorenzo Bianconi 19266ffb55e5SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) { 1927510c0106SLorenzo Bianconi hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name); 1928290a6ce1SLorenzo Bianconi if (!hw->iio_devs[i]) 1929290a6ce1SLorenzo Bianconi return -ENOMEM; 1930290a6ce1SLorenzo Bianconi } 1931290a6ce1SLorenzo Bianconi 1932290a6ce1SLorenzo Bianconi err = st_lsm6dsx_init_device(hw); 1933290a6ce1SLorenzo Bianconi if (err < 0) 1934290a6ce1SLorenzo Bianconi return err; 1935290a6ce1SLorenzo Bianconi 1936c91c1c84SLorenzo Bianconi hub_settings = &hw->settings->shub_settings; 1937c91c1c84SLorenzo Bianconi if (hub_settings->master_en.addr) { 1938c91c1c84SLorenzo Bianconi err = st_lsm6dsx_shub_probe(hw, name); 1939c91c1c84SLorenzo Bianconi if (err < 0) 1940c91c1c84SLorenzo Bianconi return err; 1941c91c1c84SLorenzo Bianconi } 1942c91c1c84SLorenzo Bianconi 1943290a6ce1SLorenzo Bianconi if (hw->irq > 0) { 19446ee6a368SSean Nyekjaer err = st_lsm6dsx_irq_setup(hw); 19456ee6a368SSean Nyekjaer if (err < 0) 19466ee6a368SSean Nyekjaer return err; 19476ee6a368SSean Nyekjaer 1948290a6ce1SLorenzo Bianconi err = st_lsm6dsx_fifo_setup(hw); 1949290a6ce1SLorenzo Bianconi if (err < 0) 1950290a6ce1SLorenzo Bianconi return err; 1951290a6ce1SLorenzo Bianconi } 1952290a6ce1SLorenzo Bianconi 1953290a6ce1SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 19546ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 19556ffb55e5SLorenzo Bianconi continue; 19566ffb55e5SLorenzo Bianconi 1957290a6ce1SLorenzo Bianconi err = devm_iio_device_register(hw->dev, hw->iio_devs[i]); 1958290a6ce1SLorenzo Bianconi if (err) 1959290a6ce1SLorenzo Bianconi return err; 1960290a6ce1SLorenzo Bianconi } 1961290a6ce1SLorenzo Bianconi 19624c997dfaSSean Nyekjaer if (dev->of_node && of_property_read_bool(dev->of_node, "wakeup-source")) 19634c997dfaSSean Nyekjaer device_init_wakeup(dev, true); 19644c997dfaSSean Nyekjaer 1965290a6ce1SLorenzo Bianconi return 0; 1966290a6ce1SLorenzo Bianconi } 1967290a6ce1SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_probe); 1968290a6ce1SLorenzo Bianconi 19693cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_suspend(struct device *dev) 1970d3f77058SLorenzo Bianconi { 1971d3f77058SLorenzo Bianconi struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); 1972d3f77058SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 1973d3f77058SLorenzo Bianconi int i, err = 0; 1974d3f77058SLorenzo Bianconi 1975d3f77058SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 19766ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 19776ffb55e5SLorenzo Bianconi continue; 19786ffb55e5SLorenzo Bianconi 1979d3f77058SLorenzo Bianconi sensor = iio_priv(hw->iio_devs[i]); 1980d3f77058SLorenzo Bianconi if (!(hw->enable_mask & BIT(sensor->id))) 1981d3f77058SLorenzo Bianconi continue; 1982d3f77058SLorenzo Bianconi 19834c997dfaSSean Nyekjaer if (device_may_wakeup(dev) && 19844c997dfaSSean Nyekjaer sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) { 19854c997dfaSSean Nyekjaer /* Enable wake from IRQ */ 19864c997dfaSSean Nyekjaer enable_irq_wake(hw->irq); 19874c997dfaSSean Nyekjaer continue; 19884c997dfaSSean Nyekjaer } 19894c997dfaSSean Nyekjaer 1990bce0d57dSLorenzo Bianconi if (sensor->id == ST_LSM6DSX_ID_EXT0 || 1991bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT1 || 1992bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT2) 1993bce0d57dSLorenzo Bianconi err = st_lsm6dsx_shub_set_enable(sensor, false); 1994bce0d57dSLorenzo Bianconi else 1995bce0d57dSLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, false); 1996d3f77058SLorenzo Bianconi if (err < 0) 1997d3f77058SLorenzo Bianconi return err; 1998bce0d57dSLorenzo Bianconi 1999bce0d57dSLorenzo Bianconi hw->suspend_mask |= BIT(sensor->id); 2000d3f77058SLorenzo Bianconi } 2001d3f77058SLorenzo Bianconi 2002d3f77058SLorenzo Bianconi if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS) 2003d3f77058SLorenzo Bianconi err = st_lsm6dsx_flush_fifo(hw); 2004d3f77058SLorenzo Bianconi 2005d3f77058SLorenzo Bianconi return err; 2006d3f77058SLorenzo Bianconi } 2007d3f77058SLorenzo Bianconi 20083cec4850SLorenzo Bianconi static int __maybe_unused st_lsm6dsx_resume(struct device *dev) 2009d3f77058SLorenzo Bianconi { 2010d3f77058SLorenzo Bianconi struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev); 2011d3f77058SLorenzo Bianconi struct st_lsm6dsx_sensor *sensor; 2012d3f77058SLorenzo Bianconi int i, err = 0; 2013d3f77058SLorenzo Bianconi 2014d3f77058SLorenzo Bianconi for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) { 20156ffb55e5SLorenzo Bianconi if (!hw->iio_devs[i]) 20166ffb55e5SLorenzo Bianconi continue; 20176ffb55e5SLorenzo Bianconi 2018d3f77058SLorenzo Bianconi sensor = iio_priv(hw->iio_devs[i]); 20194c997dfaSSean Nyekjaer if (device_may_wakeup(dev) && 20204c997dfaSSean Nyekjaer sensor->id == ST_LSM6DSX_ID_ACC && hw->enable_event) 20214c997dfaSSean Nyekjaer disable_irq_wake(hw->irq); 20224c997dfaSSean Nyekjaer 2023bce0d57dSLorenzo Bianconi if (!(hw->suspend_mask & BIT(sensor->id))) 2024d3f77058SLorenzo Bianconi continue; 2025d3f77058SLorenzo Bianconi 2026bce0d57dSLorenzo Bianconi if (sensor->id == ST_LSM6DSX_ID_EXT0 || 2027bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT1 || 2028bce0d57dSLorenzo Bianconi sensor->id == ST_LSM6DSX_ID_EXT2) 2029bce0d57dSLorenzo Bianconi err = st_lsm6dsx_shub_set_enable(sensor, true); 2030bce0d57dSLorenzo Bianconi else 2031bce0d57dSLorenzo Bianconi err = st_lsm6dsx_sensor_set_enable(sensor, true); 2032d3f77058SLorenzo Bianconi if (err < 0) 2033d3f77058SLorenzo Bianconi return err; 2034bce0d57dSLorenzo Bianconi 2035bce0d57dSLorenzo Bianconi hw->suspend_mask &= ~BIT(sensor->id); 2036d3f77058SLorenzo Bianconi } 2037d3f77058SLorenzo Bianconi 2038d3f77058SLorenzo Bianconi if (hw->enable_mask) 2039d3f77058SLorenzo Bianconi err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT); 2040d3f77058SLorenzo Bianconi 2041d3f77058SLorenzo Bianconi return err; 2042d3f77058SLorenzo Bianconi } 2043d3f77058SLorenzo Bianconi 2044d3f77058SLorenzo Bianconi const struct dev_pm_ops st_lsm6dsx_pm_ops = { 2045d3f77058SLorenzo Bianconi SET_SYSTEM_SLEEP_PM_OPS(st_lsm6dsx_suspend, st_lsm6dsx_resume) 2046d3f77058SLorenzo Bianconi }; 2047d3f77058SLorenzo Bianconi EXPORT_SYMBOL(st_lsm6dsx_pm_ops); 2048d3f77058SLorenzo Bianconi 2049290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>"); 2050290a6ce1SLorenzo Bianconi MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 2051290a6ce1SLorenzo Bianconi MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver"); 2052290a6ce1SLorenzo Bianconi MODULE_LICENSE("GPL v2"); 2053