0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/mutex.h>
0013 #include <linux/sysfs.h>
0014 #include <linux/iio/iio.h>
0015 #include <linux/iio/sysfs.h>
0016 #include <linux/iio/trigger.h>
0017 #include <asm/unaligned.h>
0018
0019 #include <linux/iio/common/st_sensors.h>
0020 #include "st_pressure.h"
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088 #define MCELSIUS_PER_CELSIUS 1000
0089
0090
0091 #define ST_PRESS_LSB_PER_MBAR 4096UL
0092 #define ST_PRESS_KPASCAL_NANO_SCALE (100000000UL / \
0093 ST_PRESS_LSB_PER_MBAR)
0094
0095
0096 #define ST_PRESS_LSB_PER_CELSIUS 480UL
0097 #define ST_PRESS_MILLI_CELSIUS_OFFSET 42500UL
0098
0099
0100 #define ST_PRESS_FS_AVL_1100MB 1100
0101 #define ST_PRESS_FS_AVL_1260MB 1260
0102
0103 #define ST_PRESS_1_OUT_XL_ADDR 0x28
0104 #define ST_TEMP_1_OUT_L_ADDR 0x2b
0105
0106
0107 #define ST_PRESS_LPS001WP_LSB_PER_MBAR 16UL
0108
0109 #define ST_PRESS_LPS001WP_LSB_PER_CELSIUS 64UL
0110
0111 #define ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN \
0112 (100000000UL / ST_PRESS_LPS001WP_LSB_PER_MBAR)
0113
0114 #define ST_PRESS_LPS001WP_OUT_L_ADDR 0x28
0115 #define ST_TEMP_LPS001WP_OUT_L_ADDR 0x2a
0116
0117
0118 #define ST_PRESS_LPS25H_OUT_XL_ADDR 0x28
0119 #define ST_TEMP_LPS25H_OUT_L_ADDR 0x2b
0120
0121
0122 #define ST_PRESS_LPS22HB_LSB_PER_CELSIUS 100UL
0123
0124 static const struct iio_chan_spec st_press_1_channels[] = {
0125 {
0126 .type = IIO_PRESSURE,
0127 .address = ST_PRESS_1_OUT_XL_ADDR,
0128 .scan_index = 0,
0129 .scan_type = {
0130 .sign = 's',
0131 .realbits = 24,
0132 .storagebits = 32,
0133 .endianness = IIO_LE,
0134 },
0135 .info_mask_separate =
0136 BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
0137 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
0138 },
0139 {
0140 .type = IIO_TEMP,
0141 .address = ST_TEMP_1_OUT_L_ADDR,
0142 .scan_index = 1,
0143 .scan_type = {
0144 .sign = 's',
0145 .realbits = 16,
0146 .storagebits = 16,
0147 .endianness = IIO_LE,
0148 },
0149 .info_mask_separate =
0150 BIT(IIO_CHAN_INFO_RAW) |
0151 BIT(IIO_CHAN_INFO_SCALE) |
0152 BIT(IIO_CHAN_INFO_OFFSET),
0153 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
0154 },
0155 IIO_CHAN_SOFT_TIMESTAMP(2)
0156 };
0157
0158 static const struct iio_chan_spec st_press_lps001wp_channels[] = {
0159 {
0160 .type = IIO_PRESSURE,
0161 .address = ST_PRESS_LPS001WP_OUT_L_ADDR,
0162 .scan_index = 0,
0163 .scan_type = {
0164 .sign = 's',
0165 .realbits = 16,
0166 .storagebits = 16,
0167 .endianness = IIO_LE,
0168 },
0169 .info_mask_separate =
0170 BIT(IIO_CHAN_INFO_RAW) |
0171 BIT(IIO_CHAN_INFO_SCALE),
0172 },
0173 {
0174 .type = IIO_TEMP,
0175 .address = ST_TEMP_LPS001WP_OUT_L_ADDR,
0176 .scan_index = 1,
0177 .scan_type = {
0178 .sign = 's',
0179 .realbits = 16,
0180 .storagebits = 16,
0181 .endianness = IIO_LE,
0182 },
0183 .info_mask_separate =
0184 BIT(IIO_CHAN_INFO_RAW) |
0185 BIT(IIO_CHAN_INFO_SCALE),
0186 },
0187 IIO_CHAN_SOFT_TIMESTAMP(2)
0188 };
0189
0190 static const struct iio_chan_spec st_press_lps22hb_channels[] = {
0191 {
0192 .type = IIO_PRESSURE,
0193 .address = ST_PRESS_1_OUT_XL_ADDR,
0194 .scan_index = 0,
0195 .scan_type = {
0196 .sign = 's',
0197 .realbits = 24,
0198 .storagebits = 32,
0199 .endianness = IIO_LE,
0200 },
0201 .info_mask_separate =
0202 BIT(IIO_CHAN_INFO_RAW) |
0203 BIT(IIO_CHAN_INFO_SCALE),
0204 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
0205 },
0206 {
0207 .type = IIO_TEMP,
0208 .address = ST_TEMP_1_OUT_L_ADDR,
0209 .scan_index = 1,
0210 .scan_type = {
0211 .sign = 's',
0212 .realbits = 16,
0213 .storagebits = 16,
0214 .endianness = IIO_LE,
0215 },
0216 .info_mask_separate =
0217 BIT(IIO_CHAN_INFO_RAW) |
0218 BIT(IIO_CHAN_INFO_SCALE),
0219 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
0220 },
0221 IIO_CHAN_SOFT_TIMESTAMP(2)
0222 };
0223
0224 static const struct st_sensor_settings st_press_sensors_settings[] = {
0225 {
0226
0227
0228
0229
0230
0231 .wai = 0xbb,
0232 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
0233 .sensors_supported = {
0234 [0] = LPS331AP_PRESS_DEV_NAME,
0235 },
0236 .ch = (struct iio_chan_spec *)st_press_1_channels,
0237 .num_ch = ARRAY_SIZE(st_press_1_channels),
0238 .odr = {
0239 .addr = 0x20,
0240 .mask = 0x70,
0241 .odr_avl = {
0242 { .hz = 1, .value = 0x01 },
0243 { .hz = 7, .value = 0x05 },
0244 { .hz = 13, .value = 0x06 },
0245 { .hz = 25, .value = 0x07 },
0246 },
0247 },
0248 .pw = {
0249 .addr = 0x20,
0250 .mask = 0x80,
0251 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
0252 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
0253 },
0254 .fs = {
0255 .addr = 0x23,
0256 .mask = 0x30,
0257 .fs_avl = {
0258
0259
0260
0261
0262 [0] = {
0263 .num = ST_PRESS_FS_AVL_1260MB,
0264 .gain = ST_PRESS_KPASCAL_NANO_SCALE,
0265 .gain2 = ST_PRESS_LSB_PER_CELSIUS,
0266 },
0267 },
0268 },
0269 .bdu = {
0270 .addr = 0x20,
0271 .mask = 0x04,
0272 },
0273 .drdy_irq = {
0274 .int1 = {
0275 .addr = 0x22,
0276 .mask = 0x04,
0277 .addr_od = 0x22,
0278 .mask_od = 0x40,
0279 },
0280 .int2 = {
0281 .addr = 0x22,
0282 .mask = 0x20,
0283 .addr_od = 0x22,
0284 .mask_od = 0x40,
0285 },
0286 .addr_ihl = 0x22,
0287 .mask_ihl = 0x80,
0288 .stat_drdy = {
0289 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
0290 .mask = 0x03,
0291 },
0292 },
0293 .sim = {
0294 .addr = 0x20,
0295 .value = BIT(0),
0296 },
0297 .multi_read_bit = true,
0298 .bootime = 2,
0299 },
0300 {
0301
0302
0303
0304 .wai = 0xba,
0305 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
0306 .sensors_supported = {
0307 [0] = LPS001WP_PRESS_DEV_NAME,
0308 },
0309 .ch = (struct iio_chan_spec *)st_press_lps001wp_channels,
0310 .num_ch = ARRAY_SIZE(st_press_lps001wp_channels),
0311 .odr = {
0312 .addr = 0x20,
0313 .mask = 0x30,
0314 .odr_avl = {
0315 { .hz = 1, .value = 0x01 },
0316 { .hz = 7, .value = 0x02 },
0317 { .hz = 13, .value = 0x03 },
0318 },
0319 },
0320 .pw = {
0321 .addr = 0x20,
0322 .mask = 0x40,
0323 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
0324 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
0325 },
0326 .fs = {
0327 .fs_avl = {
0328
0329
0330
0331
0332 [0] = {
0333 .num = ST_PRESS_FS_AVL_1100MB,
0334 .gain = ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN,
0335 .gain2 = ST_PRESS_LPS001WP_LSB_PER_CELSIUS,
0336 },
0337 },
0338 },
0339 .bdu = {
0340 .addr = 0x20,
0341 .mask = 0x04,
0342 },
0343 .sim = {
0344 .addr = 0x20,
0345 .value = BIT(0),
0346 },
0347 .multi_read_bit = true,
0348 .bootime = 2,
0349 },
0350 {
0351
0352
0353
0354
0355
0356 .wai = 0xbd,
0357 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
0358 .sensors_supported = {
0359 [0] = LPS25H_PRESS_DEV_NAME,
0360 },
0361 .ch = (struct iio_chan_spec *)st_press_1_channels,
0362 .num_ch = ARRAY_SIZE(st_press_1_channels),
0363 .odr = {
0364 .addr = 0x20,
0365 .mask = 0x70,
0366 .odr_avl = {
0367 { .hz = 1, .value = 0x01 },
0368 { .hz = 7, .value = 0x02 },
0369 { .hz = 13, .value = 0x03 },
0370 { .hz = 25, .value = 0x04 },
0371 },
0372 },
0373 .pw = {
0374 .addr = 0x20,
0375 .mask = 0x80,
0376 .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
0377 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
0378 },
0379 .fs = {
0380 .fs_avl = {
0381
0382
0383
0384
0385 [0] = {
0386 .num = ST_PRESS_FS_AVL_1260MB,
0387 .gain = ST_PRESS_KPASCAL_NANO_SCALE,
0388 .gain2 = ST_PRESS_LSB_PER_CELSIUS,
0389 },
0390 },
0391 },
0392 .bdu = {
0393 .addr = 0x20,
0394 .mask = 0x04,
0395 },
0396 .drdy_irq = {
0397 .int1 = {
0398 .addr = 0x23,
0399 .mask = 0x01,
0400 .addr_od = 0x22,
0401 .mask_od = 0x40,
0402 },
0403 .addr_ihl = 0x22,
0404 .mask_ihl = 0x80,
0405 .stat_drdy = {
0406 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
0407 .mask = 0x03,
0408 },
0409 },
0410 .sim = {
0411 .addr = 0x20,
0412 .value = BIT(0),
0413 },
0414 .multi_read_bit = true,
0415 .bootime = 2,
0416 },
0417 {
0418
0419
0420
0421
0422
0423 .wai = 0xb1,
0424 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
0425 .sensors_supported = {
0426 [0] = LPS22HB_PRESS_DEV_NAME,
0427 [1] = LPS33HW_PRESS_DEV_NAME,
0428 [2] = LPS35HW_PRESS_DEV_NAME,
0429 },
0430 .ch = (struct iio_chan_spec *)st_press_lps22hb_channels,
0431 .num_ch = ARRAY_SIZE(st_press_lps22hb_channels),
0432 .odr = {
0433 .addr = 0x10,
0434 .mask = 0x70,
0435 .odr_avl = {
0436 { .hz = 1, .value = 0x01 },
0437 { .hz = 10, .value = 0x02 },
0438 { .hz = 25, .value = 0x03 },
0439 { .hz = 50, .value = 0x04 },
0440 { .hz = 75, .value = 0x05 },
0441 },
0442 },
0443 .pw = {
0444 .addr = 0x10,
0445 .mask = 0x70,
0446 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
0447 },
0448 .fs = {
0449 .fs_avl = {
0450
0451
0452
0453
0454 [0] = {
0455 .num = ST_PRESS_FS_AVL_1260MB,
0456 .gain = ST_PRESS_KPASCAL_NANO_SCALE,
0457 .gain2 = ST_PRESS_LPS22HB_LSB_PER_CELSIUS,
0458 },
0459 },
0460 },
0461 .bdu = {
0462 .addr = 0x10,
0463 .mask = 0x02,
0464 },
0465 .drdy_irq = {
0466 .int1 = {
0467 .addr = 0x12,
0468 .mask = 0x04,
0469 .addr_od = 0x12,
0470 .mask_od = 0x40,
0471 },
0472 .addr_ihl = 0x12,
0473 .mask_ihl = 0x80,
0474 .stat_drdy = {
0475 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
0476 .mask = 0x03,
0477 },
0478 },
0479 .sim = {
0480 .addr = 0x10,
0481 .value = BIT(0),
0482 },
0483 .multi_read_bit = false,
0484 .bootime = 2,
0485 },
0486 {
0487
0488
0489
0490
0491
0492 .wai = 0xb3,
0493 .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS,
0494 .sensors_supported = {
0495 [0] = LPS22HH_PRESS_DEV_NAME,
0496 },
0497 .ch = (struct iio_chan_spec *)st_press_lps22hb_channels,
0498 .num_ch = ARRAY_SIZE(st_press_lps22hb_channels),
0499 .odr = {
0500 .addr = 0x10,
0501 .mask = 0x70,
0502 .odr_avl = {
0503 { .hz = 1, .value = 0x01 },
0504 { .hz = 10, .value = 0x02 },
0505 { .hz = 25, .value = 0x03 },
0506 { .hz = 50, .value = 0x04 },
0507 { .hz = 75, .value = 0x05 },
0508 { .hz = 100, .value = 0x06 },
0509 { .hz = 200, .value = 0x07 },
0510 },
0511 },
0512 .pw = {
0513 .addr = 0x10,
0514 .mask = 0x70,
0515 .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
0516 },
0517 .fs = {
0518 .fs_avl = {
0519
0520
0521
0522
0523 [0] = {
0524 .num = ST_PRESS_FS_AVL_1260MB,
0525 .gain = ST_PRESS_KPASCAL_NANO_SCALE,
0526 .gain2 = ST_PRESS_LPS22HB_LSB_PER_CELSIUS,
0527 },
0528 },
0529 },
0530 .bdu = {
0531 .addr = 0x10,
0532 .mask = BIT(1),
0533 },
0534 .drdy_irq = {
0535 .int1 = {
0536 .addr = 0x12,
0537 .mask = BIT(2),
0538 .addr_od = 0x11,
0539 .mask_od = BIT(5),
0540 },
0541 .addr_ihl = 0x11,
0542 .mask_ihl = BIT(6),
0543 .stat_drdy = {
0544 .addr = ST_SENSORS_DEFAULT_STAT_ADDR,
0545 .mask = 0x03,
0546 },
0547 },
0548 .sim = {
0549 .addr = 0x10,
0550 .value = BIT(0),
0551 },
0552 .multi_read_bit = false,
0553 .bootime = 2,
0554 },
0555 };
0556
0557 static int st_press_write_raw(struct iio_dev *indio_dev,
0558 struct iio_chan_spec const *ch,
0559 int val,
0560 int val2,
0561 long mask)
0562 {
0563 switch (mask) {
0564 case IIO_CHAN_INFO_SAMP_FREQ:
0565 if (val2)
0566 return -EINVAL;
0567
0568 return st_sensors_set_odr(indio_dev, val);
0569 default:
0570 return -EINVAL;
0571 }
0572 }
0573
0574 static int st_press_read_raw(struct iio_dev *indio_dev,
0575 struct iio_chan_spec const *ch, int *val,
0576 int *val2, long mask)
0577 {
0578 int err;
0579 struct st_sensor_data *press_data = iio_priv(indio_dev);
0580
0581 switch (mask) {
0582 case IIO_CHAN_INFO_RAW:
0583 err = st_sensors_read_info_raw(indio_dev, ch, val);
0584 if (err < 0)
0585 goto read_error;
0586
0587 return IIO_VAL_INT;
0588 case IIO_CHAN_INFO_SCALE:
0589 switch (ch->type) {
0590 case IIO_PRESSURE:
0591 *val = 0;
0592 *val2 = press_data->current_fullscale->gain;
0593 return IIO_VAL_INT_PLUS_NANO;
0594 case IIO_TEMP:
0595 *val = MCELSIUS_PER_CELSIUS;
0596 *val2 = press_data->current_fullscale->gain2;
0597 return IIO_VAL_FRACTIONAL;
0598 default:
0599 err = -EINVAL;
0600 goto read_error;
0601 }
0602
0603 case IIO_CHAN_INFO_OFFSET:
0604 switch (ch->type) {
0605 case IIO_TEMP:
0606 *val = ST_PRESS_MILLI_CELSIUS_OFFSET *
0607 press_data->current_fullscale->gain2;
0608 *val2 = MCELSIUS_PER_CELSIUS;
0609 break;
0610 default:
0611 err = -EINVAL;
0612 goto read_error;
0613 }
0614
0615 return IIO_VAL_FRACTIONAL;
0616 case IIO_CHAN_INFO_SAMP_FREQ:
0617 *val = press_data->odr;
0618 return IIO_VAL_INT;
0619 default:
0620 return -EINVAL;
0621 }
0622
0623 read_error:
0624 return err;
0625 }
0626
0627 static ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL();
0628
0629 static struct attribute *st_press_attributes[] = {
0630 &iio_dev_attr_sampling_frequency_available.dev_attr.attr,
0631 NULL,
0632 };
0633
0634 static const struct attribute_group st_press_attribute_group = {
0635 .attrs = st_press_attributes,
0636 };
0637
0638 static const struct iio_info press_info = {
0639 .attrs = &st_press_attribute_group,
0640 .read_raw = &st_press_read_raw,
0641 .write_raw = &st_press_write_raw,
0642 .debugfs_reg_access = &st_sensors_debugfs_reg_access,
0643 };
0644
0645 #ifdef CONFIG_IIO_TRIGGER
0646 static const struct iio_trigger_ops st_press_trigger_ops = {
0647 .set_trigger_state = ST_PRESS_TRIGGER_SET_STATE,
0648 .validate_device = st_sensors_validate_device,
0649 };
0650 #define ST_PRESS_TRIGGER_OPS (&st_press_trigger_ops)
0651 #else
0652 #define ST_PRESS_TRIGGER_OPS NULL
0653 #endif
0654
0655
0656
0657
0658
0659
0660
0661 const struct st_sensor_settings *st_press_get_settings(const char *name)
0662 {
0663 int index = st_sensors_get_settings_index(name,
0664 st_press_sensors_settings,
0665 ARRAY_SIZE(st_press_sensors_settings));
0666 if (index < 0)
0667 return NULL;
0668
0669 return &st_press_sensors_settings[index];
0670 }
0671 EXPORT_SYMBOL_NS(st_press_get_settings, IIO_ST_SENSORS);
0672
0673 int st_press_common_probe(struct iio_dev *indio_dev)
0674 {
0675 struct st_sensor_data *press_data = iio_priv(indio_dev);
0676 struct device *parent = indio_dev->dev.parent;
0677 struct st_sensors_platform_data *pdata = dev_get_platdata(parent);
0678 int err;
0679
0680 indio_dev->modes = INDIO_DIRECT_MODE;
0681 indio_dev->info = &press_info;
0682
0683 err = st_sensors_verify_id(indio_dev);
0684 if (err < 0)
0685 return err;
0686
0687
0688
0689
0690
0691
0692
0693 press_data->num_data_channels = press_data->sensor_settings->num_ch - 1;
0694 indio_dev->channels = press_data->sensor_settings->ch;
0695 indio_dev->num_channels = press_data->sensor_settings->num_ch;
0696
0697 press_data->current_fullscale = &press_data->sensor_settings->fs.fs_avl[0];
0698
0699 press_data->odr = press_data->sensor_settings->odr.odr_avl[0].hz;
0700
0701
0702 if (!pdata && (press_data->sensor_settings->drdy_irq.int1.addr ||
0703 press_data->sensor_settings->drdy_irq.int2.addr))
0704 pdata = (struct st_sensors_platform_data *)&default_press_pdata;
0705
0706 err = st_sensors_init_sensor(indio_dev, pdata);
0707 if (err < 0)
0708 return err;
0709
0710 err = st_press_allocate_ring(indio_dev);
0711 if (err < 0)
0712 return err;
0713
0714 if (press_data->irq > 0) {
0715 err = st_sensors_allocate_trigger(indio_dev,
0716 ST_PRESS_TRIGGER_OPS);
0717 if (err < 0)
0718 return err;
0719 }
0720
0721 return devm_iio_device_register(parent, indio_dev);
0722 }
0723 EXPORT_SYMBOL_NS(st_press_common_probe, IIO_ST_SENSORS);
0724
0725 MODULE_AUTHOR("Denis Ciocca <denis.ciocca@st.com>");
0726 MODULE_DESCRIPTION("STMicroelectronics pressures driver");
0727 MODULE_LICENSE("GPL v2");
0728 MODULE_IMPORT_NS(IIO_ST_SENSORS);