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 224 static 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 256 static 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 288 static 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 322 static 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 534 static 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 555 static 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 604 read_error: 605 return err; 606 } 607 608 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL(); 609 610 static struct attribute *st_press_attributes[] = { 611 &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 612 NULL, 613 }; 614 615 static const struct attribute_group st_press_attribute_group = { 616 .attrs = st_press_attributes, 617 }; 618 619 static 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 628 static 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 638 int 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 705 st_press_device_register_error: 706 if (irq > 0) 707 st_sensors_deallocate_trigger(indio_dev); 708 st_press_probe_trigger_error: 709 st_press_deallocate_ring(indio_dev); 710 st_press_power_off: 711 st_sensors_power_disable(indio_dev); 712 713 return err; 714 } 715 EXPORT_SYMBOL(st_press_common_probe); 716 717 void 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 } 729 EXPORT_SYMBOL(st_press_common_remove); 730 731 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>"); 732 MODULE_DESCRIPTION("STMicroelectronics pressures driver"); 733 MODULE_LICENSE("GPL v2"); 734