root/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. st_lsm6dsx_set_page
  2. st_lsm6dsx_check_whoami
  3. st_lsm6dsx_set_full_scale
  4. st_lsm6dsx_check_odr
  5. st_lsm6dsx_check_odr_dependency
  6. st_lsm6dsx_set_odr
  7. st_lsm6dsx_sensor_set_enable
  8. st_lsm6dsx_read_oneshot
  9. st_lsm6dsx_read_raw
  10. st_lsm6dsx_write_raw
  11. st_lsm6dsx_set_watermark
  12. st_lsm6dsx_sysfs_sampling_frequency_avail
  13. st_lsm6dsx_sysfs_scale_avail
  14. st_lsm6dsx_of_get_drdy_pin
  15. st_lsm6dsx_get_drdy_reg
  16. st_lsm6dsx_init_shub
  17. st_lsm6dsx_init_hw_timer
  18. st_lsm6dsx_init_device
  19. st_lsm6dsx_alloc_iiodev
  20. st_lsm6dsx_probe
  21. st_lsm6dsx_suspend
  22. st_lsm6dsx_resume

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * STMicroelectronics st_lsm6dsx sensor driver
   4  *
   5  * The ST LSM6DSx IMU MEMS series consists of 3D digital accelerometer
   6  * and 3D digital gyroscope system-in-package with a digital I2C/SPI serial
   7  * interface standard output.
   8  * LSM6DSx IMU MEMS series has a dynamic user-selectable full-scale
   9  * acceleration range of +-2/+-4/+-8/+-16 g and an angular rate range of
  10  * +-125/+-245/+-500/+-1000/+-2000 dps
  11  * LSM6DSx series has an integrated First-In-First-Out (FIFO) buffer
  12  * allowing dynamic batching of sensor data.
  13  * LSM9DSx series is similar but includes an additional magnetometer, handled
  14  * by a different driver.
  15  *
  16  * Supported sensors:
  17  * - LSM6DS3:
  18  *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
  19  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
  20  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
  21  *   - FIFO size: 8KB
  22  *
  23  * - LSM6DS3H/LSM6DSL/LSM6DSM/ISM330DLC/LSM6DS3TR-C:
  24  *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
  25  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
  26  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
  27  *   - FIFO size: 4KB
  28  *
  29  * - LSM6DSO/LSM6DSOX/ASM330LHH/LSM6DSR/ISM330DHCX:
  30  *   - Accelerometer/Gyroscope supported ODR [Hz]: 13, 26, 52, 104, 208, 416
  31  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
  32  *   - Gyroscope supported full-scale [dps]: +-125/+-245/+-500/+-1000/+-2000
  33  *   - FIFO size: 3KB
  34  *
  35  * - LSM9DS1:
  36  *   - Accelerometer supported ODR [Hz]: 10, 50, 119, 238, 476, 952
  37  *   - Accelerometer supported full-scale [g]: +-2/+-4/+-8/+-16
  38  *   - Gyroscope supported ODR [Hz]: 15, 60, 119, 238, 476, 952
  39  *   - Gyroscope supported full-scale [dps]: +-245/+-500/+-2000
  40  *   - FIFO size: 32
  41  *
  42  * Copyright 2016 STMicroelectronics Inc.
  43  *
  44  * Lorenzo Bianconi <lorenzo.bianconi@st.com>
  45  * Denis Ciocca <denis.ciocca@st.com>
  46  */
  47 
  48 #include <linux/kernel.h>
  49 #include <linux/module.h>
  50 #include <linux/delay.h>
  51 #include <linux/iio/iio.h>
  52 #include <linux/iio/sysfs.h>
  53 #include <linux/pm.h>
  54 #include <linux/regmap.h>
  55 #include <linux/bitfield.h>
  56 
  57 #include <linux/platform_data/st_sensors_pdata.h>
  58 
  59 #include "st_lsm6dsx.h"
  60 
  61 #define ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK        BIT(3)
  62 #define ST_LSM6DSX_REG_WHOAMI_ADDR              0x0f
  63 #define ST_LSM6DSX_REG_RESET_MASK               BIT(0)
  64 #define ST_LSM6DSX_REG_BOOT_MASK                BIT(7)
  65 #define ST_LSM6DSX_REG_BDU_ADDR                 0x12
  66 #define ST_LSM6DSX_REG_BDU_MASK                 BIT(6)
  67 
  68 static const struct iio_chan_spec st_lsm6dsx_acc_channels[] = {
  69         ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x28, IIO_MOD_X, 0),
  70         ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2a, IIO_MOD_Y, 1),
  71         ST_LSM6DSX_CHANNEL(IIO_ACCEL, 0x2c, IIO_MOD_Z, 2),
  72         IIO_CHAN_SOFT_TIMESTAMP(3),
  73 };
  74 
  75 static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {
  76         ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x22, IIO_MOD_X, 0),
  77         ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x24, IIO_MOD_Y, 1),
  78         ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x26, IIO_MOD_Z, 2),
  79         IIO_CHAN_SOFT_TIMESTAMP(3),
  80 };
  81 
  82 static const struct iio_chan_spec st_lsm6ds0_gyro_channels[] = {
  83         ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x18, IIO_MOD_X, 0),
  84         ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1a, IIO_MOD_Y, 1),
  85         ST_LSM6DSX_CHANNEL(IIO_ANGL_VEL, 0x1c, IIO_MOD_Z, 2),
  86         IIO_CHAN_SOFT_TIMESTAMP(3),
  87 };
  88 
  89 static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = {
  90         {
  91                 .wai = 0x68,
  92                 .int1_addr = 0x0c,
  93                 .int2_addr = 0x0d,
  94                 .reset_addr = 0x22,
  95                 .max_fifo_size = 32,
  96                 .id = {
  97                         {
  98                                 .hw_id = ST_LSM9DS1_ID,
  99                                 .name = ST_LSM9DS1_DEV_NAME,
 100                         },
 101                 },
 102                 .channels = {
 103                         [ST_LSM6DSX_ID_ACC] = {
 104                                 .chan = st_lsm6dsx_acc_channels,
 105                                 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
 106                         },
 107                         [ST_LSM6DSX_ID_GYRO] = {
 108                                 .chan = st_lsm6ds0_gyro_channels,
 109                                 .len = ARRAY_SIZE(st_lsm6ds0_gyro_channels),
 110                         },
 111                 },
 112                 .odr_table = {
 113                         [ST_LSM6DSX_ID_ACC] = {
 114                                 .reg = {
 115                                         .addr = 0x20,
 116                                         .mask = GENMASK(7, 5),
 117                                 },
 118                                 .odr_avl[0] = {  10, 0x01 },
 119                                 .odr_avl[1] = {  50, 0x02 },
 120                                 .odr_avl[2] = { 119, 0x03 },
 121                                 .odr_avl[3] = { 238, 0x04 },
 122                                 .odr_avl[4] = { 476, 0x05 },
 123                                 .odr_avl[5] = { 952, 0x06 },
 124                         },
 125                         [ST_LSM6DSX_ID_GYRO] = {
 126                                 .reg = {
 127                                         .addr = 0x10,
 128                                         .mask = GENMASK(7, 5),
 129                                 },
 130                                 .odr_avl[0] = {  15, 0x01 },
 131                                 .odr_avl[1] = {  60, 0x02 },
 132                                 .odr_avl[2] = { 119, 0x03 },
 133                                 .odr_avl[3] = { 238, 0x04 },
 134                                 .odr_avl[4] = { 476, 0x05 },
 135                                 .odr_avl[5] = { 952, 0x06 },
 136                         },
 137                 },
 138                 .fs_table = {
 139                         [ST_LSM6DSX_ID_ACC] = {
 140                                 .reg = {
 141                                         .addr = 0x20,
 142                                         .mask = GENMASK(4, 3),
 143                                 },
 144                                 .fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
 145                                 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
 146                                 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
 147                                 .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 },
 148                                 .fs_len = 4,
 149                         },
 150                         [ST_LSM6DSX_ID_GYRO] = {
 151                                 .reg = {
 152                                         .addr = 0x10,
 153                                         .mask = GENMASK(4, 3),
 154                                 },
 155 
 156                                 .fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
 157                                 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
 158                                 .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
 159                                 .fs_len = 3,
 160                         },
 161                 },
 162         },
 163         {
 164                 .wai = 0x69,
 165                 .int1_addr = 0x0d,
 166                 .int2_addr = 0x0e,
 167                 .reset_addr = 0x12,
 168                 .max_fifo_size = 1365,
 169                 .id = {
 170                         {
 171                                 .hw_id = ST_LSM6DS3_ID,
 172                                 .name = ST_LSM6DS3_DEV_NAME,
 173                         },
 174                 },
 175                 .channels = {
 176                         [ST_LSM6DSX_ID_ACC] = {
 177                                 .chan = st_lsm6dsx_acc_channels,
 178                                 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
 179                         },
 180                         [ST_LSM6DSX_ID_GYRO] = {
 181                                 .chan = st_lsm6dsx_gyro_channels,
 182                                 .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
 183                         },
 184                 },
 185                 .odr_table = {
 186                         [ST_LSM6DSX_ID_ACC] = {
 187                                 .reg = {
 188                                         .addr = 0x10,
 189                                         .mask = GENMASK(7, 4),
 190                                 },
 191                                 .odr_avl[0] = {  13, 0x01 },
 192                                 .odr_avl[1] = {  26, 0x02 },
 193                                 .odr_avl[2] = {  52, 0x03 },
 194                                 .odr_avl[3] = { 104, 0x04 },
 195                                 .odr_avl[4] = { 208, 0x05 },
 196                                 .odr_avl[5] = { 416, 0x06 },
 197                         },
 198                         [ST_LSM6DSX_ID_GYRO] = {
 199                                 .reg = {
 200                                         .addr = 0x11,
 201                                         .mask = GENMASK(7, 4),
 202                                 },
 203                                 .odr_avl[0] = {  13, 0x01 },
 204                                 .odr_avl[1] = {  26, 0x02 },
 205                                 .odr_avl[2] = {  52, 0x03 },
 206                                 .odr_avl[3] = { 104, 0x04 },
 207                                 .odr_avl[4] = { 208, 0x05 },
 208                                 .odr_avl[5] = { 416, 0x06 },
 209                         },
 210                 },
 211                 .fs_table = {
 212                         [ST_LSM6DSX_ID_ACC] = {
 213                                 .reg = {
 214                                         .addr = 0x10,
 215                                         .mask = GENMASK(3, 2),
 216                                 },
 217                                 .fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
 218                                 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
 219                                 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
 220                                 .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
 221                                 .fs_len = 4,
 222                         },
 223                         [ST_LSM6DSX_ID_GYRO] = {
 224                                 .reg = {
 225                                         .addr = 0x11,
 226                                         .mask = GENMASK(3, 2),
 227                                 },
 228                                 .fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
 229                                 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
 230                                 .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
 231                                 .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
 232                                 .fs_len = 4,
 233                         },
 234                 },
 235                 .decimator = {
 236                         [ST_LSM6DSX_ID_ACC] = {
 237                                 .addr = 0x08,
 238                                 .mask = GENMASK(2, 0),
 239                         },
 240                         [ST_LSM6DSX_ID_GYRO] = {
 241                                 .addr = 0x08,
 242                                 .mask = GENMASK(5, 3),
 243                         },
 244                 },
 245                 .fifo_ops = {
 246                         .update_fifo = st_lsm6dsx_update_fifo,
 247                         .read_fifo = st_lsm6dsx_read_fifo,
 248                         .fifo_th = {
 249                                 .addr = 0x06,
 250                                 .mask = GENMASK(11, 0),
 251                         },
 252                         .fifo_diff = {
 253                                 .addr = 0x3a,
 254                                 .mask = GENMASK(11, 0),
 255                         },
 256                         .th_wl = 3, /* 1LSB = 2B */
 257                 },
 258                 .ts_settings = {
 259                         .timer_en = {
 260                                 .addr = 0x58,
 261                                 .mask = BIT(7),
 262                         },
 263                         .hr_timer = {
 264                                 .addr = 0x5c,
 265                                 .mask = BIT(4),
 266                         },
 267                         .fifo_en = {
 268                                 .addr = 0x07,
 269                                 .mask = BIT(7),
 270                         },
 271                         .decimator = {
 272                                 .addr = 0x09,
 273                                 .mask = GENMASK(5, 3),
 274                         },
 275                 },
 276         },
 277         {
 278                 .wai = 0x69,
 279                 .int1_addr = 0x0d,
 280                 .int2_addr = 0x0e,
 281                 .reset_addr = 0x12,
 282                 .max_fifo_size = 682,
 283                 .id = {
 284                         {
 285                                 .hw_id = ST_LSM6DS3H_ID,
 286                                 .name = ST_LSM6DS3H_DEV_NAME,
 287                         },
 288                 },
 289                 .channels = {
 290                         [ST_LSM6DSX_ID_ACC] = {
 291                                 .chan = st_lsm6dsx_acc_channels,
 292                                 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
 293                         },
 294                         [ST_LSM6DSX_ID_GYRO] = {
 295                                 .chan = st_lsm6dsx_gyro_channels,
 296                                 .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
 297                         },
 298                 },
 299                 .odr_table = {
 300                         [ST_LSM6DSX_ID_ACC] = {
 301                                 .reg = {
 302                                         .addr = 0x10,
 303                                         .mask = GENMASK(7, 4),
 304                                 },
 305                                 .odr_avl[0] = {  13, 0x01 },
 306                                 .odr_avl[1] = {  26, 0x02 },
 307                                 .odr_avl[2] = {  52, 0x03 },
 308                                 .odr_avl[3] = { 104, 0x04 },
 309                                 .odr_avl[4] = { 208, 0x05 },
 310                                 .odr_avl[5] = { 416, 0x06 },
 311                         },
 312                         [ST_LSM6DSX_ID_GYRO] = {
 313                                 .reg = {
 314                                         .addr = 0x11,
 315                                         .mask = GENMASK(7, 4),
 316                                 },
 317                                 .odr_avl[0] = {  13, 0x01 },
 318                                 .odr_avl[1] = {  26, 0x02 },
 319                                 .odr_avl[2] = {  52, 0x03 },
 320                                 .odr_avl[3] = { 104, 0x04 },
 321                                 .odr_avl[4] = { 208, 0x05 },
 322                                 .odr_avl[5] = { 416, 0x06 },
 323                         },
 324                 },
 325                 .fs_table = {
 326                         [ST_LSM6DSX_ID_ACC] = {
 327                                 .reg = {
 328                                         .addr = 0x10,
 329                                         .mask = GENMASK(3, 2),
 330                                 },
 331                                 .fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
 332                                 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
 333                                 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
 334                                 .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
 335                                 .fs_len = 4,
 336                         },
 337                         [ST_LSM6DSX_ID_GYRO] = {
 338                                 .reg = {
 339                                         .addr = 0x11,
 340                                         .mask = GENMASK(3, 2),
 341                                 },
 342                                 .fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
 343                                 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
 344                                 .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
 345                                 .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
 346                                 .fs_len = 4,
 347                         },
 348                 },
 349                 .decimator = {
 350                         [ST_LSM6DSX_ID_ACC] = {
 351                                 .addr = 0x08,
 352                                 .mask = GENMASK(2, 0),
 353                         },
 354                         [ST_LSM6DSX_ID_GYRO] = {
 355                                 .addr = 0x08,
 356                                 .mask = GENMASK(5, 3),
 357                         },
 358                 },
 359                 .fifo_ops = {
 360                         .update_fifo = st_lsm6dsx_update_fifo,
 361                         .read_fifo = st_lsm6dsx_read_fifo,
 362                         .fifo_th = {
 363                                 .addr = 0x06,
 364                                 .mask = GENMASK(11, 0),
 365                         },
 366                         .fifo_diff = {
 367                                 .addr = 0x3a,
 368                                 .mask = GENMASK(11, 0),
 369                         },
 370                         .th_wl = 3, /* 1LSB = 2B */
 371                 },
 372                 .ts_settings = {
 373                         .timer_en = {
 374                                 .addr = 0x58,
 375                                 .mask = BIT(7),
 376                         },
 377                         .hr_timer = {
 378                                 .addr = 0x5c,
 379                                 .mask = BIT(4),
 380                         },
 381                         .fifo_en = {
 382                                 .addr = 0x07,
 383                                 .mask = BIT(7),
 384                         },
 385                         .decimator = {
 386                                 .addr = 0x09,
 387                                 .mask = GENMASK(5, 3),
 388                         },
 389                 },
 390         },
 391         {
 392                 .wai = 0x6a,
 393                 .int1_addr = 0x0d,
 394                 .int2_addr = 0x0e,
 395                 .reset_addr = 0x12,
 396                 .max_fifo_size = 682,
 397                 .id = {
 398                         {
 399                                 .hw_id = ST_LSM6DSL_ID,
 400                                 .name = ST_LSM6DSL_DEV_NAME,
 401                         }, {
 402                                 .hw_id = ST_LSM6DSM_ID,
 403                                 .name = ST_LSM6DSM_DEV_NAME,
 404                         }, {
 405                                 .hw_id = ST_ISM330DLC_ID,
 406                                 .name = ST_ISM330DLC_DEV_NAME,
 407                         }, {
 408                                 .hw_id = ST_LSM6DS3TRC_ID,
 409                                 .name = ST_LSM6DS3TRC_DEV_NAME,
 410                         },
 411                 },
 412                 .channels = {
 413                         [ST_LSM6DSX_ID_ACC] = {
 414                                 .chan = st_lsm6dsx_acc_channels,
 415                                 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
 416                         },
 417                         [ST_LSM6DSX_ID_GYRO] = {
 418                                 .chan = st_lsm6dsx_gyro_channels,
 419                                 .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
 420                         },
 421                 },
 422                 .odr_table = {
 423                         [ST_LSM6DSX_ID_ACC] = {
 424                                 .reg = {
 425                                         .addr = 0x10,
 426                                         .mask = GENMASK(7, 4),
 427                                 },
 428                                 .odr_avl[0] = {  13, 0x01 },
 429                                 .odr_avl[1] = {  26, 0x02 },
 430                                 .odr_avl[2] = {  52, 0x03 },
 431                                 .odr_avl[3] = { 104, 0x04 },
 432                                 .odr_avl[4] = { 208, 0x05 },
 433                                 .odr_avl[5] = { 416, 0x06 },
 434                         },
 435                         [ST_LSM6DSX_ID_GYRO] = {
 436                                 .reg = {
 437                                         .addr = 0x11,
 438                                         .mask = GENMASK(7, 4),
 439                                 },
 440                                 .odr_avl[0] = {  13, 0x01 },
 441                                 .odr_avl[1] = {  26, 0x02 },
 442                                 .odr_avl[2] = {  52, 0x03 },
 443                                 .odr_avl[3] = { 104, 0x04 },
 444                                 .odr_avl[4] = { 208, 0x05 },
 445                                 .odr_avl[5] = { 416, 0x06 },
 446                         },
 447                 },
 448                 .fs_table = {
 449                         [ST_LSM6DSX_ID_ACC] = {
 450                                 .reg = {
 451                                         .addr = 0x10,
 452                                         .mask = GENMASK(3, 2),
 453                                 },
 454                                 .fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
 455                                 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
 456                                 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
 457                                 .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
 458                                 .fs_len = 4,
 459                         },
 460                         [ST_LSM6DSX_ID_GYRO] = {
 461                                 .reg = {
 462                                         .addr = 0x11,
 463                                         .mask = GENMASK(3, 2),
 464                                 },
 465                                 .fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
 466                                 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
 467                                 .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
 468                                 .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
 469                                 .fs_len = 4,
 470                         },
 471                 },
 472                 .decimator = {
 473                         [ST_LSM6DSX_ID_ACC] = {
 474                                 .addr = 0x08,
 475                                 .mask = GENMASK(2, 0),
 476                         },
 477                         [ST_LSM6DSX_ID_GYRO] = {
 478                                 .addr = 0x08,
 479                                 .mask = GENMASK(5, 3),
 480                         },
 481                 },
 482                 .fifo_ops = {
 483                         .update_fifo = st_lsm6dsx_update_fifo,
 484                         .read_fifo = st_lsm6dsx_read_fifo,
 485                         .fifo_th = {
 486                                 .addr = 0x06,
 487                                 .mask = GENMASK(10, 0),
 488                         },
 489                         .fifo_diff = {
 490                                 .addr = 0x3a,
 491                                 .mask = GENMASK(10, 0),
 492                         },
 493                         .th_wl = 3, /* 1LSB = 2B */
 494                 },
 495                 .ts_settings = {
 496                         .timer_en = {
 497                                 .addr = 0x19,
 498                                 .mask = BIT(5),
 499                         },
 500                         .hr_timer = {
 501                                 .addr = 0x5c,
 502                                 .mask = BIT(4),
 503                         },
 504                         .fifo_en = {
 505                                 .addr = 0x07,
 506                                 .mask = BIT(7),
 507                         },
 508                         .decimator = {
 509                                 .addr = 0x09,
 510                                 .mask = GENMASK(5, 3),
 511                         },
 512                 },
 513         },
 514         {
 515                 .wai = 0x6c,
 516                 .int1_addr = 0x0d,
 517                 .int2_addr = 0x0e,
 518                 .reset_addr = 0x12,
 519                 .max_fifo_size = 512,
 520                 .id = {
 521                         {
 522                                 .hw_id = ST_LSM6DSO_ID,
 523                                 .name = ST_LSM6DSO_DEV_NAME,
 524                         }, {
 525                                 .hw_id = ST_LSM6DSOX_ID,
 526                                 .name = ST_LSM6DSOX_DEV_NAME,
 527                         },
 528                 },
 529                 .channels = {
 530                         [ST_LSM6DSX_ID_ACC] = {
 531                                 .chan = st_lsm6dsx_acc_channels,
 532                                 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
 533                         },
 534                         [ST_LSM6DSX_ID_GYRO] = {
 535                                 .chan = st_lsm6dsx_gyro_channels,
 536                                 .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
 537                         },
 538                 },
 539                 .odr_table = {
 540                         [ST_LSM6DSX_ID_ACC] = {
 541                                 .reg = {
 542                                         .addr = 0x10,
 543                                         .mask = GENMASK(7, 4),
 544                                 },
 545                                 .odr_avl[0] = {  13, 0x01 },
 546                                 .odr_avl[1] = {  26, 0x02 },
 547                                 .odr_avl[2] = {  52, 0x03 },
 548                                 .odr_avl[3] = { 104, 0x04 },
 549                                 .odr_avl[4] = { 208, 0x05 },
 550                                 .odr_avl[5] = { 416, 0x06 },
 551                         },
 552                         [ST_LSM6DSX_ID_GYRO] = {
 553                                 .reg = {
 554                                         .addr = 0x11,
 555                                         .mask = GENMASK(7, 4),
 556                                 },
 557                                 .odr_avl[0] = {  13, 0x01 },
 558                                 .odr_avl[1] = {  26, 0x02 },
 559                                 .odr_avl[2] = {  52, 0x03 },
 560                                 .odr_avl[3] = { 104, 0x04 },
 561                                 .odr_avl[4] = { 208, 0x05 },
 562                                 .odr_avl[5] = { 416, 0x06 },
 563                         },
 564                 },
 565                 .fs_table = {
 566                         [ST_LSM6DSX_ID_ACC] = {
 567                                 .reg = {
 568                                         .addr = 0x10,
 569                                         .mask = GENMASK(3, 2),
 570                                 },
 571                                 .fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
 572                                 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
 573                                 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
 574                                 .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
 575                                 .fs_len = 4,
 576                         },
 577                         [ST_LSM6DSX_ID_GYRO] = {
 578                                 .reg = {
 579                                         .addr = 0x11,
 580                                         .mask = GENMASK(3, 2),
 581                                 },
 582                                 .fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
 583                                 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
 584                                 .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
 585                                 .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
 586                                 .fs_len = 4,
 587                         },
 588                 },
 589                 .batch = {
 590                         [ST_LSM6DSX_ID_ACC] = {
 591                                 .addr = 0x09,
 592                                 .mask = GENMASK(3, 0),
 593                         },
 594                         [ST_LSM6DSX_ID_GYRO] = {
 595                                 .addr = 0x09,
 596                                 .mask = GENMASK(7, 4),
 597                         },
 598                 },
 599                 .fifo_ops = {
 600                         .update_fifo = st_lsm6dsx_update_fifo,
 601                         .read_fifo = st_lsm6dsx_read_tagged_fifo,
 602                         .fifo_th = {
 603                                 .addr = 0x07,
 604                                 .mask = GENMASK(8, 0),
 605                         },
 606                         .fifo_diff = {
 607                                 .addr = 0x3a,
 608                                 .mask = GENMASK(9, 0),
 609                         },
 610                         .th_wl = 1,
 611                 },
 612                 .ts_settings = {
 613                         .timer_en = {
 614                                 .addr = 0x19,
 615                                 .mask = BIT(5),
 616                         },
 617                         .decimator = {
 618                                 .addr = 0x0a,
 619                                 .mask = GENMASK(7, 6),
 620                         },
 621                 },
 622                 .shub_settings = {
 623                         .page_mux = {
 624                                 .addr = 0x01,
 625                                 .mask = BIT(6),
 626                         },
 627                         .master_en = {
 628                                 .addr = 0x14,
 629                                 .mask = BIT(2),
 630                         },
 631                         .pullup_en = {
 632                                 .addr = 0x14,
 633                                 .mask = BIT(3),
 634                         },
 635                         .aux_sens = {
 636                                 .addr = 0x14,
 637                                 .mask = GENMASK(1, 0),
 638                         },
 639                         .wr_once = {
 640                                 .addr = 0x14,
 641                                 .mask = BIT(6),
 642                         },
 643                         .shub_out = 0x02,
 644                         .slv0_addr = 0x15,
 645                         .dw_slv0_addr = 0x21,
 646                         .batch_en = BIT(3),
 647                 }
 648         },
 649         {
 650                 .wai = 0x6b,
 651                 .int1_addr = 0x0d,
 652                 .int2_addr = 0x0e,
 653                 .reset_addr = 0x12,
 654                 .max_fifo_size = 512,
 655                 .id = {
 656                         {
 657                                 .hw_id = ST_ASM330LHH_ID,
 658                                 .name = ST_ASM330LHH_DEV_NAME,
 659                         },
 660                 },
 661                 .channels = {
 662                         [ST_LSM6DSX_ID_ACC] = {
 663                                 .chan = st_lsm6dsx_acc_channels,
 664                                 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
 665                         },
 666                         [ST_LSM6DSX_ID_GYRO] = {
 667                                 .chan = st_lsm6dsx_gyro_channels,
 668                                 .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
 669                         },
 670                 },
 671                 .odr_table = {
 672                         [ST_LSM6DSX_ID_ACC] = {
 673                                 .reg = {
 674                                         .addr = 0x10,
 675                                         .mask = GENMASK(7, 4),
 676                                 },
 677                                 .odr_avl[0] = {  13, 0x01 },
 678                                 .odr_avl[1] = {  26, 0x02 },
 679                                 .odr_avl[2] = {  52, 0x03 },
 680                                 .odr_avl[3] = { 104, 0x04 },
 681                                 .odr_avl[4] = { 208, 0x05 },
 682                                 .odr_avl[5] = { 416, 0x06 },
 683                         },
 684                         [ST_LSM6DSX_ID_GYRO] = {
 685                                 .reg = {
 686                                         .addr = 0x11,
 687                                         .mask = GENMASK(7, 4),
 688                                 },
 689                                 .odr_avl[0] = {  13, 0x01 },
 690                                 .odr_avl[1] = {  26, 0x02 },
 691                                 .odr_avl[2] = {  52, 0x03 },
 692                                 .odr_avl[3] = { 104, 0x04 },
 693                                 .odr_avl[4] = { 208, 0x05 },
 694                                 .odr_avl[5] = { 416, 0x06 },
 695                         },
 696                 },
 697                 .fs_table = {
 698                         [ST_LSM6DSX_ID_ACC] = {
 699                                 .reg = {
 700                                         .addr = 0x10,
 701                                         .mask = GENMASK(3, 2),
 702                                 },
 703                                 .fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
 704                                 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
 705                                 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
 706                                 .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
 707                                 .fs_len = 4,
 708                         },
 709                         [ST_LSM6DSX_ID_GYRO] = {
 710                                 .reg = {
 711                                         .addr = 0x11,
 712                                         .mask = GENMASK(3, 2),
 713                                 },
 714                                 .fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
 715                                 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
 716                                 .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
 717                                 .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
 718                                 .fs_len = 4,
 719                         },
 720                 },
 721                 .batch = {
 722                         [ST_LSM6DSX_ID_ACC] = {
 723                                 .addr = 0x09,
 724                                 .mask = GENMASK(3, 0),
 725                         },
 726                         [ST_LSM6DSX_ID_GYRO] = {
 727                                 .addr = 0x09,
 728                                 .mask = GENMASK(7, 4),
 729                         },
 730                 },
 731                 .fifo_ops = {
 732                         .update_fifo = st_lsm6dsx_update_fifo,
 733                         .read_fifo = st_lsm6dsx_read_tagged_fifo,
 734                         .fifo_th = {
 735                                 .addr = 0x07,
 736                                 .mask = GENMASK(8, 0),
 737                         },
 738                         .fifo_diff = {
 739                                 .addr = 0x3a,
 740                                 .mask = GENMASK(9, 0),
 741                         },
 742                         .th_wl = 1,
 743                 },
 744                 .ts_settings = {
 745                         .timer_en = {
 746                                 .addr = 0x19,
 747                                 .mask = BIT(5),
 748                         },
 749                         .decimator = {
 750                                 .addr = 0x0a,
 751                                 .mask = GENMASK(7, 6),
 752                         },
 753                 },
 754         },
 755         {
 756                 .wai = 0x6b,
 757                 .int1_addr = 0x0d,
 758                 .int2_addr = 0x0e,
 759                 .reset_addr = 0x12,
 760                 .max_fifo_size = 512,
 761                 .id = {
 762                         {
 763                                 .hw_id = ST_LSM6DSR_ID,
 764                                 .name = ST_LSM6DSR_DEV_NAME,
 765                         }, {
 766                                 .hw_id = ST_ISM330DHCX_ID,
 767                                 .name = ST_ISM330DHCX_DEV_NAME,
 768                         },
 769                 },
 770                 .channels = {
 771                         [ST_LSM6DSX_ID_ACC] = {
 772                                 .chan = st_lsm6dsx_acc_channels,
 773                                 .len = ARRAY_SIZE(st_lsm6dsx_acc_channels),
 774                         },
 775                         [ST_LSM6DSX_ID_GYRO] = {
 776                                 .chan = st_lsm6dsx_gyro_channels,
 777                                 .len = ARRAY_SIZE(st_lsm6dsx_gyro_channels),
 778                         },
 779                 },
 780                 .odr_table = {
 781                         [ST_LSM6DSX_ID_ACC] = {
 782                                 .reg = {
 783                                         .addr = 0x10,
 784                                         .mask = GENMASK(7, 4),
 785                                 },
 786                                 .odr_avl[0] = {  13, 0x01 },
 787                                 .odr_avl[1] = {  26, 0x02 },
 788                                 .odr_avl[2] = {  52, 0x03 },
 789                                 .odr_avl[3] = { 104, 0x04 },
 790                                 .odr_avl[4] = { 208, 0x05 },
 791                                 .odr_avl[5] = { 416, 0x06 },
 792                         },
 793                         [ST_LSM6DSX_ID_GYRO] = {
 794                                 .reg = {
 795                                         .addr = 0x11,
 796                                         .mask = GENMASK(7, 4),
 797                                 },
 798                                 .odr_avl[0] = {  13, 0x01 },
 799                                 .odr_avl[1] = {  26, 0x02 },
 800                                 .odr_avl[2] = {  52, 0x03 },
 801                                 .odr_avl[3] = { 104, 0x04 },
 802                                 .odr_avl[4] = { 208, 0x05 },
 803                                 .odr_avl[5] = { 416, 0x06 },
 804                         },
 805                 },
 806                 .fs_table = {
 807                         [ST_LSM6DSX_ID_ACC] = {
 808                                 .reg = {
 809                                         .addr = 0x10,
 810                                         .mask = GENMASK(3, 2),
 811                                 },
 812                                 .fs_avl[0] = {  IIO_G_TO_M_S_2(61), 0x0 },
 813                                 .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 },
 814                                 .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 },
 815                                 .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 },
 816                                 .fs_len = 4,
 817                         },
 818                         [ST_LSM6DSX_ID_GYRO] = {
 819                                 .reg = {
 820                                         .addr = 0x11,
 821                                         .mask = GENMASK(3, 2),
 822                                 },
 823                                 .fs_avl[0] = {  IIO_DEGREE_TO_RAD(8750), 0x0 },
 824                                 .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 },
 825                                 .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 },
 826                                 .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 },
 827                                 .fs_len = 4,
 828                         },
 829                 },
 830                 .batch = {
 831                         [ST_LSM6DSX_ID_ACC] = {
 832                                 .addr = 0x09,
 833                                 .mask = GENMASK(3, 0),
 834                         },
 835                         [ST_LSM6DSX_ID_GYRO] = {
 836                                 .addr = 0x09,
 837                                 .mask = GENMASK(7, 4),
 838                         },
 839                 },
 840                 .fifo_ops = {
 841                         .update_fifo = st_lsm6dsx_update_fifo,
 842                         .read_fifo = st_lsm6dsx_read_tagged_fifo,
 843                         .fifo_th = {
 844                                 .addr = 0x07,
 845                                 .mask = GENMASK(8, 0),
 846                         },
 847                         .fifo_diff = {
 848                                 .addr = 0x3a,
 849                                 .mask = GENMASK(9, 0),
 850                         },
 851                         .th_wl = 1,
 852                 },
 853                 .ts_settings = {
 854                         .timer_en = {
 855                                 .addr = 0x19,
 856                                 .mask = BIT(5),
 857                         },
 858                         .decimator = {
 859                                 .addr = 0x0a,
 860                                 .mask = GENMASK(7, 6),
 861                         },
 862                 },
 863                 .shub_settings = {
 864                         .page_mux = {
 865                                 .addr = 0x01,
 866                                 .mask = BIT(6),
 867                         },
 868                         .master_en = {
 869                                 .addr = 0x14,
 870                                 .mask = BIT(2),
 871                         },
 872                         .pullup_en = {
 873                                 .addr = 0x14,
 874                                 .mask = BIT(3),
 875                         },
 876                         .aux_sens = {
 877                                 .addr = 0x14,
 878                                 .mask = GENMASK(1, 0),
 879                         },
 880                         .wr_once = {
 881                                 .addr = 0x14,
 882                                 .mask = BIT(6),
 883                         },
 884                         .shub_out = 0x02,
 885                         .slv0_addr = 0x15,
 886                         .dw_slv0_addr = 0x21,
 887                         .batch_en = BIT(3),
 888                 }
 889         },
 890 };
 891 
 892 int st_lsm6dsx_set_page(struct st_lsm6dsx_hw *hw, bool enable)
 893 {
 894         const struct st_lsm6dsx_shub_settings *hub_settings;
 895         unsigned int data;
 896         int err;
 897 
 898         hub_settings = &hw->settings->shub_settings;
 899         data = ST_LSM6DSX_SHIFT_VAL(enable, hub_settings->page_mux.mask);
 900         err = regmap_update_bits(hw->regmap, hub_settings->page_mux.addr,
 901                                  hub_settings->page_mux.mask, data);
 902         usleep_range(100, 150);
 903 
 904         return err;
 905 }
 906 
 907 static int st_lsm6dsx_check_whoami(struct st_lsm6dsx_hw *hw, int id,
 908                                    const char **name)
 909 {
 910         int err, i, j, data;
 911 
 912         for (i = 0; i < ARRAY_SIZE(st_lsm6dsx_sensor_settings); i++) {
 913                 for (j = 0; j < ST_LSM6DSX_MAX_ID; j++) {
 914                         if (st_lsm6dsx_sensor_settings[i].id[j].name &&
 915                             id == st_lsm6dsx_sensor_settings[i].id[j].hw_id)
 916                                 break;
 917                 }
 918                 if (j < ST_LSM6DSX_MAX_ID)
 919                         break;
 920         }
 921 
 922         if (i == ARRAY_SIZE(st_lsm6dsx_sensor_settings)) {
 923                 dev_err(hw->dev, "unsupported hw id [%02x]\n", id);
 924                 return -ENODEV;
 925         }
 926 
 927         err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
 928         if (err < 0) {
 929                 dev_err(hw->dev, "failed to read whoami register\n");
 930                 return err;
 931         }
 932 
 933         if (data != st_lsm6dsx_sensor_settings[i].wai) {
 934                 dev_err(hw->dev, "unsupported whoami [%02x]\n", data);
 935                 return -ENODEV;
 936         }
 937 
 938         *name = st_lsm6dsx_sensor_settings[i].id[j].name;
 939         hw->settings = &st_lsm6dsx_sensor_settings[i];
 940 
 941         return 0;
 942 }
 943 
 944 static int st_lsm6dsx_set_full_scale(struct st_lsm6dsx_sensor *sensor,
 945                                      u32 gain)
 946 {
 947         const struct st_lsm6dsx_fs_table_entry *fs_table;
 948         unsigned int data;
 949         int i, err;
 950 
 951         fs_table = &sensor->hw->settings->fs_table[sensor->id];
 952         for (i = 0; i < fs_table->fs_len; i++) {
 953                 if (fs_table->fs_avl[i].gain == gain)
 954                         break;
 955         }
 956 
 957         if (i == fs_table->fs_len)
 958                 return -EINVAL;
 959 
 960         data = ST_LSM6DSX_SHIFT_VAL(fs_table->fs_avl[i].val,
 961                                     fs_table->reg.mask);
 962         err = st_lsm6dsx_update_bits_locked(sensor->hw, fs_table->reg.addr,
 963                                             fs_table->reg.mask, data);
 964         if (err < 0)
 965                 return err;
 966 
 967         sensor->gain = gain;
 968 
 969         return 0;
 970 }
 971 
 972 int st_lsm6dsx_check_odr(struct st_lsm6dsx_sensor *sensor, u16 odr, u8 *val)
 973 {
 974         const struct st_lsm6dsx_odr_table_entry *odr_table;
 975         int i;
 976 
 977         odr_table = &sensor->hw->settings->odr_table[sensor->id];
 978         for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
 979                 /*
 980                  * ext devices can run at different odr respect to
 981                  * accel sensor
 982                  */
 983                 if (odr_table->odr_avl[i].hz >= odr)
 984                         break;
 985 
 986         if (i == ST_LSM6DSX_ODR_LIST_SIZE)
 987                 return -EINVAL;
 988 
 989         *val = odr_table->odr_avl[i].val;
 990         return odr_table->odr_avl[i].hz;
 991 }
 992 
 993 static u16 st_lsm6dsx_check_odr_dependency(struct st_lsm6dsx_hw *hw, u16 odr,
 994                                            enum st_lsm6dsx_sensor_id id)
 995 {
 996         struct st_lsm6dsx_sensor *ref = iio_priv(hw->iio_devs[id]);
 997 
 998         if (odr > 0) {
 999                 if (hw->enable_mask & BIT(id))
1000                         return max_t(u16, ref->odr, odr);
1001                 else
1002                         return odr;
1003         } else {
1004                 return (hw->enable_mask & BIT(id)) ? ref->odr : 0;
1005         }
1006 }
1007 
1008 static int st_lsm6dsx_set_odr(struct st_lsm6dsx_sensor *sensor, u16 req_odr)
1009 {
1010         struct st_lsm6dsx_sensor *ref_sensor = sensor;
1011         struct st_lsm6dsx_hw *hw = sensor->hw;
1012         const struct st_lsm6dsx_reg *reg;
1013         unsigned int data;
1014         u8 val = 0;
1015         int err;
1016 
1017         switch (sensor->id) {
1018         case ST_LSM6DSX_ID_EXT0:
1019         case ST_LSM6DSX_ID_EXT1:
1020         case ST_LSM6DSX_ID_EXT2:
1021         case ST_LSM6DSX_ID_ACC: {
1022                 u16 odr;
1023                 int i;
1024 
1025                 /*
1026                  * i2c embedded controller relies on the accelerometer sensor as
1027                  * bus read/write trigger so we need to enable accel device
1028                  * at odr = max(accel_odr, ext_odr) in order to properly
1029                  * communicate with i2c slave devices
1030                  */
1031                 ref_sensor = iio_priv(hw->iio_devs[ST_LSM6DSX_ID_ACC]);
1032                 for (i = ST_LSM6DSX_ID_ACC; i < ST_LSM6DSX_ID_MAX; i++) {
1033                         if (!hw->iio_devs[i] || i == sensor->id)
1034                                 continue;
1035 
1036                         odr = st_lsm6dsx_check_odr_dependency(hw, req_odr, i);
1037                         if (odr != req_odr)
1038                                 /* device already configured */
1039                                 return 0;
1040                 }
1041                 break;
1042         }
1043         default:
1044                 break;
1045         }
1046 
1047         if (req_odr > 0) {
1048                 err = st_lsm6dsx_check_odr(ref_sensor, req_odr, &val);
1049                 if (err < 0)
1050                         return err;
1051         }
1052 
1053         reg = &hw->settings->odr_table[ref_sensor->id].reg;
1054         data = ST_LSM6DSX_SHIFT_VAL(val, reg->mask);
1055         return st_lsm6dsx_update_bits_locked(hw, reg->addr, reg->mask, data);
1056 }
1057 
1058 int st_lsm6dsx_sensor_set_enable(struct st_lsm6dsx_sensor *sensor,
1059                                  bool enable)
1060 {
1061         struct st_lsm6dsx_hw *hw = sensor->hw;
1062         u16 odr = enable ? sensor->odr : 0;
1063         int err;
1064 
1065         err = st_lsm6dsx_set_odr(sensor, odr);
1066         if (err < 0)
1067                 return err;
1068 
1069         if (enable)
1070                 hw->enable_mask |= BIT(sensor->id);
1071         else
1072                 hw->enable_mask &= ~BIT(sensor->id);
1073 
1074         return 0;
1075 }
1076 
1077 static int st_lsm6dsx_read_oneshot(struct st_lsm6dsx_sensor *sensor,
1078                                    u8 addr, int *val)
1079 {
1080         struct st_lsm6dsx_hw *hw = sensor->hw;
1081         int err, delay;
1082         __le16 data;
1083 
1084         err = st_lsm6dsx_sensor_set_enable(sensor, true);
1085         if (err < 0)
1086                 return err;
1087 
1088         delay = 1000000 / sensor->odr;
1089         usleep_range(delay, 2 * delay);
1090 
1091         err = st_lsm6dsx_read_locked(hw, addr, &data, sizeof(data));
1092         if (err < 0)
1093                 return err;
1094 
1095         st_lsm6dsx_sensor_set_enable(sensor, false);
1096 
1097         *val = (s16)le16_to_cpu(data);
1098 
1099         return IIO_VAL_INT;
1100 }
1101 
1102 static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev,
1103                                struct iio_chan_spec const *ch,
1104                                int *val, int *val2, long mask)
1105 {
1106         struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1107         int ret;
1108 
1109         switch (mask) {
1110         case IIO_CHAN_INFO_RAW:
1111                 ret = iio_device_claim_direct_mode(iio_dev);
1112                 if (ret)
1113                         break;
1114 
1115                 ret = st_lsm6dsx_read_oneshot(sensor, ch->address, val);
1116                 iio_device_release_direct_mode(iio_dev);
1117                 break;
1118         case IIO_CHAN_INFO_SAMP_FREQ:
1119                 *val = sensor->odr;
1120                 ret = IIO_VAL_INT;
1121                 break;
1122         case IIO_CHAN_INFO_SCALE:
1123                 *val = 0;
1124                 *val2 = sensor->gain;
1125                 ret = IIO_VAL_INT_PLUS_MICRO;
1126                 break;
1127         default:
1128                 ret = -EINVAL;
1129                 break;
1130         }
1131 
1132         return ret;
1133 }
1134 
1135 static int st_lsm6dsx_write_raw(struct iio_dev *iio_dev,
1136                                 struct iio_chan_spec const *chan,
1137                                 int val, int val2, long mask)
1138 {
1139         struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1140         int err;
1141 
1142         err = iio_device_claim_direct_mode(iio_dev);
1143         if (err)
1144                 return err;
1145 
1146         switch (mask) {
1147         case IIO_CHAN_INFO_SCALE:
1148                 err = st_lsm6dsx_set_full_scale(sensor, val2);
1149                 break;
1150         case IIO_CHAN_INFO_SAMP_FREQ: {
1151                 u8 data;
1152 
1153                 val = st_lsm6dsx_check_odr(sensor, val, &data);
1154                 if (val < 0)
1155                         err = val;
1156                 else
1157                         sensor->odr = val;
1158                 break;
1159         }
1160         default:
1161                 err = -EINVAL;
1162                 break;
1163         }
1164 
1165         iio_device_release_direct_mode(iio_dev);
1166 
1167         return err;
1168 }
1169 
1170 int st_lsm6dsx_set_watermark(struct iio_dev *iio_dev, unsigned int val)
1171 {
1172         struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev);
1173         struct st_lsm6dsx_hw *hw = sensor->hw;
1174         int err;
1175 
1176         if (val < 1 || val > hw->settings->max_fifo_size)
1177                 return -EINVAL;
1178 
1179         mutex_lock(&hw->conf_lock);
1180 
1181         err = st_lsm6dsx_update_watermark(sensor, val);
1182 
1183         mutex_unlock(&hw->conf_lock);
1184 
1185         if (err < 0)
1186                 return err;
1187 
1188         sensor->watermark = val;
1189 
1190         return 0;
1191 }
1192 
1193 static ssize_t
1194 st_lsm6dsx_sysfs_sampling_frequency_avail(struct device *dev,
1195                                           struct device_attribute *attr,
1196                                           char *buf)
1197 {
1198         struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
1199         enum st_lsm6dsx_sensor_id id = sensor->id;
1200         struct st_lsm6dsx_hw *hw = sensor->hw;
1201         int i, len = 0;
1202 
1203         for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++)
1204                 len += scnprintf(buf + len, PAGE_SIZE - len, "%d ",
1205                                  hw->settings->odr_table[id].odr_avl[i].hz);
1206         buf[len - 1] = '\n';
1207 
1208         return len;
1209 }
1210 
1211 static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev,
1212                                             struct device_attribute *attr,
1213                                             char *buf)
1214 {
1215         struct st_lsm6dsx_sensor *sensor = iio_priv(dev_get_drvdata(dev));
1216         const struct st_lsm6dsx_fs_table_entry *fs_table;
1217         struct st_lsm6dsx_hw *hw = sensor->hw;
1218         int i, len = 0;
1219 
1220         fs_table = &hw->settings->fs_table[sensor->id];
1221         for (i = 0; i < fs_table->fs_len; i++)
1222                 len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
1223                                  fs_table->fs_avl[i].gain);
1224         buf[len - 1] = '\n';
1225 
1226         return len;
1227 }
1228 
1229 static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail);
1230 static IIO_DEVICE_ATTR(in_accel_scale_available, 0444,
1231                        st_lsm6dsx_sysfs_scale_avail, NULL, 0);
1232 static IIO_DEVICE_ATTR(in_anglvel_scale_available, 0444,
1233                        st_lsm6dsx_sysfs_scale_avail, NULL, 0);
1234 
1235 static struct attribute *st_lsm6dsx_acc_attributes[] = {
1236         &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1237         &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
1238         NULL,
1239 };
1240 
1241 static const struct attribute_group st_lsm6dsx_acc_attribute_group = {
1242         .attrs = st_lsm6dsx_acc_attributes,
1243 };
1244 
1245 static const struct iio_info st_lsm6dsx_acc_info = {
1246         .attrs = &st_lsm6dsx_acc_attribute_group,
1247         .read_raw = st_lsm6dsx_read_raw,
1248         .write_raw = st_lsm6dsx_write_raw,
1249         .hwfifo_set_watermark = st_lsm6dsx_set_watermark,
1250 };
1251 
1252 static struct attribute *st_lsm6dsx_gyro_attributes[] = {
1253         &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1254         &iio_dev_attr_in_anglvel_scale_available.dev_attr.attr,
1255         NULL,
1256 };
1257 
1258 static const struct attribute_group st_lsm6dsx_gyro_attribute_group = {
1259         .attrs = st_lsm6dsx_gyro_attributes,
1260 };
1261 
1262 static const struct iio_info st_lsm6dsx_gyro_info = {
1263         .attrs = &st_lsm6dsx_gyro_attribute_group,
1264         .read_raw = st_lsm6dsx_read_raw,
1265         .write_raw = st_lsm6dsx_write_raw,
1266         .hwfifo_set_watermark = st_lsm6dsx_set_watermark,
1267 };
1268 
1269 static int st_lsm6dsx_of_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin)
1270 {
1271         struct device_node *np = hw->dev->of_node;
1272 
1273         if (!np)
1274                 return -EINVAL;
1275 
1276         return of_property_read_u32(np, "st,drdy-int-pin", drdy_pin);
1277 }
1278 
1279 static int st_lsm6dsx_get_drdy_reg(struct st_lsm6dsx_hw *hw, u8 *drdy_reg)
1280 {
1281         int err = 0, drdy_pin;
1282 
1283         if (st_lsm6dsx_of_get_drdy_pin(hw, &drdy_pin) < 0) {
1284                 struct st_sensors_platform_data *pdata;
1285                 struct device *dev = hw->dev;
1286 
1287                 pdata = (struct st_sensors_platform_data *)dev->platform_data;
1288                 drdy_pin = pdata ? pdata->drdy_int_pin : 1;
1289         }
1290 
1291         switch (drdy_pin) {
1292         case 1:
1293                 *drdy_reg = hw->settings->int1_addr;
1294                 break;
1295         case 2:
1296                 *drdy_reg = hw->settings->int2_addr;
1297                 break;
1298         default:
1299                 dev_err(hw->dev, "unsupported data ready pin\n");
1300                 err = -EINVAL;
1301                 break;
1302         }
1303 
1304         return err;
1305 }
1306 
1307 static int st_lsm6dsx_init_shub(struct st_lsm6dsx_hw *hw)
1308 {
1309         const struct st_lsm6dsx_shub_settings *hub_settings;
1310         struct device_node *np = hw->dev->of_node;
1311         struct st_sensors_platform_data *pdata;
1312         unsigned int data;
1313         int err = 0;
1314 
1315         hub_settings = &hw->settings->shub_settings;
1316 
1317         pdata = (struct st_sensors_platform_data *)hw->dev->platform_data;
1318         if ((np && of_property_read_bool(np, "st,pullups")) ||
1319             (pdata && pdata->pullups)) {
1320                 err = st_lsm6dsx_set_page(hw, true);
1321                 if (err < 0)
1322                         return err;
1323 
1324                 data = ST_LSM6DSX_SHIFT_VAL(1, hub_settings->pullup_en.mask);
1325                 err = regmap_update_bits(hw->regmap,
1326                                          hub_settings->pullup_en.addr,
1327                                          hub_settings->pullup_en.mask, data);
1328 
1329                 st_lsm6dsx_set_page(hw, false);
1330 
1331                 if (err < 0)
1332                         return err;
1333         }
1334 
1335         if (hub_settings->aux_sens.addr) {
1336                 /* configure aux sensors */
1337                 err = st_lsm6dsx_set_page(hw, true);
1338                 if (err < 0)
1339                         return err;
1340 
1341                 data = ST_LSM6DSX_SHIFT_VAL(3, hub_settings->aux_sens.mask);
1342                 err = regmap_update_bits(hw->regmap,
1343                                          hub_settings->aux_sens.addr,
1344                                          hub_settings->aux_sens.mask, data);
1345 
1346                 st_lsm6dsx_set_page(hw, false);
1347         }
1348 
1349         return err;
1350 }
1351 
1352 static int st_lsm6dsx_init_hw_timer(struct st_lsm6dsx_hw *hw)
1353 {
1354         const struct st_lsm6dsx_hw_ts_settings *ts_settings;
1355         int err, val;
1356 
1357         ts_settings = &hw->settings->ts_settings;
1358         /* enable hw timestamp generation if necessary */
1359         if (ts_settings->timer_en.addr) {
1360                 val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->timer_en.mask);
1361                 err = regmap_update_bits(hw->regmap,
1362                                          ts_settings->timer_en.addr,
1363                                          ts_settings->timer_en.mask, val);
1364                 if (err < 0)
1365                         return err;
1366         }
1367 
1368         /* enable high resolution for hw ts timer if necessary */
1369         if (ts_settings->hr_timer.addr) {
1370                 val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->hr_timer.mask);
1371                 err = regmap_update_bits(hw->regmap,
1372                                          ts_settings->hr_timer.addr,
1373                                          ts_settings->hr_timer.mask, val);
1374                 if (err < 0)
1375                         return err;
1376         }
1377 
1378         /* enable ts queueing in FIFO if necessary */
1379         if (ts_settings->fifo_en.addr) {
1380                 val = ST_LSM6DSX_SHIFT_VAL(1, ts_settings->fifo_en.mask);
1381                 err = regmap_update_bits(hw->regmap,
1382                                          ts_settings->fifo_en.addr,
1383                                          ts_settings->fifo_en.mask, val);
1384                 if (err < 0)
1385                         return err;
1386         }
1387         return 0;
1388 }
1389 
1390 static int st_lsm6dsx_init_device(struct st_lsm6dsx_hw *hw)
1391 {
1392         u8 drdy_int_reg;
1393         int err;
1394 
1395         /* device sw reset */
1396         err = regmap_update_bits(hw->regmap, hw->settings->reset_addr,
1397                                  ST_LSM6DSX_REG_RESET_MASK,
1398                                  FIELD_PREP(ST_LSM6DSX_REG_RESET_MASK, 1));
1399         if (err < 0)
1400                 return err;
1401 
1402         msleep(50);
1403 
1404         /* reload trimming parameter */
1405         err = regmap_update_bits(hw->regmap, hw->settings->reset_addr,
1406                                  ST_LSM6DSX_REG_BOOT_MASK,
1407                                  FIELD_PREP(ST_LSM6DSX_REG_BOOT_MASK, 1));
1408         if (err < 0)
1409                 return err;
1410 
1411         msleep(50);
1412 
1413         /* enable Block Data Update */
1414         err = regmap_update_bits(hw->regmap, ST_LSM6DSX_REG_BDU_ADDR,
1415                                  ST_LSM6DSX_REG_BDU_MASK,
1416                                  FIELD_PREP(ST_LSM6DSX_REG_BDU_MASK, 1));
1417         if (err < 0)
1418                 return err;
1419 
1420         /* enable FIFO watermak interrupt */
1421         err = st_lsm6dsx_get_drdy_reg(hw, &drdy_int_reg);
1422         if (err < 0)
1423                 return err;
1424 
1425         err = regmap_update_bits(hw->regmap, drdy_int_reg,
1426                                  ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK,
1427                                  FIELD_PREP(ST_LSM6DSX_REG_FIFO_FTH_IRQ_MASK,
1428                                             1));
1429         if (err < 0)
1430                 return err;
1431 
1432         err = st_lsm6dsx_init_shub(hw);
1433         if (err < 0)
1434                 return err;
1435 
1436         return st_lsm6dsx_init_hw_timer(hw);
1437 }
1438 
1439 static struct iio_dev *st_lsm6dsx_alloc_iiodev(struct st_lsm6dsx_hw *hw,
1440                                                enum st_lsm6dsx_sensor_id id,
1441                                                const char *name)
1442 {
1443         struct st_lsm6dsx_sensor *sensor;
1444         struct iio_dev *iio_dev;
1445 
1446         iio_dev = devm_iio_device_alloc(hw->dev, sizeof(*sensor));
1447         if (!iio_dev)
1448                 return NULL;
1449 
1450         iio_dev->modes = INDIO_DIRECT_MODE;
1451         iio_dev->dev.parent = hw->dev;
1452         iio_dev->available_scan_masks = st_lsm6dsx_available_scan_masks;
1453         iio_dev->channels = hw->settings->channels[id].chan;
1454         iio_dev->num_channels = hw->settings->channels[id].len;
1455 
1456         sensor = iio_priv(iio_dev);
1457         sensor->id = id;
1458         sensor->hw = hw;
1459         sensor->odr = hw->settings->odr_table[id].odr_avl[0].hz;
1460         sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain;
1461         sensor->watermark = 1;
1462 
1463         switch (id) {
1464         case ST_LSM6DSX_ID_ACC:
1465                 iio_dev->info = &st_lsm6dsx_acc_info;
1466                 scnprintf(sensor->name, sizeof(sensor->name), "%s_accel",
1467                           name);
1468                 break;
1469         case ST_LSM6DSX_ID_GYRO:
1470                 iio_dev->info = &st_lsm6dsx_gyro_info;
1471                 scnprintf(sensor->name, sizeof(sensor->name), "%s_gyro",
1472                           name);
1473                 break;
1474         default:
1475                 return NULL;
1476         }
1477         iio_dev->name = sensor->name;
1478 
1479         return iio_dev;
1480 }
1481 
1482 int st_lsm6dsx_probe(struct device *dev, int irq, int hw_id,
1483                      struct regmap *regmap)
1484 {
1485         const struct st_lsm6dsx_shub_settings *hub_settings;
1486         struct st_lsm6dsx_hw *hw;
1487         const char *name = NULL;
1488         int i, err;
1489 
1490         hw = devm_kzalloc(dev, sizeof(*hw), GFP_KERNEL);
1491         if (!hw)
1492                 return -ENOMEM;
1493 
1494         dev_set_drvdata(dev, (void *)hw);
1495 
1496         mutex_init(&hw->fifo_lock);
1497         mutex_init(&hw->conf_lock);
1498         mutex_init(&hw->page_lock);
1499 
1500         hw->buff = devm_kzalloc(dev, ST_LSM6DSX_BUFF_SIZE, GFP_KERNEL);
1501         if (!hw->buff)
1502                 return -ENOMEM;
1503 
1504         hw->dev = dev;
1505         hw->irq = irq;
1506         hw->regmap = regmap;
1507 
1508         err = st_lsm6dsx_check_whoami(hw, hw_id, &name);
1509         if (err < 0)
1510                 return err;
1511 
1512         for (i = 0; i < ST_LSM6DSX_ID_EXT0; i++) {
1513                 hw->iio_devs[i] = st_lsm6dsx_alloc_iiodev(hw, i, name);
1514                 if (!hw->iio_devs[i])
1515                         return -ENOMEM;
1516         }
1517 
1518         err = st_lsm6dsx_init_device(hw);
1519         if (err < 0)
1520                 return err;
1521 
1522         hub_settings = &hw->settings->shub_settings;
1523         if (hub_settings->master_en.addr) {
1524                 err = st_lsm6dsx_shub_probe(hw, name);
1525                 if (err < 0)
1526                         return err;
1527         }
1528 
1529         if (hw->irq > 0) {
1530                 err = st_lsm6dsx_fifo_setup(hw);
1531                 if (err < 0)
1532                         return err;
1533         }
1534 
1535         for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
1536                 if (!hw->iio_devs[i])
1537                         continue;
1538 
1539                 err = devm_iio_device_register(hw->dev, hw->iio_devs[i]);
1540                 if (err)
1541                         return err;
1542         }
1543 
1544         return 0;
1545 }
1546 EXPORT_SYMBOL(st_lsm6dsx_probe);
1547 
1548 static int __maybe_unused st_lsm6dsx_suspend(struct device *dev)
1549 {
1550         struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
1551         struct st_lsm6dsx_sensor *sensor;
1552         int i, err = 0;
1553 
1554         for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
1555                 if (!hw->iio_devs[i])
1556                         continue;
1557 
1558                 sensor = iio_priv(hw->iio_devs[i]);
1559                 if (!(hw->enable_mask & BIT(sensor->id)))
1560                         continue;
1561 
1562                 if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
1563                     sensor->id == ST_LSM6DSX_ID_EXT1 ||
1564                     sensor->id == ST_LSM6DSX_ID_EXT2)
1565                         err = st_lsm6dsx_shub_set_enable(sensor, false);
1566                 else
1567                         err = st_lsm6dsx_sensor_set_enable(sensor, false);
1568                 if (err < 0)
1569                         return err;
1570 
1571                 hw->suspend_mask |= BIT(sensor->id);
1572         }
1573 
1574         if (hw->fifo_mode != ST_LSM6DSX_FIFO_BYPASS)
1575                 err = st_lsm6dsx_flush_fifo(hw);
1576 
1577         return err;
1578 }
1579 
1580 static int __maybe_unused st_lsm6dsx_resume(struct device *dev)
1581 {
1582         struct st_lsm6dsx_hw *hw = dev_get_drvdata(dev);
1583         struct st_lsm6dsx_sensor *sensor;
1584         int i, err = 0;
1585 
1586         for (i = 0; i < ST_LSM6DSX_ID_MAX; i++) {
1587                 if (!hw->iio_devs[i])
1588                         continue;
1589 
1590                 sensor = iio_priv(hw->iio_devs[i]);
1591                 if (!(hw->suspend_mask & BIT(sensor->id)))
1592                         continue;
1593 
1594                 if (sensor->id == ST_LSM6DSX_ID_EXT0 ||
1595                     sensor->id == ST_LSM6DSX_ID_EXT1 ||
1596                     sensor->id == ST_LSM6DSX_ID_EXT2)
1597                         err = st_lsm6dsx_shub_set_enable(sensor, true);
1598                 else
1599                         err = st_lsm6dsx_sensor_set_enable(sensor, true);
1600                 if (err < 0)
1601                         return err;
1602 
1603                 hw->suspend_mask &= ~BIT(sensor->id);
1604         }
1605 
1606         if (hw->enable_mask)
1607                 err = st_lsm6dsx_set_fifo_mode(hw, ST_LSM6DSX_FIFO_CONT);
1608 
1609         return err;
1610 }
1611 
1612 const struct dev_pm_ops st_lsm6dsx_pm_ops = {
1613         SET_SYSTEM_SLEEP_PM_OPS(st_lsm6dsx_suspend, st_lsm6dsx_resume)
1614 };
1615 EXPORT_SYMBOL(st_lsm6dsx_pm_ops);
1616 
1617 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo.bianconi@st.com>");
1618 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
1619 MODULE_DESCRIPTION("STMicroelectronics st_lsm6dsx driver");
1620 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */