diff options
Diffstat (limited to 'drivers/iio/pressure/st_pressure_core.c')
| -rw-r--r-- | drivers/iio/pressure/st_pressure_core.c | 361 |
1 files changed, 281 insertions, 80 deletions
diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c index 9c343b40665..cd7e01f3a93 100644 --- a/drivers/iio/pressure/st_pressure_core.c +++ b/drivers/iio/pressure/st_pressure_core.c @@ -28,95 +28,281 @@ #include <linux/iio/common/st_sensors.h> #include "st_pressure.h" -#define ST_PRESS_MBAR_TO_KPASCAL(x) (x * 10) +#define ST_PRESS_LSB_PER_MBAR 4096UL +#define ST_PRESS_KPASCAL_NANO_SCALE (100000000UL / \ + ST_PRESS_LSB_PER_MBAR) +#define ST_PRESS_LSB_PER_CELSIUS 480UL +#define ST_PRESS_CELSIUS_NANO_SCALE (1000000000UL / \ + ST_PRESS_LSB_PER_CELSIUS) #define ST_PRESS_NUMBER_DATA_CHANNELS 1 -/* DEFAULT VALUE FOR SENSORS */ -#define ST_PRESS_DEFAULT_OUT_XL_ADDR 0x28 -#define ST_TEMP_DEFAULT_OUT_L_ADDR 0x2b - /* FULLSCALE */ #define ST_PRESS_FS_AVL_1260MB 1260 -/* CUSTOM VALUES FOR SENSOR 1 */ -#define ST_PRESS_1_WAI_EXP 0xbb -#define ST_PRESS_1_ODR_ADDR 0x20 -#define ST_PRESS_1_ODR_MASK 0x70 -#define ST_PRESS_1_ODR_AVL_1HZ_VAL 0x01 -#define ST_PRESS_1_ODR_AVL_7HZ_VAL 0x05 -#define ST_PRESS_1_ODR_AVL_13HZ_VAL 0x06 -#define ST_PRESS_1_ODR_AVL_25HZ_VAL 0x07 -#define ST_PRESS_1_PW_ADDR 0x20 -#define ST_PRESS_1_PW_MASK 0x80 -#define ST_PRESS_1_FS_ADDR 0x23 -#define ST_PRESS_1_FS_MASK 0x30 -#define ST_PRESS_1_FS_AVL_1260_VAL 0x00 -#define ST_PRESS_1_FS_AVL_1260_GAIN ST_PRESS_MBAR_TO_KPASCAL(244141) -#define ST_PRESS_1_FS_AVL_TEMP_GAIN 2083000 -#define ST_PRESS_1_BDU_ADDR 0x20 -#define ST_PRESS_1_BDU_MASK 0x04 -#define ST_PRESS_1_DRDY_IRQ_ADDR 0x22 -#define ST_PRESS_1_DRDY_IRQ_MASK 0x04 -#define ST_PRESS_1_MULTIREAD_BIT true -#define ST_PRESS_1_TEMP_OFFSET 42500 - -static const struct iio_chan_spec st_press_channels[] = { - ST_SENSORS_LSM_CHANNELS(IIO_PRESSURE, +#define ST_PRESS_1_OUT_XL_ADDR 0x28 +#define ST_TEMP_1_OUT_L_ADDR 0x2b + +/* CUSTOM VALUES FOR LPS331AP SENSOR */ +#define ST_PRESS_LPS331AP_WAI_EXP 0xbb +#define ST_PRESS_LPS331AP_ODR_ADDR 0x20 +#define ST_PRESS_LPS331AP_ODR_MASK 0x70 +#define ST_PRESS_LPS331AP_ODR_AVL_1HZ_VAL 0x01 +#define ST_PRESS_LPS331AP_ODR_AVL_7HZ_VAL 0x05 +#define ST_PRESS_LPS331AP_ODR_AVL_13HZ_VAL 0x06 +#define ST_PRESS_LPS331AP_ODR_AVL_25HZ_VAL 0x07 +#define ST_PRESS_LPS331AP_PW_ADDR 0x20 +#define ST_PRESS_LPS331AP_PW_MASK 0x80 +#define ST_PRESS_LPS331AP_FS_ADDR 0x23 +#define ST_PRESS_LPS331AP_FS_MASK 0x30 +#define ST_PRESS_LPS331AP_FS_AVL_1260_VAL 0x00 +#define ST_PRESS_LPS331AP_FS_AVL_1260_GAIN ST_PRESS_KPASCAL_NANO_SCALE +#define ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN ST_PRESS_CELSIUS_NANO_SCALE +#define ST_PRESS_LPS331AP_BDU_ADDR 0x20 +#define ST_PRESS_LPS331AP_BDU_MASK 0x04 +#define ST_PRESS_LPS331AP_DRDY_IRQ_ADDR 0x22 +#define ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK 0x04 +#define ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK 0x20 +#define ST_PRESS_LPS331AP_MULTIREAD_BIT true +#define ST_PRESS_LPS331AP_TEMP_OFFSET 42500 + +/* CUSTOM VALUES FOR LPS001WP SENSOR */ +#define ST_PRESS_LPS001WP_WAI_EXP 0xba +#define ST_PRESS_LPS001WP_ODR_ADDR 0x20 +#define ST_PRESS_LPS001WP_ODR_MASK 0x30 +#define ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL 0x01 +#define ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL 0x02 +#define ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL 0x03 +#define ST_PRESS_LPS001WP_PW_ADDR 0x20 +#define ST_PRESS_LPS001WP_PW_MASK 0x40 +#define ST_PRESS_LPS001WP_BDU_ADDR 0x20 +#define ST_PRESS_LPS001WP_BDU_MASK 0x04 +#define ST_PRESS_LPS001WP_MULTIREAD_BIT true +#define ST_PRESS_LPS001WP_OUT_L_ADDR 0x28 +#define ST_TEMP_LPS001WP_OUT_L_ADDR 0x2a + +/* CUSTOM VALUES FOR LPS25H SENSOR */ +#define ST_PRESS_LPS25H_WAI_EXP 0xbd +#define ST_PRESS_LPS25H_ODR_ADDR 0x20 +#define ST_PRESS_LPS25H_ODR_MASK 0x70 +#define ST_PRESS_LPS25H_ODR_AVL_1HZ_VAL 0x01 +#define ST_PRESS_LPS25H_ODR_AVL_7HZ_VAL 0x02 +#define ST_PRESS_LPS25H_ODR_AVL_13HZ_VAL 0x03 +#define ST_PRESS_LPS25H_ODR_AVL_25HZ_VAL 0x04 +#define ST_PRESS_LPS25H_PW_ADDR 0x20 +#define ST_PRESS_LPS25H_PW_MASK 0x80 +#define ST_PRESS_LPS25H_FS_ADDR 0x00 +#define ST_PRESS_LPS25H_FS_MASK 0x00 +#define ST_PRESS_LPS25H_FS_AVL_1260_VAL 0x00 +#define ST_PRESS_LPS25H_FS_AVL_1260_GAIN ST_PRESS_KPASCAL_NANO_SCALE +#define ST_PRESS_LPS25H_FS_AVL_TEMP_GAIN ST_PRESS_CELSIUS_NANO_SCALE +#define ST_PRESS_LPS25H_BDU_ADDR 0x20 +#define ST_PRESS_LPS25H_BDU_MASK 0x04 +#define ST_PRESS_LPS25H_DRDY_IRQ_ADDR 0x23 +#define ST_PRESS_LPS25H_DRDY_IRQ_INT1_MASK 0x01 +#define ST_PRESS_LPS25H_DRDY_IRQ_INT2_MASK 0x10 +#define ST_PRESS_LPS25H_MULTIREAD_BIT true +#define ST_PRESS_LPS25H_TEMP_OFFSET 42500 +#define ST_PRESS_LPS25H_OUT_XL_ADDR 0x28 +#define ST_TEMP_LPS25H_OUT_L_ADDR 0x2b + +static const struct iio_chan_spec st_press_1_channels[] = { + { + .type = IIO_PRESSURE, + .channel2 = IIO_NO_MOD, + .address = ST_PRESS_1_OUT_XL_ADDR, + .scan_index = ST_SENSORS_SCAN_X, + .scan_type = { + .sign = 'u', + .realbits = 24, + .storagebits = 24, + .endianness = IIO_LE, + }, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), - ST_SENSORS_SCAN_X, 0, IIO_NO_MOD, 'u', IIO_LE, 24, 24, - ST_PRESS_DEFAULT_OUT_XL_ADDR), - ST_SENSORS_LSM_CHANNELS(IIO_TEMP, - BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) | - BIT(IIO_CHAN_INFO_OFFSET), - -1, 0, IIO_NO_MOD, 's', IIO_LE, 16, 16, - ST_TEMP_DEFAULT_OUT_L_ADDR), + .modified = 0, + }, + { + .type = IIO_TEMP, + .channel2 = IIO_NO_MOD, + .address = ST_TEMP_1_OUT_L_ADDR, + .scan_index = -1, + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_LE, + }, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_SCALE) | + BIT(IIO_CHAN_INFO_OFFSET), + .modified = 0, + }, + IIO_CHAN_SOFT_TIMESTAMP(1) +}; + +static const struct iio_chan_spec st_press_lps001wp_channels[] = { + { + .type = IIO_PRESSURE, + .channel2 = IIO_NO_MOD, + .address = ST_PRESS_LPS001WP_OUT_L_ADDR, + .scan_index = ST_SENSORS_SCAN_X, + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_LE, + }, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), + .modified = 0, + }, + { + .type = IIO_TEMP, + .channel2 = IIO_NO_MOD, + .address = ST_TEMP_LPS001WP_OUT_L_ADDR, + .scan_index = -1, + .scan_type = { + .sign = 'u', + .realbits = 16, + .storagebits = 16, + .endianness = IIO_LE, + }, + .info_mask_separate = + BIT(IIO_CHAN_INFO_RAW) | + BIT(IIO_CHAN_INFO_OFFSET), + .modified = 0, + }, IIO_CHAN_SOFT_TIMESTAMP(1) }; static const struct st_sensors st_press_sensors[] = { { - .wai = ST_PRESS_1_WAI_EXP, + .wai = ST_PRESS_LPS331AP_WAI_EXP, .sensors_supported = { [0] = LPS331AP_PRESS_DEV_NAME, }, - .ch = (struct iio_chan_spec *)st_press_channels, + .ch = (struct iio_chan_spec *)st_press_1_channels, + .num_ch = ARRAY_SIZE(st_press_1_channels), + .odr = { + .addr = ST_PRESS_LPS331AP_ODR_ADDR, + .mask = ST_PRESS_LPS331AP_ODR_MASK, + .odr_avl = { + { 1, ST_PRESS_LPS331AP_ODR_AVL_1HZ_VAL, }, + { 7, ST_PRESS_LPS331AP_ODR_AVL_7HZ_VAL, }, + { 13, ST_PRESS_LPS331AP_ODR_AVL_13HZ_VAL, }, + { 25, ST_PRESS_LPS331AP_ODR_AVL_25HZ_VAL, }, + }, + }, + .pw = { + .addr = ST_PRESS_LPS331AP_PW_ADDR, + .mask = ST_PRESS_LPS331AP_PW_MASK, + .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE, + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, + }, + .fs = { + .addr = ST_PRESS_LPS331AP_FS_ADDR, + .mask = ST_PRESS_LPS331AP_FS_MASK, + .fs_avl = { + [0] = { + .num = ST_PRESS_FS_AVL_1260MB, + .value = ST_PRESS_LPS331AP_FS_AVL_1260_VAL, + .gain = ST_PRESS_LPS331AP_FS_AVL_1260_GAIN, + .gain2 = ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN, + }, + }, + }, + .bdu = { + .addr = ST_PRESS_LPS331AP_BDU_ADDR, + .mask = ST_PRESS_LPS331AP_BDU_MASK, + }, + .drdy_irq = { + .addr = ST_PRESS_LPS331AP_DRDY_IRQ_ADDR, + .mask_int1 = ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK, + .mask_int2 = ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK, + }, + .multi_read_bit = ST_PRESS_LPS331AP_MULTIREAD_BIT, + .bootime = 2, + }, + { + .wai = ST_PRESS_LPS001WP_WAI_EXP, + .sensors_supported = { + [0] = LPS001WP_PRESS_DEV_NAME, + }, + .ch = (struct iio_chan_spec *)st_press_lps001wp_channels, + .num_ch = ARRAY_SIZE(st_press_lps001wp_channels), .odr = { - .addr = ST_PRESS_1_ODR_ADDR, - .mask = ST_PRESS_1_ODR_MASK, + .addr = ST_PRESS_LPS001WP_ODR_ADDR, + .mask = ST_PRESS_LPS001WP_ODR_MASK, .odr_avl = { - { 1, ST_PRESS_1_ODR_AVL_1HZ_VAL, }, - { 7, ST_PRESS_1_ODR_AVL_7HZ_VAL, }, - { 13, ST_PRESS_1_ODR_AVL_13HZ_VAL, }, - { 25, ST_PRESS_1_ODR_AVL_25HZ_VAL, }, + { 1, ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL, }, + { 7, ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL, }, + { 13, ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL, }, }, }, .pw = { - .addr = ST_PRESS_1_PW_ADDR, - .mask = ST_PRESS_1_PW_MASK, + .addr = ST_PRESS_LPS001WP_PW_ADDR, + .mask = ST_PRESS_LPS001WP_PW_MASK, .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE, .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, }, .fs = { - .addr = ST_PRESS_1_FS_ADDR, - .mask = ST_PRESS_1_FS_MASK, + .addr = 0, + }, + .bdu = { + .addr = ST_PRESS_LPS001WP_BDU_ADDR, + .mask = ST_PRESS_LPS001WP_BDU_MASK, + }, + .drdy_irq = { + .addr = 0, + }, + .multi_read_bit = ST_PRESS_LPS001WP_MULTIREAD_BIT, + .bootime = 2, + }, + { + .wai = ST_PRESS_LPS25H_WAI_EXP, + .sensors_supported = { + [0] = LPS25H_PRESS_DEV_NAME, + }, + .ch = (struct iio_chan_spec *)st_press_1_channels, + .num_ch = ARRAY_SIZE(st_press_1_channels), + .odr = { + .addr = ST_PRESS_LPS25H_ODR_ADDR, + .mask = ST_PRESS_LPS25H_ODR_MASK, + .odr_avl = { + { 1, ST_PRESS_LPS25H_ODR_AVL_1HZ_VAL, }, + { 7, ST_PRESS_LPS25H_ODR_AVL_7HZ_VAL, }, + { 13, ST_PRESS_LPS25H_ODR_AVL_13HZ_VAL, }, + { 25, ST_PRESS_LPS25H_ODR_AVL_25HZ_VAL, }, + }, + }, + .pw = { + .addr = ST_PRESS_LPS25H_PW_ADDR, + .mask = ST_PRESS_LPS25H_PW_MASK, + .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE, + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, + }, + .fs = { + .addr = ST_PRESS_LPS25H_FS_ADDR, + .mask = ST_PRESS_LPS25H_FS_MASK, .fs_avl = { [0] = { .num = ST_PRESS_FS_AVL_1260MB, - .value = ST_PRESS_1_FS_AVL_1260_VAL, - .gain = ST_PRESS_1_FS_AVL_1260_GAIN, - .gain2 = ST_PRESS_1_FS_AVL_TEMP_GAIN, + .value = ST_PRESS_LPS25H_FS_AVL_1260_VAL, + .gain = ST_PRESS_LPS25H_FS_AVL_1260_GAIN, + .gain2 = ST_PRESS_LPS25H_FS_AVL_TEMP_GAIN, }, }, }, .bdu = { - .addr = ST_PRESS_1_BDU_ADDR, - .mask = ST_PRESS_1_BDU_MASK, + .addr = ST_PRESS_LPS25H_BDU_ADDR, + .mask = ST_PRESS_LPS25H_BDU_MASK, }, .drdy_irq = { - .addr = ST_PRESS_1_DRDY_IRQ_ADDR, - .mask = ST_PRESS_1_DRDY_IRQ_MASK, + .addr = ST_PRESS_LPS25H_DRDY_IRQ_ADDR, + .mask_int1 = ST_PRESS_LPS25H_DRDY_IRQ_INT1_MASK, + .mask_int2 = ST_PRESS_LPS25H_DRDY_IRQ_INT2_MASK, }, - .multi_read_bit = ST_PRESS_1_MULTIREAD_BIT, + .multi_read_bit = ST_PRESS_LPS25H_MULTIREAD_BIT, .bootime = 2, }, }; @@ -200,39 +386,51 @@ static const struct iio_trigger_ops st_press_trigger_ops = { #define ST_PRESS_TRIGGER_OPS NULL #endif -int st_press_common_probe(struct iio_dev *indio_dev) +int st_press_common_probe(struct iio_dev *indio_dev, + struct st_sensors_platform_data *plat_data) { - int err; struct st_sensor_data *pdata = iio_priv(indio_dev); + int irq = pdata->get_irq_data_ready(indio_dev); + int err; indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->info = &press_info; + st_sensors_power_enable(indio_dev); + err = st_sensors_check_device_support(indio_dev, - ARRAY_SIZE(st_press_sensors), st_press_sensors); + ARRAY_SIZE(st_press_sensors), + st_press_sensors); if (err < 0) - goto st_press_common_probe_error; + return err; pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS; - pdata->multiread_bit = pdata->sensor->multi_read_bit; - indio_dev->channels = pdata->sensor->ch; - indio_dev->num_channels = ARRAY_SIZE(st_press_channels); + pdata->multiread_bit = pdata->sensor->multi_read_bit; + indio_dev->channels = pdata->sensor->ch; + indio_dev->num_channels = pdata->sensor->num_ch; + + if (pdata->sensor->fs.addr != 0) + pdata->current_fullscale = (struct st_sensor_fullscale_avl *) + &pdata->sensor->fs.fs_avl[0]; - pdata->current_fullscale = (struct st_sensor_fullscale_avl *) - &pdata->sensor->fs.fs_avl[0]; pdata->odr = pdata->sensor->odr.odr_avl[0].hz; - err = st_sensors_init_sensor(indio_dev); + /* Some devices don't support a data ready pin. */ + if (!plat_data && pdata->sensor->drdy_irq.addr) + plat_data = + (struct st_sensors_platform_data *)&default_press_pdata; + + err = st_sensors_init_sensor(indio_dev, plat_data); if (err < 0) - goto st_press_common_probe_error; + return err; - if (pdata->get_irq_data_ready(indio_dev) > 0) { - err = st_press_allocate_ring(indio_dev); - if (err < 0) - goto st_press_common_probe_error; + err = st_press_allocate_ring(indio_dev); + if (err < 0) + return err; + if (irq > 0) { err = st_sensors_allocate_trigger(indio_dev, - ST_PRESS_TRIGGER_OPS); + ST_PRESS_TRIGGER_OPS); if (err < 0) goto st_press_probe_trigger_error; } @@ -241,15 +439,17 @@ int st_press_common_probe(struct iio_dev *indio_dev) if (err) goto st_press_device_register_error; + dev_info(&indio_dev->dev, "registered pressure sensor %s\n", + indio_dev->name); + return err; st_press_device_register_error: - if (pdata->get_irq_data_ready(indio_dev) > 0) + if (irq > 0) st_sensors_deallocate_trigger(indio_dev); st_press_probe_trigger_error: - if (pdata->get_irq_data_ready(indio_dev) > 0) - st_press_deallocate_ring(indio_dev); -st_press_common_probe_error: + st_press_deallocate_ring(indio_dev); + return err; } EXPORT_SYMBOL(st_press_common_probe); @@ -258,12 +458,13 @@ void st_press_common_remove(struct iio_dev *indio_dev) { struct st_sensor_data *pdata = iio_priv(indio_dev); + st_sensors_power_disable(indio_dev); + iio_device_unregister(indio_dev); - if (pdata->get_irq_data_ready(indio_dev) > 0) { + if (pdata->get_irq_data_ready(indio_dev) > 0) st_sensors_deallocate_trigger(indio_dev); - st_press_deallocate_ring(indio_dev); - } - iio_device_free(indio_dev); + + st_press_deallocate_ring(indio_dev); } EXPORT_SYMBOL(st_press_common_remove); |
