root/drivers/iio/pressure/st_pressure_core.c

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

DEFINITIONS

This source file includes following definitions.
  1. st_press_write_raw
  2. st_press_read_raw
  3. st_press_get_settings
  4. st_press_common_probe
  5. st_press_common_remove

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

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