linux/drivers/iio/accel/st_accel_core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * STMicroelectronics accelerometers driver
   4 *
   5 * Copyright 2012-2013 STMicroelectronics Inc.
   6 *
   7 * Denis Ciocca <denis.ciocca@st.com>
   8 */
   9
  10#include <linux/kernel.h>
  11#include <linux/module.h>
  12#include <linux/slab.h>
  13#include <linux/acpi.h>
  14#include <linux/errno.h>
  15#include <linux/types.h>
  16#include <linux/interrupt.h>
  17#include <linux/i2c.h>
  18#include <linux/irq.h>
  19#include <linux/iio/iio.h>
  20#include <linux/iio/sysfs.h>
  21#include <linux/iio/trigger.h>
  22#include <linux/iio/buffer.h>
  23
  24#include <linux/iio/common/st_sensors.h>
  25#include "st_accel.h"
  26
  27#define ST_ACCEL_NUMBER_DATA_CHANNELS           3
  28
  29/* DEFAULT VALUE FOR SENSORS */
  30#define ST_ACCEL_DEFAULT_OUT_X_L_ADDR           0x28
  31#define ST_ACCEL_DEFAULT_OUT_Y_L_ADDR           0x2a
  32#define ST_ACCEL_DEFAULT_OUT_Z_L_ADDR           0x2c
  33
  34/* FULLSCALE */
  35#define ST_ACCEL_FS_AVL_2G                      2
  36#define ST_ACCEL_FS_AVL_4G                      4
  37#define ST_ACCEL_FS_AVL_6G                      6
  38#define ST_ACCEL_FS_AVL_8G                      8
  39#define ST_ACCEL_FS_AVL_16G                     16
  40#define ST_ACCEL_FS_AVL_100G                    100
  41#define ST_ACCEL_FS_AVL_200G                    200
  42#define ST_ACCEL_FS_AVL_400G                    400
  43
  44static const struct iio_mount_matrix *
  45st_accel_get_mount_matrix(const struct iio_dev *indio_dev,
  46                          const struct iio_chan_spec *chan)
  47{
  48        struct st_sensor_data *adata = iio_priv(indio_dev);
  49
  50        return &adata->mount_matrix;
  51}
  52
  53static const struct iio_chan_spec_ext_info st_accel_mount_matrix_ext_info[] = {
  54        IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, st_accel_get_mount_matrix),
  55        { }
  56};
  57
  58static const struct iio_chan_spec st_accel_8bit_channels[] = {
  59        ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL,
  60                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  61                        ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 8, 8,
  62                        ST_ACCEL_DEFAULT_OUT_X_L_ADDR+1,
  63                        st_accel_mount_matrix_ext_info),
  64        ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL,
  65                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  66                        ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 8, 8,
  67                        ST_ACCEL_DEFAULT_OUT_Y_L_ADDR+1,
  68                        st_accel_mount_matrix_ext_info),
  69        ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL,
  70                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  71                        ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 8, 8,
  72                        ST_ACCEL_DEFAULT_OUT_Z_L_ADDR+1,
  73                        st_accel_mount_matrix_ext_info),
  74        IIO_CHAN_SOFT_TIMESTAMP(3)
  75};
  76
  77static const struct iio_chan_spec st_accel_12bit_channels[] = {
  78        ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL,
  79                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  80                        ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 12, 16,
  81                        ST_ACCEL_DEFAULT_OUT_X_L_ADDR,
  82                        st_accel_mount_matrix_ext_info),
  83        ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL,
  84                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  85                        ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 12, 16,
  86                        ST_ACCEL_DEFAULT_OUT_Y_L_ADDR,
  87                        st_accel_mount_matrix_ext_info),
  88        ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL,
  89                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  90                        ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 12, 16,
  91                        ST_ACCEL_DEFAULT_OUT_Z_L_ADDR,
  92                        st_accel_mount_matrix_ext_info),
  93        IIO_CHAN_SOFT_TIMESTAMP(3)
  94};
  95
  96static const struct iio_chan_spec st_accel_16bit_channels[] = {
  97        ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL,
  98                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
  99                        ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
 100                        ST_ACCEL_DEFAULT_OUT_X_L_ADDR,
 101                        st_accel_mount_matrix_ext_info),
 102        ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL,
 103                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 104                        ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
 105                        ST_ACCEL_DEFAULT_OUT_Y_L_ADDR,
 106                        st_accel_mount_matrix_ext_info),
 107        ST_SENSORS_LSM_CHANNELS_EXT(IIO_ACCEL,
 108                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 109                        ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
 110                        ST_ACCEL_DEFAULT_OUT_Z_L_ADDR,
 111                        st_accel_mount_matrix_ext_info),
 112        IIO_CHAN_SOFT_TIMESTAMP(3)
 113};
 114
 115static const struct st_sensor_settings st_accel_sensors_settings[] = {
 116        {
 117                .wai = 0x33,
 118                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 119                .sensors_supported = {
 120                        [0] = LIS3DH_ACCEL_DEV_NAME,
 121                        [1] = LSM303DLHC_ACCEL_DEV_NAME,
 122                        [2] = LSM330D_ACCEL_DEV_NAME,
 123                        [3] = LSM330DL_ACCEL_DEV_NAME,
 124                        [4] = LSM330DLC_ACCEL_DEV_NAME,
 125                        [5] = LSM303AGR_ACCEL_DEV_NAME,
 126                        [6] = LIS2DH12_ACCEL_DEV_NAME,
 127                        [7] = LIS3DE_ACCEL_DEV_NAME,
 128                },
 129                .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
 130                .odr = {
 131                        .addr = 0x20,
 132                        .mask = 0xf0,
 133                        .odr_avl = {
 134                                { .hz = 1, .value = 0x01, },
 135                                { .hz = 10, .value = 0x02, },
 136                                { .hz = 25, .value = 0x03, },
 137                                { .hz = 50, .value = 0x04, },
 138                                { .hz = 100, .value = 0x05, },
 139                                { .hz = 200, .value = 0x06, },
 140                                { .hz = 400, .value = 0x07, },
 141                                { .hz = 1600, .value = 0x08, },
 142                        },
 143                },
 144                .pw = {
 145                        .addr = 0x20,
 146                        .mask = 0xf0,
 147                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 148                },
 149                .enable_axis = {
 150                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 151                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 152                },
 153                .fs = {
 154                        .addr = 0x23,
 155                        .mask = 0x30,
 156                        .fs_avl = {
 157                                [0] = {
 158                                        .num = ST_ACCEL_FS_AVL_2G,
 159                                        .value = 0x00,
 160                                        .gain = IIO_G_TO_M_S_2(1000),
 161                                },
 162                                [1] = {
 163                                        .num = ST_ACCEL_FS_AVL_4G,
 164                                        .value = 0x01,
 165                                        .gain = IIO_G_TO_M_S_2(2000),
 166                                },
 167                                [2] = {
 168                                        .num = ST_ACCEL_FS_AVL_8G,
 169                                        .value = 0x02,
 170                                        .gain = IIO_G_TO_M_S_2(4000),
 171                                },
 172                                [3] = {
 173                                        .num = ST_ACCEL_FS_AVL_16G,
 174                                        .value = 0x03,
 175                                        .gain = IIO_G_TO_M_S_2(12000),
 176                                },
 177                        },
 178                },
 179                .bdu = {
 180                        .addr = 0x23,
 181                        .mask = 0x80,
 182                },
 183                .drdy_irq = {
 184                        .int1 = {
 185                                .addr = 0x22,
 186                                .mask = 0x10,
 187                        },
 188                        .addr_ihl = 0x25,
 189                        .mask_ihl = 0x02,
 190                        .stat_drdy = {
 191                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 192                                .mask = 0x07,
 193                        },
 194                },
 195                .sim = {
 196                        .addr = 0x23,
 197                        .value = BIT(0),
 198                },
 199                .multi_read_bit = true,
 200                .bootime = 2,
 201        },
 202        {
 203                .wai = 0x32,
 204                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 205                .sensors_supported = {
 206                        [0] = LIS331DLH_ACCEL_DEV_NAME,
 207                        [1] = LSM303DL_ACCEL_DEV_NAME,
 208                        [2] = LSM303DLH_ACCEL_DEV_NAME,
 209                        [3] = LSM303DLM_ACCEL_DEV_NAME,
 210                },
 211                .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
 212                .odr = {
 213                        .addr = 0x20,
 214                        .mask = 0x18,
 215                        .odr_avl = {
 216                                { .hz = 50, .value = 0x00, },
 217                                { .hz = 100, .value = 0x01, },
 218                                { .hz = 400, .value = 0x02, },
 219                                { .hz = 1000, .value = 0x03, },
 220                        },
 221                },
 222                .pw = {
 223                        .addr = 0x20,
 224                        .mask = 0xe0,
 225                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 226                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 227                },
 228                .enable_axis = {
 229                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 230                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 231                },
 232                .fs = {
 233                        .addr = 0x23,
 234                        .mask = 0x30,
 235                        .fs_avl = {
 236                                [0] = {
 237                                        .num = ST_ACCEL_FS_AVL_2G,
 238                                        .value = 0x00,
 239                                        .gain = IIO_G_TO_M_S_2(1000),
 240                                },
 241                                [1] = {
 242                                        .num = ST_ACCEL_FS_AVL_4G,
 243                                        .value = 0x01,
 244                                        .gain = IIO_G_TO_M_S_2(2000),
 245                                },
 246                                [2] = {
 247                                        .num = ST_ACCEL_FS_AVL_8G,
 248                                        .value = 0x03,
 249                                        .gain = IIO_G_TO_M_S_2(3900),
 250                                },
 251                        },
 252                },
 253                .bdu = {
 254                        .addr = 0x23,
 255                        .mask = 0x80,
 256                },
 257                .drdy_irq = {
 258                        .int1 = {
 259                                .addr = 0x22,
 260                                .mask = 0x02,
 261                                .addr_od = 0x22,
 262                                .mask_od = 0x40,
 263                        },
 264                        .int2 = {
 265                                .addr = 0x22,
 266                                .mask = 0x10,
 267                                .addr_od = 0x22,
 268                                .mask_od = 0x40,
 269                        },
 270                        .addr_ihl = 0x22,
 271                        .mask_ihl = 0x80,
 272                        .stat_drdy = {
 273                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 274                                .mask = 0x07,
 275                        },
 276                },
 277                .sim = {
 278                        .addr = 0x23,
 279                        .value = BIT(0),
 280                },
 281                .multi_read_bit = true,
 282                .bootime = 2,
 283        },
 284        {
 285                .wai = 0x40,
 286                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 287                .sensors_supported = {
 288                        [0] = LSM330_ACCEL_DEV_NAME,
 289                },
 290                .ch = (struct iio_chan_spec *)st_accel_16bit_channels,
 291                .odr = {
 292                        .addr = 0x20,
 293                        .mask = 0xf0,
 294                        .odr_avl = {
 295                                { .hz = 3, .value = 0x01, },
 296                                { .hz = 6, .value = 0x02, },
 297                                { .hz = 12, .value = 0x03, },
 298                                { .hz = 25, .value = 0x04, },
 299                                { .hz = 50, .value = 0x05, },
 300                                { .hz = 100, .value = 0x06, },
 301                                { .hz = 200, .value = 0x07, },
 302                                { .hz = 400, .value = 0x08, },
 303                                { .hz = 800, .value = 0x09, },
 304                                { .hz = 1600, .value = 0x0a, },
 305                        },
 306                },
 307                .pw = {
 308                        .addr = 0x20,
 309                        .mask = 0xf0,
 310                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 311                },
 312                .enable_axis = {
 313                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 314                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 315                },
 316                .fs = {
 317                        .addr = 0x24,
 318                        .mask = 0x38,
 319                        .fs_avl = {
 320                                [0] = {
 321                                        .num = ST_ACCEL_FS_AVL_2G,
 322                                        .value = 0x00,
 323                                        .gain = IIO_G_TO_M_S_2(61),
 324                                },
 325                                [1] = {
 326                                        .num = ST_ACCEL_FS_AVL_4G,
 327                                        .value = 0x01,
 328                                        .gain = IIO_G_TO_M_S_2(122),
 329                                },
 330                                [2] = {
 331                                        .num = ST_ACCEL_FS_AVL_6G,
 332                                        .value = 0x02,
 333                                        .gain = IIO_G_TO_M_S_2(183),
 334                                },
 335                                [3] = {
 336                                        .num = ST_ACCEL_FS_AVL_8G,
 337                                        .value = 0x03,
 338                                        .gain = IIO_G_TO_M_S_2(244),
 339                                },
 340                                [4] = {
 341                                        .num = ST_ACCEL_FS_AVL_16G,
 342                                        .value = 0x04,
 343                                        .gain = IIO_G_TO_M_S_2(732),
 344                                },
 345                        },
 346                },
 347                .bdu = {
 348                        .addr = 0x20,
 349                        .mask = 0x08,
 350                },
 351                .drdy_irq = {
 352                        .int1 = {
 353                                .addr = 0x23,
 354                                .mask = 0x80,
 355                        },
 356                        .addr_ihl = 0x23,
 357                        .mask_ihl = 0x40,
 358                        .stat_drdy = {
 359                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 360                                .mask = 0x07,
 361                        },
 362                        .ig1 = {
 363                                .en_addr = 0x23,
 364                                .en_mask = 0x08,
 365                        },
 366                },
 367                .sim = {
 368                        .addr = 0x24,
 369                        .value = BIT(0),
 370                },
 371                .multi_read_bit = false,
 372                .bootime = 2,
 373        },
 374        {
 375                .wai = 0x3a,
 376                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 377                .sensors_supported = {
 378                        [0] = LIS3LV02DL_ACCEL_DEV_NAME,
 379                },
 380                .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
 381                .odr = {
 382                        .addr = 0x20,
 383                        .mask = 0x30, /* DF1 and DF0 */
 384                        .odr_avl = {
 385                                { .hz = 40, .value = 0x00, },
 386                                { .hz = 160, .value = 0x01, },
 387                                { .hz = 640, .value = 0x02, },
 388                                { .hz = 2560, .value = 0x03, },
 389                        },
 390                },
 391                .pw = {
 392                        .addr = 0x20,
 393                        .mask = 0xc0,
 394                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 395                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 396                },
 397                .enable_axis = {
 398                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 399                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 400                },
 401                .fs = {
 402                        .addr = 0x21,
 403                        .mask = 0x80,
 404                        .fs_avl = {
 405                                [0] = {
 406                                        .num = ST_ACCEL_FS_AVL_2G,
 407                                        .value = 0x00,
 408                                        .gain = IIO_G_TO_M_S_2(1000),
 409                                },
 410                                [1] = {
 411                                        .num = ST_ACCEL_FS_AVL_6G,
 412                                        .value = 0x01,
 413                                        .gain = IIO_G_TO_M_S_2(3000),
 414                                },
 415                        },
 416                },
 417                .bdu = {
 418                        .addr = 0x21,
 419                        .mask = 0x40,
 420                },
 421                /*
 422                 * Data Alignment Setting - needs to be set to get
 423                 * left-justified data like all other sensors.
 424                 */
 425                .das = {
 426                        .addr = 0x21,
 427                        .mask = 0x01,
 428                },
 429                .drdy_irq = {
 430                        .int1 = {
 431                                .addr = 0x21,
 432                                .mask = 0x04,
 433                        },
 434                        .stat_drdy = {
 435                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 436                                .mask = 0x07,
 437                        },
 438                },
 439                .sim = {
 440                        .addr = 0x21,
 441                        .value = BIT(1),
 442                },
 443                .multi_read_bit = true,
 444                .bootime = 2, /* guess */
 445        },
 446        {
 447                .wai = 0x3b,
 448                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 449                .sensors_supported = {
 450                        [0] = LIS331DL_ACCEL_DEV_NAME,
 451                },
 452                .ch = (struct iio_chan_spec *)st_accel_8bit_channels,
 453                .odr = {
 454                        .addr = 0x20,
 455                        .mask = 0x80,
 456                        .odr_avl = {
 457                                { .hz = 100, .value = 0x00, },
 458                                { .hz = 400, .value = 0x01, },
 459                        },
 460                },
 461                .pw = {
 462                        .addr = 0x20,
 463                        .mask = 0x40,
 464                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 465                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 466                },
 467                .enable_axis = {
 468                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 469                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 470                },
 471                .fs = {
 472                        .addr = 0x20,
 473                        .mask = 0x20,
 474                        /*
 475                         * TODO: check these resulting gain settings, these are
 476                         * not in the datsheet
 477                         */
 478                        .fs_avl = {
 479                                [0] = {
 480                                        .num = ST_ACCEL_FS_AVL_2G,
 481                                        .value = 0x00,
 482                                        .gain = IIO_G_TO_M_S_2(18000),
 483                                },
 484                                [1] = {
 485                                        .num = ST_ACCEL_FS_AVL_8G,
 486                                        .value = 0x01,
 487                                        .gain = IIO_G_TO_M_S_2(72000),
 488                                },
 489                        },
 490                },
 491                .drdy_irq = {
 492                        .int1 = {
 493                                .addr = 0x22,
 494                                .mask = 0x04,
 495                                .addr_od = 0x22,
 496                                .mask_od = 0x40,
 497                        },
 498                        .int2 = {
 499                                .addr = 0x22,
 500                                .mask = 0x20,
 501                                .addr_od = 0x22,
 502                                .mask_od = 0x40,
 503                        },
 504                        .addr_ihl = 0x22,
 505                        .mask_ihl = 0x80,
 506                        .stat_drdy = {
 507                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 508                                .mask = 0x07,
 509                        },
 510                },
 511                .sim = {
 512                        .addr = 0x21,
 513                        .value = BIT(7),
 514                },
 515                .multi_read_bit = false,
 516                .bootime = 2, /* guess */
 517        },
 518        {
 519                .wai = 0x32,
 520                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 521                .sensors_supported = {
 522                        [0] = H3LIS331DL_ACCEL_DEV_NAME,
 523                },
 524                .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
 525                .odr = {
 526                        .addr = 0x20,
 527                        .mask = 0x18,
 528                        .odr_avl = {
 529                                { .hz = 50, .value = 0x00, },
 530                                { .hz = 100, .value = 0x01, },
 531                                { .hz = 400, .value = 0x02, },
 532                                { .hz = 1000, .value = 0x03, },
 533                        },
 534                },
 535                .pw = {
 536                        .addr = 0x20,
 537                        .mask = 0x20,
 538                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 539                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 540                },
 541                .enable_axis = {
 542                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 543                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 544                },
 545                .fs = {
 546                        .addr = 0x23,
 547                        .mask = 0x30,
 548                        .fs_avl = {
 549                                [0] = {
 550                                        .num = ST_ACCEL_FS_AVL_100G,
 551                                        .value = 0x00,
 552                                        .gain = IIO_G_TO_M_S_2(49000),
 553                                },
 554                                [1] = {
 555                                        .num = ST_ACCEL_FS_AVL_200G,
 556                                        .value = 0x01,
 557                                        .gain = IIO_G_TO_M_S_2(98000),
 558                                },
 559                                [2] = {
 560                                        .num = ST_ACCEL_FS_AVL_400G,
 561                                        .value = 0x03,
 562                                        .gain = IIO_G_TO_M_S_2(195000),
 563                                },
 564                        },
 565                },
 566                .bdu = {
 567                        .addr = 0x23,
 568                        .mask = 0x80,
 569                },
 570                .drdy_irq = {
 571                        .int1 = {
 572                                .addr = 0x22,
 573                                .mask = 0x02,
 574                        },
 575                        .int2 = {
 576                                .addr = 0x22,
 577                                .mask = 0x10,
 578                        },
 579                        .addr_ihl = 0x22,
 580                        .mask_ihl = 0x80,
 581                },
 582                .sim = {
 583                        .addr = 0x23,
 584                        .value = BIT(0),
 585                },
 586                .multi_read_bit = true,
 587                .bootime = 2,
 588        },
 589        {
 590                /* No WAI register present */
 591                .sensors_supported = {
 592                        [0] = LIS3L02DQ_ACCEL_DEV_NAME,
 593                },
 594                .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
 595                .odr = {
 596                        .addr = 0x20,
 597                        .mask = 0x30,
 598                        .odr_avl = {
 599                                { .hz = 280, .value = 0x00, },
 600                                { .hz = 560, .value = 0x01, },
 601                                { .hz = 1120, .value = 0x02, },
 602                                { .hz = 4480, .value = 0x03, },
 603                        },
 604                },
 605                .pw = {
 606                        .addr = 0x20,
 607                        .mask = 0xc0,
 608                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 609                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 610                },
 611                .enable_axis = {
 612                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 613                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 614                },
 615                .fs = {
 616                        .fs_avl = {
 617                                [0] = {
 618                                        .num = ST_ACCEL_FS_AVL_2G,
 619                                        .gain = IIO_G_TO_M_S_2(488),
 620                                },
 621                        },
 622                },
 623                /*
 624                 * The part has a BDU bit but if set the data is never
 625                 * updated so don't set it.
 626                 */
 627                .bdu = {
 628                },
 629                .drdy_irq = {
 630                        .int1 = {
 631                                .addr = 0x21,
 632                                .mask = 0x04,
 633                        },
 634                        .stat_drdy = {
 635                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 636                                .mask = 0x07,
 637                        },
 638                },
 639                .sim = {
 640                        .addr = 0x21,
 641                        .value = BIT(1),
 642                },
 643                .multi_read_bit = false,
 644                .bootime = 2,
 645        },
 646        {
 647                .wai = 0x33,
 648                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 649                .sensors_supported = {
 650                        [0] = LNG2DM_ACCEL_DEV_NAME,
 651                },
 652                .ch = (struct iio_chan_spec *)st_accel_8bit_channels,
 653                .odr = {
 654                        .addr = 0x20,
 655                        .mask = 0xf0,
 656                        .odr_avl = {
 657                                { .hz = 1, .value = 0x01, },
 658                                { .hz = 10, .value = 0x02, },
 659                                { .hz = 25, .value = 0x03, },
 660                                { .hz = 50, .value = 0x04, },
 661                                { .hz = 100, .value = 0x05, },
 662                                { .hz = 200, .value = 0x06, },
 663                                { .hz = 400, .value = 0x07, },
 664                                { .hz = 1600, .value = 0x08, },
 665                        },
 666                },
 667                .pw = {
 668                        .addr = 0x20,
 669                        .mask = 0xf0,
 670                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 671                },
 672                .enable_axis = {
 673                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 674                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 675                },
 676                .fs = {
 677                        .addr = 0x23,
 678                        .mask = 0x30,
 679                        .fs_avl = {
 680                                [0] = {
 681                                        .num = ST_ACCEL_FS_AVL_2G,
 682                                        .value = 0x00,
 683                                        .gain = IIO_G_TO_M_S_2(15600),
 684                                },
 685                                [1] = {
 686                                        .num = ST_ACCEL_FS_AVL_4G,
 687                                        .value = 0x01,
 688                                        .gain = IIO_G_TO_M_S_2(31200),
 689                                },
 690                                [2] = {
 691                                        .num = ST_ACCEL_FS_AVL_8G,
 692                                        .value = 0x02,
 693                                        .gain = IIO_G_TO_M_S_2(62500),
 694                                },
 695                                [3] = {
 696                                        .num = ST_ACCEL_FS_AVL_16G,
 697                                        .value = 0x03,
 698                                        .gain = IIO_G_TO_M_S_2(187500),
 699                                },
 700                        },
 701                },
 702                .drdy_irq = {
 703                        .int1 = {
 704                                .addr = 0x22,
 705                                .mask = 0x10,
 706                        },
 707                        .addr_ihl = 0x25,
 708                        .mask_ihl = 0x02,
 709                        .stat_drdy = {
 710                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 711                                .mask = 0x07,
 712                        },
 713                },
 714                .sim = {
 715                        .addr = 0x23,
 716                        .value = BIT(0),
 717                },
 718                .multi_read_bit = true,
 719                .bootime = 2,
 720        },
 721        {
 722                .wai = 0x44,
 723                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 724                .sensors_supported = {
 725                        [0] = LIS2DW12_ACCEL_DEV_NAME,
 726                },
 727                .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
 728                .odr = {
 729                        .addr = 0x20,
 730                        .mask = 0xf0,
 731                        .odr_avl = {
 732                                { .hz = 1, .value = 0x01, },
 733                                { .hz = 12, .value = 0x02, },
 734                                { .hz = 25, .value = 0x03, },
 735                                { .hz = 50, .value = 0x04, },
 736                                { .hz = 100, .value = 0x05, },
 737                                { .hz = 200, .value = 0x06, },
 738                        },
 739                },
 740                .pw = {
 741                        .addr = 0x20,
 742                        .mask = 0xf0,
 743                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 744                },
 745                .fs = {
 746                        .addr = 0x25,
 747                        .mask = 0x30,
 748                        .fs_avl = {
 749                                [0] = {
 750                                        .num = ST_ACCEL_FS_AVL_2G,
 751                                        .value = 0x00,
 752                                        .gain = IIO_G_TO_M_S_2(976),
 753                                },
 754                                [1] = {
 755                                        .num = ST_ACCEL_FS_AVL_4G,
 756                                        .value = 0x01,
 757                                        .gain = IIO_G_TO_M_S_2(1952),
 758                                },
 759                                [2] = {
 760                                        .num = ST_ACCEL_FS_AVL_8G,
 761                                        .value = 0x02,
 762                                        .gain = IIO_G_TO_M_S_2(3904),
 763                                },
 764                                [3] = {
 765                                        .num = ST_ACCEL_FS_AVL_16G,
 766                                        .value = 0x03,
 767                                        .gain = IIO_G_TO_M_S_2(7808),
 768                                },
 769                        },
 770                },
 771                .bdu = {
 772                        .addr = 0x21,
 773                        .mask = 0x08,
 774                },
 775                .drdy_irq = {
 776                        .int1 = {
 777                                .addr = 0x23,
 778                                .mask = 0x01,
 779                                .addr_od = 0x22,
 780                                .mask_od = 0x20,
 781                        },
 782                        .int2 = {
 783                                .addr = 0x24,
 784                                .mask = 0x01,
 785                                .addr_od = 0x22,
 786                                .mask_od = 0x20,
 787                        },
 788                        .addr_ihl = 0x22,
 789                        .mask_ihl = 0x08,
 790                        .stat_drdy = {
 791                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 792                                .mask = 0x01,
 793                        },
 794                },
 795                .sim = {
 796                        .addr = 0x21,
 797                        .value = BIT(0),
 798                },
 799                .multi_read_bit = false,
 800                .bootime = 2,
 801        },
 802        {
 803                .wai = 0x11,
 804                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 805                .sensors_supported = {
 806                        [0] = LIS3DHH_ACCEL_DEV_NAME,
 807                },
 808                .ch = (struct iio_chan_spec *)st_accel_16bit_channels,
 809                .odr = {
 810                        /* just ODR = 1100Hz available */
 811                        .odr_avl = {
 812                                { .hz = 1100, .value = 0x00, },
 813                        },
 814                },
 815                .pw = {
 816                        .addr = 0x20,
 817                        .mask = 0x80,
 818                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 819                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 820                },
 821                .fs = {
 822                        .fs_avl = {
 823                                [0] = {
 824                                        .num = ST_ACCEL_FS_AVL_2G,
 825                                        .gain = IIO_G_TO_M_S_2(76),
 826                                },
 827                        },
 828                },
 829                .bdu = {
 830                        .addr = 0x20,
 831                        .mask = 0x01,
 832                },
 833                .drdy_irq = {
 834                        .int1 = {
 835                                .addr = 0x21,
 836                                .mask = 0x80,
 837                                .addr_od = 0x23,
 838                                .mask_od = 0x04,
 839                        },
 840                        .int2 = {
 841                                .addr = 0x22,
 842                                .mask = 0x80,
 843                                .addr_od = 0x23,
 844                                .mask_od = 0x08,
 845                        },
 846                        .stat_drdy = {
 847                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 848                                .mask = 0x07,
 849                        },
 850                },
 851                .multi_read_bit = false,
 852                .bootime = 2,
 853        },
 854        {
 855                .wai = 0x33,
 856                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 857                .sensors_supported = {
 858                        [0] = LIS2DE12_ACCEL_DEV_NAME,
 859                },
 860                .ch = (struct iio_chan_spec *)st_accel_8bit_channels,
 861                .odr = {
 862                        .addr = 0x20,
 863                        .mask = 0xf0,
 864                        .odr_avl = {
 865                                { .hz = 1, .value = 0x01, },
 866                                { .hz = 10, .value = 0x02, },
 867                                { .hz = 25, .value = 0x03, },
 868                                { .hz = 50, .value = 0x04, },
 869                                { .hz = 100, .value = 0x05, },
 870                                { .hz = 200, .value = 0x06, },
 871                                { .hz = 400, .value = 0x07, },
 872                                { .hz = 1620, .value = 0x08, },
 873                                { .hz = 5376, .value = 0x09, },
 874                        },
 875                },
 876                .pw = {
 877                        .addr = 0x20,
 878                        .mask = 0xf0,
 879                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 880                },
 881                .enable_axis = {
 882                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 883                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 884                },
 885                .fs = {
 886                        .addr = 0x23,
 887                        .mask = 0x30,
 888                        .fs_avl = {
 889                                [0] = {
 890                                        .num = ST_ACCEL_FS_AVL_2G,
 891                                        .value = 0x00,
 892                                        .gain = IIO_G_TO_M_S_2(15600),
 893                                },
 894                                [1] = {
 895                                        .num = ST_ACCEL_FS_AVL_4G,
 896                                        .value = 0x01,
 897                                        .gain = IIO_G_TO_M_S_2(31200),
 898                                },
 899                                [2] = {
 900                                        .num = ST_ACCEL_FS_AVL_8G,
 901                                        .value = 0x02,
 902                                        .gain = IIO_G_TO_M_S_2(62500),
 903                                },
 904                                [3] = {
 905                                        .num = ST_ACCEL_FS_AVL_16G,
 906                                        .value = 0x03,
 907                                        .gain = IIO_G_TO_M_S_2(187500),
 908                                },
 909                        },
 910                },
 911                .drdy_irq = {
 912                        .int1 = {
 913                                .addr = 0x22,
 914                                .mask = 0x10,
 915                        },
 916                        .addr_ihl = 0x25,
 917                        .mask_ihl = 0x02,
 918                        .stat_drdy = {
 919                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 920                                .mask = 0x07,
 921                        },
 922                },
 923                .sim = {
 924                        .addr = 0x23,
 925                        .value = BIT(0),
 926                },
 927                .multi_read_bit = true,
 928                .bootime = 2,
 929        },
 930        {
 931                .wai = 0x41,
 932                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 933                .sensors_supported = {
 934                        [0] = LIS2HH12_ACCEL_DEV_NAME,
 935                },
 936                .ch = (struct iio_chan_spec *)st_accel_16bit_channels,
 937                .odr = {
 938                        .addr = 0x20,
 939                        .mask = 0x70,
 940                        .odr_avl = {
 941                                { .hz = 10, .value = 0x01, },
 942                                { .hz = 50, .value = 0x02, },
 943                                { .hz = 100, .value = 0x03, },
 944                                { .hz = 200, .value = 0x04, },
 945                                { .hz = 400, .value = 0x05, },
 946                                { .hz = 800, .value = 0x06, },
 947                        },
 948                },
 949                .pw = {
 950                        .addr = 0x20,
 951                        .mask = 0x70,
 952                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 953                },
 954                .enable_axis = {
 955                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 956                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 957                },
 958                .fs = {
 959                        .addr = 0x23,
 960                        .mask = 0x30,
 961                        .fs_avl = {
 962                                [0] = {
 963                                        .num = ST_ACCEL_FS_AVL_2G,
 964                                        .value = 0x00,
 965                                        .gain = IIO_G_TO_M_S_2(61),
 966                                },
 967                                [1] = {
 968                                        .num = ST_ACCEL_FS_AVL_4G,
 969                                        .value = 0x02,
 970                                        .gain = IIO_G_TO_M_S_2(122),
 971                                },
 972                                [2] = {
 973                                        .num = ST_ACCEL_FS_AVL_8G,
 974                                        .value = 0x03,
 975                                        .gain = IIO_G_TO_M_S_2(244),
 976                                },
 977                        },
 978                },
 979                .bdu = {
 980                        .addr = 0x20,
 981                        .mask = 0x08,
 982                },
 983                .drdy_irq = {
 984                        .int1 = {
 985                                .addr = 0x22,
 986                                .mask = 0x01,
 987                        },
 988                        .int2 = {
 989                                .addr = 0x25,
 990                                .mask = 0x01,
 991                        },
 992                        .addr_ihl = 0x24,
 993                        .mask_ihl = 0x02,
 994                        .stat_drdy = {
 995                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
 996                                .mask = 0x07,
 997                        },
 998                },
 999                .sim = {
1000                        .addr = 0x23,
1001                        .value = BIT(0),
1002                },
1003                .multi_read_bit = true,
1004                .bootime = 2,
1005        },
1006        {
1007                .wai = 0x49,
1008                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
1009                .sensors_supported = {
1010                        [0] = LSM9DS0_IMU_DEV_NAME,
1011                },
1012                .ch = (struct iio_chan_spec *)st_accel_16bit_channels,
1013                .odr = {
1014                        .addr = 0x20,
1015                        .mask = GENMASK(7, 4),
1016                        .odr_avl = {
1017                                { 3, 0x01, },
1018                                { 6, 0x02, },
1019                                { 12, 0x03, },
1020                                { 25, 0x04, },
1021                                { 50, 0x05, },
1022                                { 100, 0x06, },
1023                                { 200, 0x07, },
1024                                { 400, 0x08, },
1025                                { 800, 0x09, },
1026                                { 1600, 0x0a, },
1027                        },
1028                },
1029                .pw = {
1030                        .addr = 0x20,
1031                        .mask = GENMASK(7, 4),
1032                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
1033                },
1034                .enable_axis = {
1035                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
1036                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
1037                },
1038                .fs = {
1039                        .addr = 0x21,
1040                        .mask = GENMASK(5, 3),
1041                        .fs_avl = {
1042                                [0] = {
1043                                        .num = ST_ACCEL_FS_AVL_2G,
1044                                        .value = 0x00,
1045                                        .gain = IIO_G_TO_M_S_2(61),
1046                                },
1047                                [1] = {
1048                                        .num = ST_ACCEL_FS_AVL_4G,
1049                                        .value = 0x01,
1050                                        .gain = IIO_G_TO_M_S_2(122),
1051                                },
1052                                [2] = {
1053                                        .num = ST_ACCEL_FS_AVL_6G,
1054                                        .value = 0x02,
1055                                        .gain = IIO_G_TO_M_S_2(183),
1056                                },
1057                                [3] = {
1058                                        .num = ST_ACCEL_FS_AVL_8G,
1059                                        .value = 0x03,
1060                                        .gain = IIO_G_TO_M_S_2(244),
1061                                },
1062                                [4] = {
1063                                        .num = ST_ACCEL_FS_AVL_16G,
1064                                        .value = 0x04,
1065                                        .gain = IIO_G_TO_M_S_2(732),
1066                                },
1067                        },
1068                },
1069                .bdu = {
1070                        .addr = 0x20,
1071                        .mask = BIT(3),
1072                },
1073                .drdy_irq = {
1074                        .int1 = {
1075                                .addr = 0x22,
1076                                .mask = BIT(2),
1077                        },
1078                        .int2 = {
1079                                .addr = 0x23,
1080                                .mask = BIT(3),
1081                        },
1082                        .stat_drdy = {
1083                                .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
1084                                .mask = GENMASK(2, 0),
1085                        },
1086                },
1087                .sim = {
1088                        .addr = 0x21,
1089                        .value = BIT(0),
1090                },
1091                .multi_read_bit = true,
1092                .bootime = 2,
1093        },
1094};
1095
1096/* Default accel DRDY is available on INT1 pin */
1097static const struct st_sensors_platform_data default_accel_pdata = {
1098        .drdy_int_pin = 1,
1099};
1100
1101static int st_accel_read_raw(struct iio_dev *indio_dev,
1102                        struct iio_chan_spec const *ch, int *val,
1103                                                        int *val2, long mask)
1104{
1105        int err;
1106        struct st_sensor_data *adata = iio_priv(indio_dev);
1107
1108        switch (mask) {
1109        case IIO_CHAN_INFO_RAW:
1110                err = st_sensors_read_info_raw(indio_dev, ch, val);
1111                if (err < 0)
1112                        goto read_error;
1113
1114                return IIO_VAL_INT;
1115        case IIO_CHAN_INFO_SCALE:
1116                *val = adata->current_fullscale->gain / 1000000;
1117                *val2 = adata->current_fullscale->gain % 1000000;
1118                return IIO_VAL_INT_PLUS_MICRO;
1119        case IIO_CHAN_INFO_SAMP_FREQ:
1120                *val = adata->odr;
1121                return IIO_VAL_INT;
1122        default:
1123                return -EINVAL;
1124        }
1125
1126read_error:
1127        return err;
1128}
1129
1130static int st_accel_write_raw(struct iio_dev *indio_dev,
1131                struct iio_chan_spec const *chan, int val, int val2, long mask)
1132{
1133        int err;
1134
1135        switch (mask) {
1136        case IIO_CHAN_INFO_SCALE: {
1137                int gain;
1138
1139                gain = val * 1000000 + val2;
1140                err = st_sensors_set_fullscale_by_gain(indio_dev, gain);
1141                break;
1142        }
1143        case IIO_CHAN_INFO_SAMP_FREQ:
1144                if (val2)
1145                        return -EINVAL;
1146                mutex_lock(&indio_dev->mlock);
1147                err = st_sensors_set_odr(indio_dev, val);
1148                mutex_unlock(&indio_dev->mlock);
1149                return err;
1150        default:
1151                return -EINVAL;
1152        }
1153
1154        return err;
1155}
1156
1157static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
1158static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_accel_scale_available);
1159
1160static struct attribute *st_accel_attributes[] = {
1161        &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
1162        &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
1163        NULL,
1164};
1165
1166static const struct attribute_group st_accel_attribute_group = {
1167        .attrs = st_accel_attributes,
1168};
1169
1170static const struct iio_info accel_info = {
1171        .attrs = &st_accel_attribute_group,
1172        .read_raw = &st_accel_read_raw,
1173        .write_raw = &st_accel_write_raw,
1174        .debugfs_reg_access = &st_sensors_debugfs_reg_access,
1175};
1176
1177#ifdef CONFIG_IIO_TRIGGER
1178static const struct iio_trigger_ops st_accel_trigger_ops = {
1179        .set_trigger_state = ST_ACCEL_TRIGGER_SET_STATE,
1180        .validate_device = st_sensors_validate_device,
1181};
1182#define ST_ACCEL_TRIGGER_OPS (&st_accel_trigger_ops)
1183#else
1184#define ST_ACCEL_TRIGGER_OPS NULL
1185#endif
1186
1187#ifdef CONFIG_ACPI
1188/* Read ST-specific _ONT orientation data from ACPI and generate an
1189 * appropriate mount matrix.
1190 */
1191static int apply_acpi_orientation(struct iio_dev *indio_dev)
1192{
1193        struct st_sensor_data *adata = iio_priv(indio_dev);
1194        struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
1195        struct acpi_device *adev;
1196        union acpi_object *ont;
1197        union acpi_object *elements;
1198        acpi_status status;
1199        int ret = -EINVAL;
1200        unsigned int val;
1201        int i, j;
1202        int final_ont[3][3] = { { 0 }, };
1203
1204        /* For some reason, ST's _ONT translation does not apply directly
1205         * to the data read from the sensor. Another translation must be
1206         * performed first, as described by the matrix below. Perhaps
1207         * ST required this specific translation for the first product
1208         * where the device was mounted?
1209         */
1210        const int default_ont[3][3] = {
1211                {  0,  1,  0 },
1212                { -1,  0,  0 },
1213                {  0,  0, -1 },
1214        };
1215
1216
1217        adev = ACPI_COMPANION(adata->dev);
1218        if (!adev)
1219                return 0;
1220
1221        /* Read _ONT data, which should be a package of 6 integers. */
1222        status = acpi_evaluate_object(adev->handle, "_ONT", NULL, &buffer);
1223        if (status == AE_NOT_FOUND) {
1224                return 0;
1225        } else if (ACPI_FAILURE(status)) {
1226                dev_warn(&indio_dev->dev, "failed to execute _ONT: %d\n",
1227                         status);
1228                return status;
1229        }
1230
1231        ont = buffer.pointer;
1232        if (ont->type != ACPI_TYPE_PACKAGE || ont->package.count != 6)
1233                goto out;
1234
1235        /* The first 3 integers provide axis order information.
1236         * e.g. 0 1 2 would indicate normal X,Y,Z ordering.
1237         * e.g. 1 0 2 indicates that data arrives in order Y,X,Z.
1238         */
1239        elements = ont->package.elements;
1240        for (i = 0; i < 3; i++) {
1241                if (elements[i].type != ACPI_TYPE_INTEGER)
1242                        goto out;
1243
1244                val = elements[i].integer.value;
1245                if (val > 2)
1246                        goto out;
1247
1248                /* Avoiding full matrix multiplication, we simply reorder the
1249                 * columns in the default_ont matrix according to the
1250                 * ordering provided by _ONT.
1251                 */
1252                final_ont[0][i] = default_ont[0][val];
1253                final_ont[1][i] = default_ont[1][val];
1254                final_ont[2][i] = default_ont[2][val];
1255        }
1256
1257        /* The final 3 integers provide sign flip information.
1258         * 0 means no change, 1 means flip.
1259         * e.g. 0 0 1 means that Z data should be sign-flipped.
1260         * This is applied after the axis reordering from above.
1261         */
1262        elements += 3;
1263        for (i = 0; i < 3; i++) {
1264                if (elements[i].type != ACPI_TYPE_INTEGER)
1265                        goto out;
1266
1267                val = elements[i].integer.value;
1268                if (val != 0 && val != 1)
1269                        goto out;
1270                if (!val)
1271                        continue;
1272
1273                /* Flip the values in the indicated column */
1274                final_ont[0][i] *= -1;
1275                final_ont[1][i] *= -1;
1276                final_ont[2][i] *= -1;
1277        }
1278
1279        /* Convert our integer matrix to a string-based iio_mount_matrix */
1280        for (i = 0; i < 3; i++) {
1281                for (j = 0; j < 3; j++) {
1282                        int matrix_val = final_ont[i][j];
1283                        char *str_value;
1284
1285                        switch (matrix_val) {
1286                        case -1:
1287                                str_value = "-1";
1288                                break;
1289                        case 0:
1290                                str_value = "0";
1291                                break;
1292                        case 1:
1293                                str_value = "1";
1294                                break;
1295                        default:
1296                                goto out;
1297                        }
1298                        adata->mount_matrix.rotation[i * 3 + j] = str_value;
1299                }
1300        }
1301
1302        ret = 0;
1303        dev_info(&indio_dev->dev, "computed mount matrix from ACPI\n");
1304
1305out:
1306        kfree(buffer.pointer);
1307        if (ret)
1308                dev_dbg(&indio_dev->dev,
1309                        "failed to apply ACPI orientation data: %d\n", ret);
1310
1311        return ret;
1312}
1313#else /* !CONFIG_ACPI */
1314static int apply_acpi_orientation(struct iio_dev *indio_dev)
1315{
1316        return -EINVAL;
1317}
1318#endif
1319
1320/*
1321 * st_accel_get_settings() - get sensor settings from device name
1322 * @name: device name buffer reference.
1323 *
1324 * Return: valid reference on success, NULL otherwise.
1325 */
1326const struct st_sensor_settings *st_accel_get_settings(const char *name)
1327{
1328        int index = st_sensors_get_settings_index(name,
1329                                        st_accel_sensors_settings,
1330                                        ARRAY_SIZE(st_accel_sensors_settings));
1331        if (index < 0)
1332                return NULL;
1333
1334        return &st_accel_sensors_settings[index];
1335}
1336EXPORT_SYMBOL(st_accel_get_settings);
1337
1338int st_accel_common_probe(struct iio_dev *indio_dev)
1339{
1340        struct st_sensor_data *adata = iio_priv(indio_dev);
1341        struct st_sensors_platform_data *pdata = dev_get_platdata(adata->dev);
1342        int err;
1343
1344        indio_dev->modes = INDIO_DIRECT_MODE;
1345        indio_dev->info = &accel_info;
1346
1347        err = st_sensors_verify_id(indio_dev);
1348        if (err < 0)
1349                return err;
1350
1351        adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS;
1352        indio_dev->channels = adata->sensor_settings->ch;
1353        indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
1354
1355        /*
1356         * First try specific ACPI methods to retrieve orientation then try the
1357         * generic function.
1358         */
1359        err = apply_acpi_orientation(indio_dev);
1360        if (err) {
1361                err = iio_read_mount_matrix(adata->dev, &adata->mount_matrix);
1362                if (err)
1363                        return err;
1364        }
1365
1366        adata->current_fullscale = &adata->sensor_settings->fs.fs_avl[0];
1367        adata->odr = adata->sensor_settings->odr.odr_avl[0].hz;
1368
1369        if (!pdata)
1370                pdata = (struct st_sensors_platform_data *)&default_accel_pdata;
1371
1372        err = st_sensors_init_sensor(indio_dev, pdata);
1373        if (err < 0)
1374                return err;
1375
1376        err = st_accel_allocate_ring(indio_dev);
1377        if (err < 0)
1378                return err;
1379
1380        if (adata->irq > 0) {
1381                err = st_sensors_allocate_trigger(indio_dev,
1382                                                 ST_ACCEL_TRIGGER_OPS);
1383                if (err < 0)
1384                        goto st_accel_probe_trigger_error;
1385        }
1386
1387        err = iio_device_register(indio_dev);
1388        if (err)
1389                goto st_accel_device_register_error;
1390
1391        dev_info(&indio_dev->dev, "registered accelerometer %s\n",
1392                 indio_dev->name);
1393
1394        return 0;
1395
1396st_accel_device_register_error:
1397        if (adata->irq > 0)
1398                st_sensors_deallocate_trigger(indio_dev);
1399st_accel_probe_trigger_error:
1400        st_accel_deallocate_ring(indio_dev);
1401        return err;
1402}
1403EXPORT_SYMBOL(st_accel_common_probe);
1404
1405void st_accel_common_remove(struct iio_dev *indio_dev)
1406{
1407        struct st_sensor_data *adata = iio_priv(indio_dev);
1408
1409        iio_device_unregister(indio_dev);
1410        if (adata->irq > 0)
1411                st_sensors_deallocate_trigger(indio_dev);
1412
1413        st_accel_deallocate_ring(indio_dev);
1414}
1415EXPORT_SYMBOL(st_accel_common_remove);
1416
1417MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
1418MODULE_DESCRIPTION("STMicroelectronics accelerometers driver");
1419MODULE_LICENSE("GPL v2");
1420