linux/drivers/iio/accel/st_accel_core.c
<<
>>
Prefs
   1/*
   2 * STMicroelectronics accelerometers driver
   3 *
   4 * Copyright 2012-2013 STMicroelectronics Inc.
   5 *
   6 * Denis Ciocca <denis.ciocca@st.com>
   7 *
   8 * Licensed under the GPL-2.
   9 */
  10
  11#include <linux/kernel.h>
  12#include <linux/module.h>
  13#include <linux/slab.h>
  14#include <linux/errno.h>
  15#include <linux/types.h>
  16#include <linux/mutex.h>
  17#include <linux/interrupt.h>
  18#include <linux/i2c.h>
  19#include <linux/gpio.h>
  20#include <linux/irq.h>
  21#include <linux/iio/iio.h>
  22#include <linux/iio/sysfs.h>
  23#include <linux/iio/trigger.h>
  24#include <linux/iio/buffer.h>
  25
  26#include <linux/iio/common/st_sensors.h>
  27#include "st_accel.h"
  28
  29#define ST_ACCEL_NUMBER_DATA_CHANNELS           3
  30
  31/* DEFAULT VALUE FOR SENSORS */
  32#define ST_ACCEL_DEFAULT_OUT_X_L_ADDR           0x28
  33#define ST_ACCEL_DEFAULT_OUT_Y_L_ADDR           0x2a
  34#define ST_ACCEL_DEFAULT_OUT_Z_L_ADDR           0x2c
  35
  36/* FULLSCALE */
  37#define ST_ACCEL_FS_AVL_2G                      2
  38#define ST_ACCEL_FS_AVL_4G                      4
  39#define ST_ACCEL_FS_AVL_6G                      6
  40#define ST_ACCEL_FS_AVL_8G                      8
  41#define ST_ACCEL_FS_AVL_16G                     16
  42
  43/* CUSTOM VALUES FOR SENSOR 1 */
  44#define ST_ACCEL_1_WAI_EXP                      0x33
  45#define ST_ACCEL_1_ODR_ADDR                     0x20
  46#define ST_ACCEL_1_ODR_MASK                     0xf0
  47#define ST_ACCEL_1_ODR_AVL_1HZ_VAL              0x01
  48#define ST_ACCEL_1_ODR_AVL_10HZ_VAL             0x02
  49#define ST_ACCEL_1_ODR_AVL_25HZ_VAL             0x03
  50#define ST_ACCEL_1_ODR_AVL_50HZ_VAL             0x04
  51#define ST_ACCEL_1_ODR_AVL_100HZ_VAL            0x05
  52#define ST_ACCEL_1_ODR_AVL_200HZ_VAL            0x06
  53#define ST_ACCEL_1_ODR_AVL_400HZ_VAL            0x07
  54#define ST_ACCEL_1_ODR_AVL_1600HZ_VAL           0x08
  55#define ST_ACCEL_1_FS_ADDR                      0x23
  56#define ST_ACCEL_1_FS_MASK                      0x30
  57#define ST_ACCEL_1_FS_AVL_2_VAL                 0x00
  58#define ST_ACCEL_1_FS_AVL_4_VAL                 0x01
  59#define ST_ACCEL_1_FS_AVL_8_VAL                 0x02
  60#define ST_ACCEL_1_FS_AVL_16_VAL                0x03
  61#define ST_ACCEL_1_FS_AVL_2_GAIN                IIO_G_TO_M_S_2(1000)
  62#define ST_ACCEL_1_FS_AVL_4_GAIN                IIO_G_TO_M_S_2(2000)
  63#define ST_ACCEL_1_FS_AVL_8_GAIN                IIO_G_TO_M_S_2(4000)
  64#define ST_ACCEL_1_FS_AVL_16_GAIN               IIO_G_TO_M_S_2(12000)
  65#define ST_ACCEL_1_BDU_ADDR                     0x23
  66#define ST_ACCEL_1_BDU_MASK                     0x80
  67#define ST_ACCEL_1_DRDY_IRQ_ADDR                0x22
  68#define ST_ACCEL_1_DRDY_IRQ_INT1_MASK           0x10
  69#define ST_ACCEL_1_DRDY_IRQ_INT2_MASK           0x08
  70#define ST_ACCEL_1_IHL_IRQ_ADDR                 0x25
  71#define ST_ACCEL_1_IHL_IRQ_MASK                 0x02
  72#define ST_ACCEL_1_MULTIREAD_BIT                true
  73
  74/* CUSTOM VALUES FOR SENSOR 2 */
  75#define ST_ACCEL_2_WAI_EXP                      0x32
  76#define ST_ACCEL_2_ODR_ADDR                     0x20
  77#define ST_ACCEL_2_ODR_MASK                     0x18
  78#define ST_ACCEL_2_ODR_AVL_50HZ_VAL             0x00
  79#define ST_ACCEL_2_ODR_AVL_100HZ_VAL            0x01
  80#define ST_ACCEL_2_ODR_AVL_400HZ_VAL            0x02
  81#define ST_ACCEL_2_ODR_AVL_1000HZ_VAL           0x03
  82#define ST_ACCEL_2_PW_ADDR                      0x20
  83#define ST_ACCEL_2_PW_MASK                      0xe0
  84#define ST_ACCEL_2_FS_ADDR                      0x23
  85#define ST_ACCEL_2_FS_MASK                      0x30
  86#define ST_ACCEL_2_FS_AVL_2_VAL                 0X00
  87#define ST_ACCEL_2_FS_AVL_4_VAL                 0X01
  88#define ST_ACCEL_2_FS_AVL_8_VAL                 0x03
  89#define ST_ACCEL_2_FS_AVL_2_GAIN                IIO_G_TO_M_S_2(1000)
  90#define ST_ACCEL_2_FS_AVL_4_GAIN                IIO_G_TO_M_S_2(2000)
  91#define ST_ACCEL_2_FS_AVL_8_GAIN                IIO_G_TO_M_S_2(3900)
  92#define ST_ACCEL_2_BDU_ADDR                     0x23
  93#define ST_ACCEL_2_BDU_MASK                     0x80
  94#define ST_ACCEL_2_DRDY_IRQ_ADDR                0x22
  95#define ST_ACCEL_2_DRDY_IRQ_INT1_MASK           0x02
  96#define ST_ACCEL_2_DRDY_IRQ_INT2_MASK           0x10
  97#define ST_ACCEL_2_IHL_IRQ_ADDR                 0x22
  98#define ST_ACCEL_2_IHL_IRQ_MASK                 0x80
  99#define ST_ACCEL_2_MULTIREAD_BIT                true
 100
 101/* CUSTOM VALUES FOR SENSOR 3 */
 102#define ST_ACCEL_3_WAI_EXP                      0x40
 103#define ST_ACCEL_3_ODR_ADDR                     0x20
 104#define ST_ACCEL_3_ODR_MASK                     0xf0
 105#define ST_ACCEL_3_ODR_AVL_3HZ_VAL              0x01
 106#define ST_ACCEL_3_ODR_AVL_6HZ_VAL              0x02
 107#define ST_ACCEL_3_ODR_AVL_12HZ_VAL             0x03
 108#define ST_ACCEL_3_ODR_AVL_25HZ_VAL             0x04
 109#define ST_ACCEL_3_ODR_AVL_50HZ_VAL             0x05
 110#define ST_ACCEL_3_ODR_AVL_100HZ_VAL            0x06
 111#define ST_ACCEL_3_ODR_AVL_200HZ_VAL            0x07
 112#define ST_ACCEL_3_ODR_AVL_400HZ_VAL            0x08
 113#define ST_ACCEL_3_ODR_AVL_800HZ_VAL            0x09
 114#define ST_ACCEL_3_ODR_AVL_1600HZ_VAL           0x0a
 115#define ST_ACCEL_3_FS_ADDR                      0x24
 116#define ST_ACCEL_3_FS_MASK                      0x38
 117#define ST_ACCEL_3_FS_AVL_2_VAL                 0X00
 118#define ST_ACCEL_3_FS_AVL_4_VAL                 0X01
 119#define ST_ACCEL_3_FS_AVL_6_VAL                 0x02
 120#define ST_ACCEL_3_FS_AVL_8_VAL                 0x03
 121#define ST_ACCEL_3_FS_AVL_16_VAL                0x04
 122#define ST_ACCEL_3_FS_AVL_2_GAIN                IIO_G_TO_M_S_2(61)
 123#define ST_ACCEL_3_FS_AVL_4_GAIN                IIO_G_TO_M_S_2(122)
 124#define ST_ACCEL_3_FS_AVL_6_GAIN                IIO_G_TO_M_S_2(183)
 125#define ST_ACCEL_3_FS_AVL_8_GAIN                IIO_G_TO_M_S_2(244)
 126#define ST_ACCEL_3_FS_AVL_16_GAIN               IIO_G_TO_M_S_2(732)
 127#define ST_ACCEL_3_BDU_ADDR                     0x20
 128#define ST_ACCEL_3_BDU_MASK                     0x08
 129#define ST_ACCEL_3_DRDY_IRQ_ADDR                0x23
 130#define ST_ACCEL_3_DRDY_IRQ_INT1_MASK           0x80
 131#define ST_ACCEL_3_DRDY_IRQ_INT2_MASK           0x00
 132#define ST_ACCEL_3_IHL_IRQ_ADDR                 0x23
 133#define ST_ACCEL_3_IHL_IRQ_MASK                 0x40
 134#define ST_ACCEL_3_IG1_EN_ADDR                  0x23
 135#define ST_ACCEL_3_IG1_EN_MASK                  0x08
 136#define ST_ACCEL_3_MULTIREAD_BIT                false
 137
 138/* CUSTOM VALUES FOR SENSOR 4 */
 139#define ST_ACCEL_4_WAI_EXP                      0x3a
 140#define ST_ACCEL_4_ODR_ADDR                     0x20
 141#define ST_ACCEL_4_ODR_MASK                     0x30 /* DF1 and DF0 */
 142#define ST_ACCEL_4_ODR_AVL_40HZ_VAL             0x00
 143#define ST_ACCEL_4_ODR_AVL_160HZ_VAL            0x01
 144#define ST_ACCEL_4_ODR_AVL_640HZ_VAL            0x02
 145#define ST_ACCEL_4_ODR_AVL_2560HZ_VAL           0x03
 146#define ST_ACCEL_4_PW_ADDR                      0x20
 147#define ST_ACCEL_4_PW_MASK                      0xc0
 148#define ST_ACCEL_4_FS_ADDR                      0x21
 149#define ST_ACCEL_4_FS_MASK                      0x80
 150#define ST_ACCEL_4_FS_AVL_2_VAL                 0X00
 151#define ST_ACCEL_4_FS_AVL_6_VAL                 0X01
 152#define ST_ACCEL_4_FS_AVL_2_GAIN                IIO_G_TO_M_S_2(1024)
 153#define ST_ACCEL_4_FS_AVL_6_GAIN                IIO_G_TO_M_S_2(340)
 154#define ST_ACCEL_4_BDU_ADDR                     0x21
 155#define ST_ACCEL_4_BDU_MASK                     0x40
 156#define ST_ACCEL_4_DRDY_IRQ_ADDR                0x21
 157#define ST_ACCEL_4_DRDY_IRQ_INT1_MASK           0x04
 158#define ST_ACCEL_4_MULTIREAD_BIT                true
 159
 160/* CUSTOM VALUES FOR SENSOR 5 */
 161#define ST_ACCEL_5_WAI_EXP                      0x3b
 162#define ST_ACCEL_5_ODR_ADDR                     0x20
 163#define ST_ACCEL_5_ODR_MASK                     0x80
 164#define ST_ACCEL_5_ODR_AVL_100HZ_VAL            0x00
 165#define ST_ACCEL_5_ODR_AVL_400HZ_VAL            0x01
 166#define ST_ACCEL_5_PW_ADDR                      0x20
 167#define ST_ACCEL_5_PW_MASK                      0x40
 168#define ST_ACCEL_5_FS_ADDR                      0x20
 169#define ST_ACCEL_5_FS_MASK                      0x20
 170#define ST_ACCEL_5_FS_AVL_2_VAL                 0X00
 171#define ST_ACCEL_5_FS_AVL_8_VAL                 0X01
 172/* TODO: check these resulting gain settings, these are not in the datsheet */
 173#define ST_ACCEL_5_FS_AVL_2_GAIN                IIO_G_TO_M_S_2(18000)
 174#define ST_ACCEL_5_FS_AVL_8_GAIN                IIO_G_TO_M_S_2(72000)
 175#define ST_ACCEL_5_DRDY_IRQ_ADDR                0x22
 176#define ST_ACCEL_5_DRDY_IRQ_INT1_MASK           0x04
 177#define ST_ACCEL_5_DRDY_IRQ_INT2_MASK           0x20
 178#define ST_ACCEL_5_IHL_IRQ_ADDR                 0x22
 179#define ST_ACCEL_5_IHL_IRQ_MASK                 0x80
 180#define ST_ACCEL_5_IG1_EN_ADDR                  0x21
 181#define ST_ACCEL_5_IG1_EN_MASK                  0x08
 182#define ST_ACCEL_5_MULTIREAD_BIT                false
 183
 184static const struct iio_chan_spec st_accel_8bit_channels[] = {
 185        ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
 186                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 187                        ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 8, 8,
 188                        ST_ACCEL_DEFAULT_OUT_X_L_ADDR+1),
 189        ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
 190                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 191                        ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 8, 8,
 192                        ST_ACCEL_DEFAULT_OUT_Y_L_ADDR+1),
 193        ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
 194                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 195                        ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 8, 8,
 196                        ST_ACCEL_DEFAULT_OUT_Z_L_ADDR+1),
 197        IIO_CHAN_SOFT_TIMESTAMP(3)
 198};
 199
 200static const struct iio_chan_spec st_accel_12bit_channels[] = {
 201        ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
 202                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 203                        ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 12, 16,
 204                        ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
 205        ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
 206                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 207                        ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 12, 16,
 208                        ST_ACCEL_DEFAULT_OUT_Y_L_ADDR),
 209        ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
 210                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 211                        ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 12, 16,
 212                        ST_ACCEL_DEFAULT_OUT_Z_L_ADDR),
 213        IIO_CHAN_SOFT_TIMESTAMP(3)
 214};
 215
 216static const struct iio_chan_spec st_accel_16bit_channels[] = {
 217        ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
 218                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 219                        ST_SENSORS_SCAN_X, 1, IIO_MOD_X, 's', IIO_LE, 16, 16,
 220                        ST_ACCEL_DEFAULT_OUT_X_L_ADDR),
 221        ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
 222                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 223                        ST_SENSORS_SCAN_Y, 1, IIO_MOD_Y, 's', IIO_LE, 16, 16,
 224                        ST_ACCEL_DEFAULT_OUT_Y_L_ADDR),
 225        ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
 226                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 227                        ST_SENSORS_SCAN_Z, 1, IIO_MOD_Z, 's', IIO_LE, 16, 16,
 228                        ST_ACCEL_DEFAULT_OUT_Z_L_ADDR),
 229        IIO_CHAN_SOFT_TIMESTAMP(3)
 230};
 231
 232static const struct st_sensor_settings st_accel_sensors_settings[] = {
 233        {
 234                .wai = ST_ACCEL_1_WAI_EXP,
 235                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 236                .sensors_supported = {
 237                        [0] = LIS3DH_ACCEL_DEV_NAME,
 238                        [1] = LSM303DLHC_ACCEL_DEV_NAME,
 239                        [2] = LSM330D_ACCEL_DEV_NAME,
 240                        [3] = LSM330DL_ACCEL_DEV_NAME,
 241                        [4] = LSM330DLC_ACCEL_DEV_NAME,
 242                        [5] = LSM303AGR_ACCEL_DEV_NAME,
 243                        [6] = LIS2DH12_ACCEL_DEV_NAME,
 244                },
 245                .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
 246                .odr = {
 247                        .addr = ST_ACCEL_1_ODR_ADDR,
 248                        .mask = ST_ACCEL_1_ODR_MASK,
 249                        .odr_avl = {
 250                                { 1, ST_ACCEL_1_ODR_AVL_1HZ_VAL, },
 251                                { 10, ST_ACCEL_1_ODR_AVL_10HZ_VAL, },
 252                                { 25, ST_ACCEL_1_ODR_AVL_25HZ_VAL, },
 253                                { 50, ST_ACCEL_1_ODR_AVL_50HZ_VAL, },
 254                                { 100, ST_ACCEL_1_ODR_AVL_100HZ_VAL, },
 255                                { 200, ST_ACCEL_1_ODR_AVL_200HZ_VAL, },
 256                                { 400, ST_ACCEL_1_ODR_AVL_400HZ_VAL, },
 257                                { 1600, ST_ACCEL_1_ODR_AVL_1600HZ_VAL, },
 258                        },
 259                },
 260                .pw = {
 261                        .addr = ST_ACCEL_1_ODR_ADDR,
 262                        .mask = ST_ACCEL_1_ODR_MASK,
 263                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 264                },
 265                .enable_axis = {
 266                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 267                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 268                },
 269                .fs = {
 270                        .addr = ST_ACCEL_1_FS_ADDR,
 271                        .mask = ST_ACCEL_1_FS_MASK,
 272                        .fs_avl = {
 273                                [0] = {
 274                                        .num = ST_ACCEL_FS_AVL_2G,
 275                                        .value = ST_ACCEL_1_FS_AVL_2_VAL,
 276                                        .gain = ST_ACCEL_1_FS_AVL_2_GAIN,
 277                                },
 278                                [1] = {
 279                                        .num = ST_ACCEL_FS_AVL_4G,
 280                                        .value = ST_ACCEL_1_FS_AVL_4_VAL,
 281                                        .gain = ST_ACCEL_1_FS_AVL_4_GAIN,
 282                                },
 283                                [2] = {
 284                                        .num = ST_ACCEL_FS_AVL_8G,
 285                                        .value = ST_ACCEL_1_FS_AVL_8_VAL,
 286                                        .gain = ST_ACCEL_1_FS_AVL_8_GAIN,
 287                                },
 288                                [3] = {
 289                                        .num = ST_ACCEL_FS_AVL_16G,
 290                                        .value = ST_ACCEL_1_FS_AVL_16_VAL,
 291                                        .gain = ST_ACCEL_1_FS_AVL_16_GAIN,
 292                                },
 293                        },
 294                },
 295                .bdu = {
 296                        .addr = ST_ACCEL_1_BDU_ADDR,
 297                        .mask = ST_ACCEL_1_BDU_MASK,
 298                },
 299                .drdy_irq = {
 300                        .addr = ST_ACCEL_1_DRDY_IRQ_ADDR,
 301                        .mask_int1 = ST_ACCEL_1_DRDY_IRQ_INT1_MASK,
 302                        .mask_int2 = ST_ACCEL_1_DRDY_IRQ_INT2_MASK,
 303                        .addr_ihl = ST_ACCEL_1_IHL_IRQ_ADDR,
 304                        .mask_ihl = ST_ACCEL_1_IHL_IRQ_MASK,
 305                },
 306                .multi_read_bit = ST_ACCEL_1_MULTIREAD_BIT,
 307                .bootime = 2,
 308        },
 309        {
 310                .wai = ST_ACCEL_2_WAI_EXP,
 311                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 312                .sensors_supported = {
 313                        [0] = LIS331DLH_ACCEL_DEV_NAME,
 314                        [1] = LSM303DL_ACCEL_DEV_NAME,
 315                        [2] = LSM303DLH_ACCEL_DEV_NAME,
 316                        [3] = LSM303DLM_ACCEL_DEV_NAME,
 317                },
 318                .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
 319                .odr = {
 320                        .addr = ST_ACCEL_2_ODR_ADDR,
 321                        .mask = ST_ACCEL_2_ODR_MASK,
 322                        .odr_avl = {
 323                                { 50, ST_ACCEL_2_ODR_AVL_50HZ_VAL, },
 324                                { 100, ST_ACCEL_2_ODR_AVL_100HZ_VAL, },
 325                                { 400, ST_ACCEL_2_ODR_AVL_400HZ_VAL, },
 326                                { 1000, ST_ACCEL_2_ODR_AVL_1000HZ_VAL, },
 327                        },
 328                },
 329                .pw = {
 330                        .addr = ST_ACCEL_2_PW_ADDR,
 331                        .mask = ST_ACCEL_2_PW_MASK,
 332                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 333                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 334                },
 335                .enable_axis = {
 336                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 337                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 338                },
 339                .fs = {
 340                        .addr = ST_ACCEL_2_FS_ADDR,
 341                        .mask = ST_ACCEL_2_FS_MASK,
 342                        .fs_avl = {
 343                                [0] = {
 344                                        .num = ST_ACCEL_FS_AVL_2G,
 345                                        .value = ST_ACCEL_2_FS_AVL_2_VAL,
 346                                        .gain = ST_ACCEL_2_FS_AVL_2_GAIN,
 347                                },
 348                                [1] = {
 349                                        .num = ST_ACCEL_FS_AVL_4G,
 350                                        .value = ST_ACCEL_2_FS_AVL_4_VAL,
 351                                        .gain = ST_ACCEL_2_FS_AVL_4_GAIN,
 352                                },
 353                                [2] = {
 354                                        .num = ST_ACCEL_FS_AVL_8G,
 355                                        .value = ST_ACCEL_2_FS_AVL_8_VAL,
 356                                        .gain = ST_ACCEL_2_FS_AVL_8_GAIN,
 357                                },
 358                        },
 359                },
 360                .bdu = {
 361                        .addr = ST_ACCEL_2_BDU_ADDR,
 362                        .mask = ST_ACCEL_2_BDU_MASK,
 363                },
 364                .drdy_irq = {
 365                        .addr = ST_ACCEL_2_DRDY_IRQ_ADDR,
 366                        .mask_int1 = ST_ACCEL_2_DRDY_IRQ_INT1_MASK,
 367                        .mask_int2 = ST_ACCEL_2_DRDY_IRQ_INT2_MASK,
 368                        .addr_ihl = ST_ACCEL_2_IHL_IRQ_ADDR,
 369                        .mask_ihl = ST_ACCEL_2_IHL_IRQ_MASK,
 370                },
 371                .multi_read_bit = ST_ACCEL_2_MULTIREAD_BIT,
 372                .bootime = 2,
 373        },
 374        {
 375                .wai = ST_ACCEL_3_WAI_EXP,
 376                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 377                .sensors_supported = {
 378                        [0] = LSM330_ACCEL_DEV_NAME,
 379                },
 380                .ch = (struct iio_chan_spec *)st_accel_16bit_channels,
 381                .odr = {
 382                        .addr = ST_ACCEL_3_ODR_ADDR,
 383                        .mask = ST_ACCEL_3_ODR_MASK,
 384                        .odr_avl = {
 385                                { 3, ST_ACCEL_3_ODR_AVL_3HZ_VAL },
 386                                { 6, ST_ACCEL_3_ODR_AVL_6HZ_VAL, },
 387                                { 12, ST_ACCEL_3_ODR_AVL_12HZ_VAL, },
 388                                { 25, ST_ACCEL_3_ODR_AVL_25HZ_VAL, },
 389                                { 50, ST_ACCEL_3_ODR_AVL_50HZ_VAL, },
 390                                { 100, ST_ACCEL_3_ODR_AVL_100HZ_VAL, },
 391                                { 200, ST_ACCEL_3_ODR_AVL_200HZ_VAL, },
 392                                { 400, ST_ACCEL_3_ODR_AVL_400HZ_VAL, },
 393                                { 800, ST_ACCEL_3_ODR_AVL_800HZ_VAL, },
 394                                { 1600, ST_ACCEL_3_ODR_AVL_1600HZ_VAL, },
 395                        },
 396                },
 397                .pw = {
 398                        .addr = ST_ACCEL_3_ODR_ADDR,
 399                        .mask = ST_ACCEL_3_ODR_MASK,
 400                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 401                },
 402                .enable_axis = {
 403                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 404                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 405                },
 406                .fs = {
 407                        .addr = ST_ACCEL_3_FS_ADDR,
 408                        .mask = ST_ACCEL_3_FS_MASK,
 409                        .fs_avl = {
 410                                [0] = {
 411                                        .num = ST_ACCEL_FS_AVL_2G,
 412                                        .value = ST_ACCEL_3_FS_AVL_2_VAL,
 413                                        .gain = ST_ACCEL_3_FS_AVL_2_GAIN,
 414                                },
 415                                [1] = {
 416                                        .num = ST_ACCEL_FS_AVL_4G,
 417                                        .value = ST_ACCEL_3_FS_AVL_4_VAL,
 418                                        .gain = ST_ACCEL_3_FS_AVL_4_GAIN,
 419                                },
 420                                [2] = {
 421                                        .num = ST_ACCEL_FS_AVL_6G,
 422                                        .value = ST_ACCEL_3_FS_AVL_6_VAL,
 423                                        .gain = ST_ACCEL_3_FS_AVL_6_GAIN,
 424                                },
 425                                [3] = {
 426                                        .num = ST_ACCEL_FS_AVL_8G,
 427                                        .value = ST_ACCEL_3_FS_AVL_8_VAL,
 428                                        .gain = ST_ACCEL_3_FS_AVL_8_GAIN,
 429                                },
 430                                [4] = {
 431                                        .num = ST_ACCEL_FS_AVL_16G,
 432                                        .value = ST_ACCEL_3_FS_AVL_16_VAL,
 433                                        .gain = ST_ACCEL_3_FS_AVL_16_GAIN,
 434                                },
 435                        },
 436                },
 437                .bdu = {
 438                        .addr = ST_ACCEL_3_BDU_ADDR,
 439                        .mask = ST_ACCEL_3_BDU_MASK,
 440                },
 441                .drdy_irq = {
 442                        .addr = ST_ACCEL_3_DRDY_IRQ_ADDR,
 443                        .mask_int1 = ST_ACCEL_3_DRDY_IRQ_INT1_MASK,
 444                        .mask_int2 = ST_ACCEL_3_DRDY_IRQ_INT2_MASK,
 445                        .addr_ihl = ST_ACCEL_3_IHL_IRQ_ADDR,
 446                        .mask_ihl = ST_ACCEL_3_IHL_IRQ_MASK,
 447                        .ig1 = {
 448                                .en_addr = ST_ACCEL_3_IG1_EN_ADDR,
 449                                .en_mask = ST_ACCEL_3_IG1_EN_MASK,
 450                        },
 451                },
 452                .multi_read_bit = ST_ACCEL_3_MULTIREAD_BIT,
 453                .bootime = 2,
 454        },
 455        {
 456                .wai = ST_ACCEL_4_WAI_EXP,
 457                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 458                .sensors_supported = {
 459                        [0] = LIS3LV02DL_ACCEL_DEV_NAME,
 460                },
 461                .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
 462                .odr = {
 463                        .addr = ST_ACCEL_4_ODR_ADDR,
 464                        .mask = ST_ACCEL_4_ODR_MASK,
 465                        .odr_avl = {
 466                                { 40, ST_ACCEL_4_ODR_AVL_40HZ_VAL },
 467                                { 160, ST_ACCEL_4_ODR_AVL_160HZ_VAL, },
 468                                { 640, ST_ACCEL_4_ODR_AVL_640HZ_VAL, },
 469                                { 2560, ST_ACCEL_4_ODR_AVL_2560HZ_VAL, },
 470                        },
 471                },
 472                .pw = {
 473                        .addr = ST_ACCEL_4_PW_ADDR,
 474                        .mask = ST_ACCEL_4_PW_MASK,
 475                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 476                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 477                },
 478                .enable_axis = {
 479                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 480                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 481                },
 482                .fs = {
 483                        .addr = ST_ACCEL_4_FS_ADDR,
 484                        .mask = ST_ACCEL_4_FS_MASK,
 485                        .fs_avl = {
 486                                [0] = {
 487                                        .num = ST_ACCEL_FS_AVL_2G,
 488                                        .value = ST_ACCEL_4_FS_AVL_2_VAL,
 489                                        .gain = ST_ACCEL_4_FS_AVL_2_GAIN,
 490                                },
 491                                [1] = {
 492                                        .num = ST_ACCEL_FS_AVL_6G,
 493                                        .value = ST_ACCEL_4_FS_AVL_6_VAL,
 494                                        .gain = ST_ACCEL_4_FS_AVL_6_GAIN,
 495                                },
 496                        },
 497                },
 498                .bdu = {
 499                        .addr = ST_ACCEL_4_BDU_ADDR,
 500                        .mask = ST_ACCEL_4_BDU_MASK,
 501                },
 502                .drdy_irq = {
 503                        .addr = ST_ACCEL_4_DRDY_IRQ_ADDR,
 504                        .mask_int1 = ST_ACCEL_4_DRDY_IRQ_INT1_MASK,
 505                },
 506                .multi_read_bit = ST_ACCEL_4_MULTIREAD_BIT,
 507                .bootime = 2, /* guess */
 508        },
 509        {
 510                .wai = ST_ACCEL_5_WAI_EXP,
 511                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 512                .sensors_supported = {
 513                        [0] = LIS331DL_ACCEL_DEV_NAME,
 514                },
 515                .ch = (struct iio_chan_spec *)st_accel_8bit_channels,
 516                .odr = {
 517                        .addr = ST_ACCEL_5_ODR_ADDR,
 518                        .mask = ST_ACCEL_5_ODR_MASK,
 519                        .odr_avl = {
 520                                { 100, ST_ACCEL_5_ODR_AVL_100HZ_VAL },
 521                                { 400, ST_ACCEL_5_ODR_AVL_400HZ_VAL, },
 522                        },
 523                },
 524                .pw = {
 525                        .addr = ST_ACCEL_5_PW_ADDR,
 526                        .mask = ST_ACCEL_5_PW_MASK,
 527                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 528                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 529                },
 530                .enable_axis = {
 531                        .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
 532                        .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
 533                },
 534                .fs = {
 535                        .addr = ST_ACCEL_5_FS_ADDR,
 536                        .mask = ST_ACCEL_5_FS_MASK,
 537                        .fs_avl = {
 538                                [0] = {
 539                                        .num = ST_ACCEL_FS_AVL_2G,
 540                                        .value = ST_ACCEL_5_FS_AVL_2_VAL,
 541                                        .gain = ST_ACCEL_5_FS_AVL_2_GAIN,
 542                                },
 543                                [1] = {
 544                                        .num = ST_ACCEL_FS_AVL_8G,
 545                                        .value = ST_ACCEL_5_FS_AVL_8_VAL,
 546                                        .gain = ST_ACCEL_5_FS_AVL_8_GAIN,
 547                                },
 548                        },
 549                },
 550                .drdy_irq = {
 551                        .addr = ST_ACCEL_5_DRDY_IRQ_ADDR,
 552                        .mask_int1 = ST_ACCEL_5_DRDY_IRQ_INT1_MASK,
 553                        .mask_int2 = ST_ACCEL_5_DRDY_IRQ_INT2_MASK,
 554                        .addr_ihl = ST_ACCEL_5_IHL_IRQ_ADDR,
 555                        .mask_ihl = ST_ACCEL_5_IHL_IRQ_MASK,
 556                },
 557                .multi_read_bit = ST_ACCEL_5_MULTIREAD_BIT,
 558                .bootime = 2, /* guess */
 559        },
 560};
 561
 562static int st_accel_read_raw(struct iio_dev *indio_dev,
 563                        struct iio_chan_spec const *ch, int *val,
 564                                                        int *val2, long mask)
 565{
 566        int err;
 567        struct st_sensor_data *adata = iio_priv(indio_dev);
 568
 569        switch (mask) {
 570        case IIO_CHAN_INFO_RAW:
 571                err = st_sensors_read_info_raw(indio_dev, ch, val);
 572                if (err < 0)
 573                        goto read_error;
 574
 575                return IIO_VAL_INT;
 576        case IIO_CHAN_INFO_SCALE:
 577                *val = 0;
 578                *val2 = adata->current_fullscale->gain;
 579                return IIO_VAL_INT_PLUS_MICRO;
 580        case IIO_CHAN_INFO_SAMP_FREQ:
 581                *val = adata->odr;
 582                return IIO_VAL_INT;
 583        default:
 584                return -EINVAL;
 585        }
 586
 587read_error:
 588        return err;
 589}
 590
 591static int st_accel_write_raw(struct iio_dev *indio_dev,
 592                struct iio_chan_spec const *chan, int val, int val2, long mask)
 593{
 594        int err;
 595
 596        switch (mask) {
 597        case IIO_CHAN_INFO_SCALE:
 598                err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
 599                break;
 600        case IIO_CHAN_INFO_SAMP_FREQ:
 601                if (val2)
 602                        return -EINVAL;
 603                mutex_lock(&indio_dev->mlock);
 604                err = st_sensors_set_odr(indio_dev, val);
 605                mutex_unlock(&indio_dev->mlock);
 606                return err;
 607        default:
 608                return -EINVAL;
 609        }
 610
 611        return err;
 612}
 613
 614static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
 615static ST_SENSORS_DEV_ATTR_SCALE_AVAIL(in_accel_scale_available);
 616
 617static struct attribute *st_accel_attributes[] = {
 618        &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
 619        &iio_dev_attr_in_accel_scale_available.dev_attr.attr,
 620        NULL,
 621};
 622
 623static const struct attribute_group st_accel_attribute_group = {
 624        .attrs = st_accel_attributes,
 625};
 626
 627static const struct iio_info accel_info = {
 628        .driver_module = THIS_MODULE,
 629        .attrs = &st_accel_attribute_group,
 630        .read_raw = &st_accel_read_raw,
 631        .write_raw = &st_accel_write_raw,
 632        .debugfs_reg_access = &st_sensors_debugfs_reg_access,
 633};
 634
 635#ifdef CONFIG_IIO_TRIGGER
 636static const struct iio_trigger_ops st_accel_trigger_ops = {
 637        .owner = THIS_MODULE,
 638        .set_trigger_state = ST_ACCEL_TRIGGER_SET_STATE,
 639};
 640#define ST_ACCEL_TRIGGER_OPS (&st_accel_trigger_ops)
 641#else
 642#define ST_ACCEL_TRIGGER_OPS NULL
 643#endif
 644
 645int st_accel_common_probe(struct iio_dev *indio_dev)
 646{
 647        struct st_sensor_data *adata = iio_priv(indio_dev);
 648        int irq = adata->get_irq_data_ready(indio_dev);
 649        int err;
 650
 651        indio_dev->modes = INDIO_DIRECT_MODE;
 652        indio_dev->info = &accel_info;
 653        mutex_init(&adata->tb.buf_lock);
 654
 655        st_sensors_power_enable(indio_dev);
 656
 657        err = st_sensors_check_device_support(indio_dev,
 658                                        ARRAY_SIZE(st_accel_sensors_settings),
 659                                        st_accel_sensors_settings);
 660        if (err < 0)
 661                return err;
 662
 663        adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS;
 664        adata->multiread_bit = adata->sensor_settings->multi_read_bit;
 665        indio_dev->channels = adata->sensor_settings->ch;
 666        indio_dev->num_channels = ST_SENSORS_NUMBER_ALL_CHANNELS;
 667
 668        adata->current_fullscale = (struct st_sensor_fullscale_avl *)
 669                                        &adata->sensor_settings->fs.fs_avl[0];
 670        adata->odr = adata->sensor_settings->odr.odr_avl[0].hz;
 671
 672        if (!adata->dev->platform_data)
 673                adata->dev->platform_data =
 674                        (struct st_sensors_platform_data *)&default_accel_pdata;
 675
 676        err = st_sensors_init_sensor(indio_dev, adata->dev->platform_data);
 677        if (err < 0)
 678                return err;
 679
 680        err = st_accel_allocate_ring(indio_dev);
 681        if (err < 0)
 682                return err;
 683
 684        if (irq > 0) {
 685                err = st_sensors_allocate_trigger(indio_dev,
 686                                                 ST_ACCEL_TRIGGER_OPS);
 687                if (err < 0)
 688                        goto st_accel_probe_trigger_error;
 689        }
 690
 691        err = iio_device_register(indio_dev);
 692        if (err)
 693                goto st_accel_device_register_error;
 694
 695        dev_info(&indio_dev->dev, "registered accelerometer %s\n",
 696                 indio_dev->name);
 697
 698        return 0;
 699
 700st_accel_device_register_error:
 701        if (irq > 0)
 702                st_sensors_deallocate_trigger(indio_dev);
 703st_accel_probe_trigger_error:
 704        st_accel_deallocate_ring(indio_dev);
 705
 706        return err;
 707}
 708EXPORT_SYMBOL(st_accel_common_probe);
 709
 710void st_accel_common_remove(struct iio_dev *indio_dev)
 711{
 712        struct st_sensor_data *adata = iio_priv(indio_dev);
 713
 714        st_sensors_power_disable(indio_dev);
 715
 716        iio_device_unregister(indio_dev);
 717        if (adata->get_irq_data_ready(indio_dev) > 0)
 718                st_sensors_deallocate_trigger(indio_dev);
 719
 720        st_accel_deallocate_ring(indio_dev);
 721}
 722EXPORT_SYMBOL(st_accel_common_remove);
 723
 724MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
 725MODULE_DESCRIPTION("STMicroelectronics accelerometers driver");
 726MODULE_LICENSE("GPL v2");
 727