linux/drivers/iio/pressure/st_pressure_core.c
<<
>>
Prefs
   1/*
   2 * STMicroelectronics pressures driver
   3 *
   4 * Copyright 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/delay.h>
  22#include <linux/iio/iio.h>
  23#include <linux/iio/sysfs.h>
  24#include <linux/iio/trigger.h>
  25#include <linux/iio/buffer.h>
  26#include <asm/unaligned.h>
  27
  28#include <linux/iio/common/st_sensors.h>
  29#include "st_pressure.h"
  30
  31/*
  32 * About determining pressure scaling factors
  33 * ------------------------------------------
  34 *
  35 * Datasheets specify typical pressure sensitivity so that pressure is computed
  36 * according to the following equation :
  37 *     pressure[mBar] = raw / sensitivity
  38 * where :
  39 *     raw          the 24 bits long raw sampled pressure
  40 *     sensitivity  a scaling factor specified by the datasheet in LSB/mBar
  41 *
  42 * IIO ABI expects pressure to be expressed as kPascal, hence pressure should be
  43 * computed according to :
  44 *     pressure[kPascal] = pressure[mBar] / 10
  45 *                       = raw / (sensitivity * 10)                          (1)
  46 *
  47 * Finally, st_press_read_raw() returns pressure scaling factor as an
  48 * IIO_VAL_INT_PLUS_NANO with a zero integral part and "gain" as decimal part.
  49 * Therefore, from (1), "gain" becomes :
  50 *     gain = 10^9 / (sensitivity * 10)
  51 *          = 10^8 / sensitivity
  52 *
  53 * About determining temperature scaling factors and offsets
  54 * ---------------------------------------------------------
  55 *
  56 * Datasheets specify typical temperature sensitivity and offset so that
  57 * temperature is computed according to the following equation :
  58 *     temp[Celsius] = offset[Celsius] + (raw / sensitivity)
  59 * where :
  60 *     raw          the 16 bits long raw sampled temperature
  61 *     offset       a constant specified by the datasheet in degree Celsius
  62 *                  (sometimes zero)
  63 *     sensitivity  a scaling factor specified by the datasheet in LSB/Celsius
  64 *
  65 * IIO ABI expects temperature to be expressed as milli degree Celsius such as
  66 * user space should compute temperature according to :
  67 *     temp[mCelsius] = temp[Celsius] * 10^3
  68 *                    = (offset[Celsius] + (raw / sensitivity)) * 10^3
  69 *                    = ((offset[Celsius] * sensitivity) + raw) *
  70 *                      (10^3 / sensitivity)                                 (2)
  71 *
  72 * IIO ABI expects user space to apply offset and scaling factors to raw samples
  73 * according to :
  74 *     temp[mCelsius] = (OFFSET + raw) * SCALE
  75 * where :
  76 *     OFFSET an arbitrary constant exposed by device
  77 *     SCALE  an arbitrary scaling factor exposed by device
  78 *
  79 * Matching OFFSET and SCALE with members of (2) gives :
  80 *     OFFSET = offset[Celsius] * sensitivity                                (3)
  81 *     SCALE  = 10^3 / sensitivity                                           (4)
  82 *
  83 * st_press_read_raw() returns temperature scaling factor as an
  84 * IIO_VAL_FRACTIONAL with a 10^3 numerator and "gain2" as denominator.
  85 * Therefore, from (3), "gain2" becomes :
  86 *     gain2 = sensitivity
  87 *
  88 * When declared within channel, i.e. for a non zero specified offset,
  89 * st_press_read_raw() will return the latter as an IIO_VAL_FRACTIONAL such as :
  90 *     numerator = OFFSET * 10^3
  91 *     denominator = 10^3
  92 * giving from (4):
  93 *     numerator = offset[Celsius] * 10^3 * sensitivity
  94 *               = offset[mCelsius] * gain2
  95 */
  96
  97#define MCELSIUS_PER_CELSIUS                    1000
  98
  99/* Default pressure sensitivity */
 100#define ST_PRESS_LSB_PER_MBAR                   4096UL
 101#define ST_PRESS_KPASCAL_NANO_SCALE             (100000000UL / \
 102                                                 ST_PRESS_LSB_PER_MBAR)
 103
 104/* Default temperature sensitivity */
 105#define ST_PRESS_LSB_PER_CELSIUS                480UL
 106#define ST_PRESS_MILLI_CELSIUS_OFFSET           42500UL
 107
 108/* FULLSCALE */
 109#define ST_PRESS_FS_AVL_1100MB                  1100
 110#define ST_PRESS_FS_AVL_1260MB                  1260
 111
 112#define ST_PRESS_1_OUT_XL_ADDR                  0x28
 113#define ST_TEMP_1_OUT_L_ADDR                    0x2b
 114
 115/*
 116 * CUSTOM VALUES FOR LPS331AP SENSOR
 117 * See LPS331AP datasheet:
 118 * http://www2.st.com/resource/en/datasheet/lps331ap.pdf
 119 */
 120#define ST_PRESS_LPS331AP_WAI_EXP               0xbb
 121#define ST_PRESS_LPS331AP_ODR_ADDR              0x20
 122#define ST_PRESS_LPS331AP_ODR_MASK              0x70
 123#define ST_PRESS_LPS331AP_ODR_AVL_1HZ_VAL       0x01
 124#define ST_PRESS_LPS331AP_ODR_AVL_7HZ_VAL       0x05
 125#define ST_PRESS_LPS331AP_ODR_AVL_13HZ_VAL      0x06
 126#define ST_PRESS_LPS331AP_ODR_AVL_25HZ_VAL      0x07
 127#define ST_PRESS_LPS331AP_PW_ADDR               0x20
 128#define ST_PRESS_LPS331AP_PW_MASK               0x80
 129#define ST_PRESS_LPS331AP_FS_ADDR               0x23
 130#define ST_PRESS_LPS331AP_FS_MASK               0x30
 131#define ST_PRESS_LPS331AP_BDU_ADDR              0x20
 132#define ST_PRESS_LPS331AP_BDU_MASK              0x04
 133#define ST_PRESS_LPS331AP_DRDY_IRQ_ADDR         0x22
 134#define ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK    0x04
 135#define ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK    0x20
 136#define ST_PRESS_LPS331AP_IHL_IRQ_ADDR          0x22
 137#define ST_PRESS_LPS331AP_IHL_IRQ_MASK          0x80
 138#define ST_PRESS_LPS331AP_OD_IRQ_ADDR           0x22
 139#define ST_PRESS_LPS331AP_OD_IRQ_MASK           0x40
 140#define ST_PRESS_LPS331AP_MULTIREAD_BIT         true
 141
 142/*
 143 * CUSTOM VALUES FOR THE OBSOLETE LPS001WP SENSOR
 144 */
 145
 146/* LPS001WP pressure resolution */
 147#define ST_PRESS_LPS001WP_LSB_PER_MBAR          16UL
 148/* LPS001WP temperature resolution */
 149#define ST_PRESS_LPS001WP_LSB_PER_CELSIUS       64UL
 150
 151#define ST_PRESS_LPS001WP_WAI_EXP               0xba
 152#define ST_PRESS_LPS001WP_ODR_ADDR              0x20
 153#define ST_PRESS_LPS001WP_ODR_MASK              0x30
 154#define ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL       0x01
 155#define ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL       0x02
 156#define ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL      0x03
 157#define ST_PRESS_LPS001WP_PW_ADDR               0x20
 158#define ST_PRESS_LPS001WP_PW_MASK               0x40
 159#define ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN \
 160        (100000000UL / ST_PRESS_LPS001WP_LSB_PER_MBAR)
 161#define ST_PRESS_LPS001WP_BDU_ADDR              0x20
 162#define ST_PRESS_LPS001WP_BDU_MASK              0x04
 163#define ST_PRESS_LPS001WP_MULTIREAD_BIT         true
 164#define ST_PRESS_LPS001WP_OUT_L_ADDR            0x28
 165#define ST_TEMP_LPS001WP_OUT_L_ADDR             0x2a
 166
 167/*
 168 * CUSTOM VALUES FOR LPS25H SENSOR
 169 * See LPS25H datasheet:
 170 * http://www2.st.com/resource/en/datasheet/lps25h.pdf
 171 */
 172#define ST_PRESS_LPS25H_WAI_EXP                 0xbd
 173#define ST_PRESS_LPS25H_ODR_ADDR                0x20
 174#define ST_PRESS_LPS25H_ODR_MASK                0x70
 175#define ST_PRESS_LPS25H_ODR_AVL_1HZ_VAL         0x01
 176#define ST_PRESS_LPS25H_ODR_AVL_7HZ_VAL         0x02
 177#define ST_PRESS_LPS25H_ODR_AVL_13HZ_VAL        0x03
 178#define ST_PRESS_LPS25H_ODR_AVL_25HZ_VAL        0x04
 179#define ST_PRESS_LPS25H_PW_ADDR                 0x20
 180#define ST_PRESS_LPS25H_PW_MASK                 0x80
 181#define ST_PRESS_LPS25H_BDU_ADDR                0x20
 182#define ST_PRESS_LPS25H_BDU_MASK                0x04
 183#define ST_PRESS_LPS25H_DRDY_IRQ_ADDR           0x23
 184#define ST_PRESS_LPS25H_DRDY_IRQ_INT1_MASK      0x01
 185#define ST_PRESS_LPS25H_DRDY_IRQ_INT2_MASK      0x10
 186#define ST_PRESS_LPS25H_IHL_IRQ_ADDR            0x22
 187#define ST_PRESS_LPS25H_IHL_IRQ_MASK            0x80
 188#define ST_PRESS_LPS25H_OD_IRQ_ADDR             0x22
 189#define ST_PRESS_LPS25H_OD_IRQ_MASK             0x40
 190#define ST_PRESS_LPS25H_MULTIREAD_BIT           true
 191#define ST_PRESS_LPS25H_OUT_XL_ADDR             0x28
 192#define ST_TEMP_LPS25H_OUT_L_ADDR               0x2b
 193
 194/*
 195 * CUSTOM VALUES FOR LPS22HB SENSOR
 196 * See LPS22HB datasheet:
 197 * http://www2.st.com/resource/en/datasheet/lps22hb.pdf
 198 */
 199
 200/* LPS22HB temperature sensitivity */
 201#define ST_PRESS_LPS22HB_LSB_PER_CELSIUS        100UL
 202
 203#define ST_PRESS_LPS22HB_WAI_EXP                0xb1
 204#define ST_PRESS_LPS22HB_ODR_ADDR               0x10
 205#define ST_PRESS_LPS22HB_ODR_MASK               0x70
 206#define ST_PRESS_LPS22HB_ODR_AVL_1HZ_VAL        0x01
 207#define ST_PRESS_LPS22HB_ODR_AVL_10HZ_VAL       0x02
 208#define ST_PRESS_LPS22HB_ODR_AVL_25HZ_VAL       0x03
 209#define ST_PRESS_LPS22HB_ODR_AVL_50HZ_VAL       0x04
 210#define ST_PRESS_LPS22HB_ODR_AVL_75HZ_VAL       0x05
 211#define ST_PRESS_LPS22HB_PW_ADDR                0x10
 212#define ST_PRESS_LPS22HB_PW_MASK                0x70
 213#define ST_PRESS_LPS22HB_BDU_ADDR               0x10
 214#define ST_PRESS_LPS22HB_BDU_MASK               0x02
 215#define ST_PRESS_LPS22HB_DRDY_IRQ_ADDR          0x12
 216#define ST_PRESS_LPS22HB_DRDY_IRQ_INT1_MASK     0x04
 217#define ST_PRESS_LPS22HB_DRDY_IRQ_INT2_MASK     0x08
 218#define ST_PRESS_LPS22HB_IHL_IRQ_ADDR           0x12
 219#define ST_PRESS_LPS22HB_IHL_IRQ_MASK           0x80
 220#define ST_PRESS_LPS22HB_OD_IRQ_ADDR            0x12
 221#define ST_PRESS_LPS22HB_OD_IRQ_MASK            0x40
 222#define ST_PRESS_LPS22HB_MULTIREAD_BIT          true
 223
 224static const struct iio_chan_spec st_press_1_channels[] = {
 225        {
 226                .type = IIO_PRESSURE,
 227                .address = ST_PRESS_1_OUT_XL_ADDR,
 228                .scan_index = 0,
 229                .scan_type = {
 230                        .sign = 'u',
 231                        .realbits = 24,
 232                        .storagebits = 32,
 233                        .endianness = IIO_LE,
 234                },
 235                .info_mask_separate =
 236                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
 237        },
 238        {
 239                .type = IIO_TEMP,
 240                .address = ST_TEMP_1_OUT_L_ADDR,
 241                .scan_index = 1,
 242                .scan_type = {
 243                        .sign = 'u',
 244                        .realbits = 16,
 245                        .storagebits = 16,
 246                        .endianness = IIO_LE,
 247                },
 248                .info_mask_separate =
 249                        BIT(IIO_CHAN_INFO_RAW) |
 250                        BIT(IIO_CHAN_INFO_SCALE) |
 251                        BIT(IIO_CHAN_INFO_OFFSET),
 252        },
 253        IIO_CHAN_SOFT_TIMESTAMP(2)
 254};
 255
 256static const struct iio_chan_spec st_press_lps001wp_channels[] = {
 257        {
 258                .type = IIO_PRESSURE,
 259                .address = ST_PRESS_LPS001WP_OUT_L_ADDR,
 260                .scan_index = 0,
 261                .scan_type = {
 262                        .sign = 'u',
 263                        .realbits = 16,
 264                        .storagebits = 16,
 265                        .endianness = IIO_LE,
 266                },
 267                .info_mask_separate =
 268                        BIT(IIO_CHAN_INFO_RAW) |
 269                        BIT(IIO_CHAN_INFO_SCALE),
 270        },
 271        {
 272                .type = IIO_TEMP,
 273                .address = ST_TEMP_LPS001WP_OUT_L_ADDR,
 274                .scan_index = 1,
 275                .scan_type = {
 276                        .sign = 'u',
 277                        .realbits = 16,
 278                        .storagebits = 16,
 279                        .endianness = IIO_LE,
 280                },
 281                .info_mask_separate =
 282                        BIT(IIO_CHAN_INFO_RAW) |
 283                        BIT(IIO_CHAN_INFO_SCALE),
 284        },
 285        IIO_CHAN_SOFT_TIMESTAMP(2)
 286};
 287
 288static const struct iio_chan_spec st_press_lps22hb_channels[] = {
 289        {
 290                .type = IIO_PRESSURE,
 291                .address = ST_PRESS_1_OUT_XL_ADDR,
 292                .scan_index = 0,
 293                .scan_type = {
 294                        .sign = 'u',
 295                        .realbits = 24,
 296                        .storagebits = 32,
 297                        .endianness = IIO_LE,
 298                },
 299                .info_mask_separate =
 300                        BIT(IIO_CHAN_INFO_RAW) |
 301                        BIT(IIO_CHAN_INFO_SCALE),
 302                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 303        },
 304        {
 305                .type = IIO_TEMP,
 306                .address = ST_TEMP_1_OUT_L_ADDR,
 307                .scan_index = 1,
 308                .scan_type = {
 309                        .sign = 's',
 310                        .realbits = 16,
 311                        .storagebits = 16,
 312                        .endianness = IIO_LE,
 313                },
 314                .info_mask_separate =
 315                        BIT(IIO_CHAN_INFO_RAW) |
 316                        BIT(IIO_CHAN_INFO_SCALE),
 317                .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
 318        },
 319        IIO_CHAN_SOFT_TIMESTAMP(2)
 320};
 321
 322static const struct st_sensor_settings st_press_sensors_settings[] = {
 323        {
 324                .wai = ST_PRESS_LPS331AP_WAI_EXP,
 325                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 326                .sensors_supported = {
 327                        [0] = LPS331AP_PRESS_DEV_NAME,
 328                },
 329                .ch = (struct iio_chan_spec *)st_press_1_channels,
 330                .num_ch = ARRAY_SIZE(st_press_1_channels),
 331                .odr = {
 332                        .addr = ST_PRESS_LPS331AP_ODR_ADDR,
 333                        .mask = ST_PRESS_LPS331AP_ODR_MASK,
 334                        .odr_avl = {
 335                                { 1, ST_PRESS_LPS331AP_ODR_AVL_1HZ_VAL, },
 336                                { 7, ST_PRESS_LPS331AP_ODR_AVL_7HZ_VAL, },
 337                                { 13, ST_PRESS_LPS331AP_ODR_AVL_13HZ_VAL, },
 338                                { 25, ST_PRESS_LPS331AP_ODR_AVL_25HZ_VAL, },
 339                        },
 340                },
 341                .pw = {
 342                        .addr = ST_PRESS_LPS331AP_PW_ADDR,
 343                        .mask = ST_PRESS_LPS331AP_PW_MASK,
 344                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 345                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 346                },
 347                .fs = {
 348                        .addr = ST_PRESS_LPS331AP_FS_ADDR,
 349                        .mask = ST_PRESS_LPS331AP_FS_MASK,
 350                        .fs_avl = {
 351                                /*
 352                                 * Pressure and temperature sensitivity values
 353                                 * as defined in table 3 of LPS331AP datasheet.
 354                                 */
 355                                [0] = {
 356                                        .num = ST_PRESS_FS_AVL_1260MB,
 357                                        .gain = ST_PRESS_KPASCAL_NANO_SCALE,
 358                                        .gain2 = ST_PRESS_LSB_PER_CELSIUS,
 359                                },
 360                        },
 361                },
 362                .bdu = {
 363                        .addr = ST_PRESS_LPS331AP_BDU_ADDR,
 364                        .mask = ST_PRESS_LPS331AP_BDU_MASK,
 365                },
 366                .drdy_irq = {
 367                        .addr = ST_PRESS_LPS331AP_DRDY_IRQ_ADDR,
 368                        .mask_int1 = ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK,
 369                        .mask_int2 = ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK,
 370                        .addr_ihl = ST_PRESS_LPS331AP_IHL_IRQ_ADDR,
 371                        .mask_ihl = ST_PRESS_LPS331AP_IHL_IRQ_MASK,
 372                        .addr_od = ST_PRESS_LPS331AP_OD_IRQ_ADDR,
 373                        .mask_od = ST_PRESS_LPS331AP_OD_IRQ_MASK,
 374                        .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
 375                },
 376                .multi_read_bit = ST_PRESS_LPS331AP_MULTIREAD_BIT,
 377                .bootime = 2,
 378        },
 379        {
 380                .wai = ST_PRESS_LPS001WP_WAI_EXP,
 381                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 382                .sensors_supported = {
 383                        [0] = LPS001WP_PRESS_DEV_NAME,
 384                },
 385                .ch = (struct iio_chan_spec *)st_press_lps001wp_channels,
 386                .num_ch = ARRAY_SIZE(st_press_lps001wp_channels),
 387                .odr = {
 388                        .addr = ST_PRESS_LPS001WP_ODR_ADDR,
 389                        .mask = ST_PRESS_LPS001WP_ODR_MASK,
 390                        .odr_avl = {
 391                                { 1, ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL, },
 392                                { 7, ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL, },
 393                                { 13, ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL, },
 394                        },
 395                },
 396                .pw = {
 397                        .addr = ST_PRESS_LPS001WP_PW_ADDR,
 398                        .mask = ST_PRESS_LPS001WP_PW_MASK,
 399                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 400                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 401                },
 402                .fs = {
 403                        .fs_avl = {
 404                                /*
 405                                 * Pressure and temperature resolution values
 406                                 * as defined in table 3 of LPS001WP datasheet.
 407                                 */
 408                                [0] = {
 409                                        .num = ST_PRESS_FS_AVL_1100MB,
 410                                        .gain = ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN,
 411                                        .gain2 = ST_PRESS_LPS001WP_LSB_PER_CELSIUS,
 412                                },
 413                        },
 414                },
 415                .bdu = {
 416                        .addr = ST_PRESS_LPS001WP_BDU_ADDR,
 417                        .mask = ST_PRESS_LPS001WP_BDU_MASK,
 418                },
 419                .drdy_irq = {
 420                        .addr = 0,
 421                },
 422                .multi_read_bit = ST_PRESS_LPS001WP_MULTIREAD_BIT,
 423                .bootime = 2,
 424        },
 425        {
 426                .wai = ST_PRESS_LPS25H_WAI_EXP,
 427                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 428                .sensors_supported = {
 429                        [0] = LPS25H_PRESS_DEV_NAME,
 430                },
 431                .ch = (struct iio_chan_spec *)st_press_1_channels,
 432                .num_ch = ARRAY_SIZE(st_press_1_channels),
 433                .odr = {
 434                        .addr = ST_PRESS_LPS25H_ODR_ADDR,
 435                        .mask = ST_PRESS_LPS25H_ODR_MASK,
 436                        .odr_avl = {
 437                                { 1, ST_PRESS_LPS25H_ODR_AVL_1HZ_VAL, },
 438                                { 7, ST_PRESS_LPS25H_ODR_AVL_7HZ_VAL, },
 439                                { 13, ST_PRESS_LPS25H_ODR_AVL_13HZ_VAL, },
 440                                { 25, ST_PRESS_LPS25H_ODR_AVL_25HZ_VAL, },
 441                        },
 442                },
 443                .pw = {
 444                        .addr = ST_PRESS_LPS25H_PW_ADDR,
 445                        .mask = ST_PRESS_LPS25H_PW_MASK,
 446                        .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
 447                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 448                },
 449                .fs = {
 450                        .fs_avl = {
 451                                /*
 452                                 * Pressure and temperature sensitivity values
 453                                 * as defined in table 3 of LPS25H datasheet.
 454                                 */
 455                                [0] = {
 456                                        .num = ST_PRESS_FS_AVL_1260MB,
 457                                        .gain = ST_PRESS_KPASCAL_NANO_SCALE,
 458                                        .gain2 = ST_PRESS_LSB_PER_CELSIUS,
 459                                },
 460                        },
 461                },
 462                .bdu = {
 463                        .addr = ST_PRESS_LPS25H_BDU_ADDR,
 464                        .mask = ST_PRESS_LPS25H_BDU_MASK,
 465                },
 466                .drdy_irq = {
 467                        .addr = ST_PRESS_LPS25H_DRDY_IRQ_ADDR,
 468                        .mask_int1 = ST_PRESS_LPS25H_DRDY_IRQ_INT1_MASK,
 469                        .mask_int2 = ST_PRESS_LPS25H_DRDY_IRQ_INT2_MASK,
 470                        .addr_ihl = ST_PRESS_LPS25H_IHL_IRQ_ADDR,
 471                        .mask_ihl = ST_PRESS_LPS25H_IHL_IRQ_MASK,
 472                        .addr_od = ST_PRESS_LPS25H_OD_IRQ_ADDR,
 473                        .mask_od = ST_PRESS_LPS25H_OD_IRQ_MASK,
 474                        .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
 475                },
 476                .multi_read_bit = ST_PRESS_LPS25H_MULTIREAD_BIT,
 477                .bootime = 2,
 478        },
 479        {
 480                .wai = ST_PRESS_LPS22HB_WAI_EXP,
 481                .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
 482                .sensors_supported = {
 483                        [0] = LPS22HB_PRESS_DEV_NAME,
 484                },
 485                .ch = (struct iio_chan_spec *)st_press_lps22hb_channels,
 486                .num_ch = ARRAY_SIZE(st_press_lps22hb_channels),
 487                .odr = {
 488                        .addr = ST_PRESS_LPS22HB_ODR_ADDR,
 489                        .mask = ST_PRESS_LPS22HB_ODR_MASK,
 490                        .odr_avl = {
 491                                { 1, ST_PRESS_LPS22HB_ODR_AVL_1HZ_VAL, },
 492                                { 10, ST_PRESS_LPS22HB_ODR_AVL_10HZ_VAL, },
 493                                { 25, ST_PRESS_LPS22HB_ODR_AVL_25HZ_VAL, },
 494                                { 50, ST_PRESS_LPS22HB_ODR_AVL_50HZ_VAL, },
 495                                { 75, ST_PRESS_LPS22HB_ODR_AVL_75HZ_VAL, },
 496                        },
 497                },
 498                .pw = {
 499                        .addr = ST_PRESS_LPS22HB_PW_ADDR,
 500                        .mask = ST_PRESS_LPS22HB_PW_MASK,
 501                        .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
 502                },
 503                .fs = {
 504                        .fs_avl = {
 505                                /*
 506                                 * Pressure and temperature sensitivity values
 507                                 * as defined in table 3 of LPS22HB datasheet.
 508                                 */
 509                                [0] = {
 510                                        .num = ST_PRESS_FS_AVL_1260MB,
 511                                        .gain = ST_PRESS_KPASCAL_NANO_SCALE,
 512                                        .gain2 = ST_PRESS_LPS22HB_LSB_PER_CELSIUS,
 513                                },
 514                        },
 515                },
 516                .bdu = {
 517                        .addr = ST_PRESS_LPS22HB_BDU_ADDR,
 518                        .mask = ST_PRESS_LPS22HB_BDU_MASK,
 519                },
 520                .drdy_irq = {
 521                        .addr = ST_PRESS_LPS22HB_DRDY_IRQ_ADDR,
 522                        .mask_int1 = ST_PRESS_LPS22HB_DRDY_IRQ_INT1_MASK,
 523                        .mask_int2 = ST_PRESS_LPS22HB_DRDY_IRQ_INT2_MASK,
 524                        .addr_ihl = ST_PRESS_LPS22HB_IHL_IRQ_ADDR,
 525                        .mask_ihl = ST_PRESS_LPS22HB_IHL_IRQ_MASK,
 526                        .addr_od = ST_PRESS_LPS22HB_OD_IRQ_ADDR,
 527                        .mask_od = ST_PRESS_LPS22HB_OD_IRQ_MASK,
 528                        .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
 529                },
 530                .multi_read_bit = ST_PRESS_LPS22HB_MULTIREAD_BIT,
 531        },
 532};
 533
 534static int st_press_write_raw(struct iio_dev *indio_dev,
 535                              struct iio_chan_spec const *ch,
 536                              int val,
 537                              int val2,
 538                              long mask)
 539{
 540        int err;
 541
 542        switch (mask) {
 543        case IIO_CHAN_INFO_SAMP_FREQ:
 544                if (val2)
 545                        return -EINVAL;
 546                mutex_lock(&indio_dev->mlock);
 547                err = st_sensors_set_odr(indio_dev, val);
 548                mutex_unlock(&indio_dev->mlock);
 549                return err;
 550        default:
 551                return -EINVAL;
 552        }
 553}
 554
 555static int st_press_read_raw(struct iio_dev *indio_dev,
 556                        struct iio_chan_spec const *ch, int *val,
 557                                                        int *val2, long mask)
 558{
 559        int err;
 560        struct st_sensor_data *press_data = iio_priv(indio_dev);
 561
 562        switch (mask) {
 563        case IIO_CHAN_INFO_RAW:
 564                err = st_sensors_read_info_raw(indio_dev, ch, val);
 565                if (err < 0)
 566                        goto read_error;
 567
 568                return IIO_VAL_INT;
 569        case IIO_CHAN_INFO_SCALE:
 570                switch (ch->type) {
 571                case IIO_PRESSURE:
 572                        *val = 0;
 573                        *val2 = press_data->current_fullscale->gain;
 574                        return IIO_VAL_INT_PLUS_NANO;
 575                case IIO_TEMP:
 576                        *val = MCELSIUS_PER_CELSIUS;
 577                        *val2 = press_data->current_fullscale->gain2;
 578                        return IIO_VAL_FRACTIONAL;
 579                default:
 580                        err = -EINVAL;
 581                        goto read_error;
 582                }
 583
 584        case IIO_CHAN_INFO_OFFSET:
 585                switch (ch->type) {
 586                case IIO_TEMP:
 587                        *val = ST_PRESS_MILLI_CELSIUS_OFFSET *
 588                               press_data->current_fullscale->gain2;
 589                        *val2 = MCELSIUS_PER_CELSIUS;
 590                        break;
 591                default:
 592                        err = -EINVAL;
 593                        goto read_error;
 594                }
 595
 596                return IIO_VAL_FRACTIONAL;
 597        case IIO_CHAN_INFO_SAMP_FREQ:
 598                *val = press_data->odr;
 599                return IIO_VAL_INT;
 600        default:
 601                return -EINVAL;
 602        }
 603
 604read_error:
 605        return err;
 606}
 607
 608static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
 609
 610static struct attribute *st_press_attributes[] = {
 611        &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
 612        NULL,
 613};
 614
 615static const struct attribute_group st_press_attribute_group = {
 616        .attrs = st_press_attributes,
 617};
 618
 619static const struct iio_info press_info = {
 620        .driver_module = THIS_MODULE,
 621        .attrs = &st_press_attribute_group,
 622        .read_raw = &st_press_read_raw,
 623        .write_raw = &st_press_write_raw,
 624        .debugfs_reg_access = &st_sensors_debugfs_reg_access,
 625};
 626
 627#ifdef CONFIG_IIO_TRIGGER
 628static const struct iio_trigger_ops st_press_trigger_ops = {
 629        .owner = THIS_MODULE,
 630        .set_trigger_state = ST_PRESS_TRIGGER_SET_STATE,
 631        .validate_device = st_sensors_validate_device,
 632};
 633#define ST_PRESS_TRIGGER_OPS (&st_press_trigger_ops)
 634#else
 635#define ST_PRESS_TRIGGER_OPS NULL
 636#endif
 637
 638int st_press_common_probe(struct iio_dev *indio_dev)
 639{
 640        struct st_sensor_data *press_data = iio_priv(indio_dev);
 641        int irq = press_data->get_irq_data_ready(indio_dev);
 642        int err;
 643
 644        indio_dev->modes = INDIO_DIRECT_MODE;
 645        indio_dev->info = &press_info;
 646        mutex_init(&press_data->tb.buf_lock);
 647
 648        err = st_sensors_power_enable(indio_dev);
 649        if (err)
 650                return err;
 651
 652        err = st_sensors_check_device_support(indio_dev,
 653                                        ARRAY_SIZE(st_press_sensors_settings),
 654                                        st_press_sensors_settings);
 655        if (err < 0)
 656                goto st_press_power_off;
 657
 658        /*
 659         * Skip timestamping channel while declaring available channels to
 660         * common st_sensor layer. Look at st_sensors_get_buffer_element() to
 661         * see how timestamps are explicitly pushed as last samples block
 662         * element.
 663         */
 664        press_data->num_data_channels = press_data->sensor_settings->num_ch - 1;
 665        press_data->multiread_bit = press_data->sensor_settings->multi_read_bit;
 666        indio_dev->channels = press_data->sensor_settings->ch;
 667        indio_dev->num_channels = press_data->sensor_settings->num_ch;
 668
 669        press_data->current_fullscale =
 670                (struct st_sensor_fullscale_avl *)
 671                        &press_data->sensor_settings->fs.fs_avl[0];
 672
 673        press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz;
 674
 675        /* Some devices don't support a data ready pin. */
 676        if (!press_data->dev->platform_data &&
 677                                press_data->sensor_settings->drdy_irq.addr)
 678                press_data->dev->platform_data =
 679                        (struct st_sensors_platform_data *)&default_press_pdata;
 680
 681        err = st_sensors_init_sensor(indio_dev, press_data->dev->platform_data);
 682        if (err < 0)
 683                goto st_press_power_off;
 684
 685        err = st_press_allocate_ring(indio_dev);
 686        if (err < 0)
 687                goto st_press_power_off;
 688
 689        if (irq > 0) {
 690                err = st_sensors_allocate_trigger(indio_dev,
 691                                                  ST_PRESS_TRIGGER_OPS);
 692                if (err < 0)
 693                        goto st_press_probe_trigger_error;
 694        }
 695
 696        err = iio_device_register(indio_dev);
 697        if (err)
 698                goto st_press_device_register_error;
 699
 700        dev_info(&indio_dev->dev, "registered pressure sensor %s\n",
 701                 indio_dev->name);
 702
 703        return err;
 704
 705st_press_device_register_error:
 706        if (irq > 0)
 707                st_sensors_deallocate_trigger(indio_dev);
 708st_press_probe_trigger_error:
 709        st_press_deallocate_ring(indio_dev);
 710st_press_power_off:
 711        st_sensors_power_disable(indio_dev);
 712
 713        return err;
 714}
 715EXPORT_SYMBOL(st_press_common_probe);
 716
 717void st_press_common_remove(struct iio_dev *indio_dev)
 718{
 719        struct st_sensor_data *press_data = iio_priv(indio_dev);
 720
 721        st_sensors_power_disable(indio_dev);
 722
 723        iio_device_unregister(indio_dev);
 724        if (press_data->get_irq_data_ready(indio_dev) > 0)
 725                st_sensors_deallocate_trigger(indio_dev);
 726
 727        st_press_deallocate_ring(indio_dev);
 728}
 729EXPORT_SYMBOL(st_press_common_remove);
 730
 731MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
 732MODULE_DESCRIPTION("STMicroelectronics pressures driver");
 733MODULE_LICENSE("GPL v2");
 734