diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-09-22 09:45:11 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-09-22 09:45:11 +0200 |
commit | b290f902b857d75a5eaeb0aa8d0a12fbc8312699 (patch) | |
tree | f7c9b88995750ca5adb25fc9dc25ea046df785e7 /drivers/iio/imu | |
parent | 93b61540dfa56b2385ec188a29615e062cd571be (diff) | |
parent | 596fd0162ac70c2253041e60394ecb5cccb15b07 (diff) | |
download | linux-b290f902b857d75a5eaeb0aa8d0a12fbc8312699.tar.bz2 |
Merge tag 'iio-for-5.10b-take2' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes:
Second set of features and cleanups for IIO in 5.10
We have a couple of changes that apply to large sets of drivers, so
I have grouped those to keep this short.
There are a few late breaking fixes in here that can wait for the
merge window.
dt yaml conversions
-------------------
* adi,ad7768-1
* adi,ad7949
* aspeed,ast2400
* cosmic,10001-adc
* dlg,da9150-gpadc
* fsl,imx25-gcq
* fsl,imx7d-adc
* fsl,vf610
* holt,hi8435
* marvell,berlin2-adc
* motorola,cpcap-adc
* nuvoton,nau7802
* nuvoton,npcm750-adc
* nxp,lpc1850-adc
* nxp,lpc3220
* sprd,sc2720-adc
* st,stmpe-adc
* ti,adc12138
* ti,ads1015
* ti,ads7950
* ti,twl4030-madc
Features
--------
* adxrs290
- Add triggered buffer support and expose data ready signal as a possible
trigger. Includes updating bindings.
- Add debugfs hooks for register access.
* mlx90632
- Add a clear user interface to override the measured ambient temperature.
* vl53l0x
- Add IRQ support including dt bindings.
Cleanups and minor fixes
------------------------
(groups)
Replace mlock with local lock:
* adf4350
* exynos-adc
* fls-imx25-gcq
* stm32-dac
devm use to simplify probe error handling and remove functions.
* adis16201
* adis16203
* adis16209
* adis16240
* adis16136
* adis16260
* adis16400
* adis16460
* adis16480
* adis library - drop unused adis_setup_buffer_and_trigger()
of_match_ptr removal and incorrect ACPI binding removal
of_match_ptr() rarely makes sense in an IIO driver as space saving
is trivial and it breaks ACPI PRP0001 based instantiation.
Mostly this series is about removing examples that get copied into new
drivers.
* ad2s1200
* ad5272
* ad5446
* ad5592r
* ad5593r
* ad5703
* ak8974
* ak8975
* ams-iaq-core
* as3935
* atlas-sensor
* ds1803
* hdc100x
* htu21
* icp10100
* lmp91000
* pulsedlight
* max30102
* max5432
* max5481
* mcp4018
* mcp4131
* mcp4531
* mcp4725
* ms5611
* ms5637
* si7020
* sgp30
* ti-dac082s085
* ti-dac5571
* tmp007
* tsys01
* vz89x
* zpa2326
kernel-doc fixes
* iio-core
* ad7303
* ad7947
* adis16080
* adis16400
* iio_dummy_evgen
* sgp30
Fixes for buffer alignment when passed to iio_push_to_buffers_with_timestamp()
This is a long running effort. There are a few more drivers to come.
* inv_mpu6050
* itg3200
* si1145
* st_lsm6dsx
* ti-adc0832
* ti-adc12138
(not driver focused)
* MAINTAINERS
- Consolidate Analog Device IIO entries whilst removing Beniamin Bia.
- Remove Hartmut Knaack as a listed IIO maintainer as he hasn't been
active for a long time and people are getting intermitted bounces.
* Add __printf() markings to a few functions that were missing them.
* drop some rotted documentation from staging.
* rework buffer sysfs file creation (precursor to multiple buffer support)
(individual drivers)
* ad5592r
- Fix use of true for IIO_SHARED_BY_TYPE
- Tidy up locking and indentation.
* ad9467
- Improve error message on chip-id missmatch.
- Use more appropriate error value if chip-id not recognised.
* adis-library
- Simplify burst mode handling.
* adxrs290
- Make sure to switch device to standby mode during remove.
* as73211
- Increase measurement timeout as seems some devices are slower.
* bma180
- Fix use of true fo IIO_SHARED_BY_TYPE
* exynos_adc
- Update binding to require second interrut with touch screen.
- Update binding to not require syscon on S5Pv210
* hmc5843
- Fix use of true for IIO_SHARED_BY_TYPE
* inv_mpu6050
- Use regmap_noinc_read() for fifo reading.
* palmas_gpadc
- Use module_platform_driver() to remove boilerplate.
* meson-saradc
- style consistency fixes
* rockchip_saradc
- Allow compile testing with !ARM.
* st_lsm6dsx
- Changing scaling factor to use IIO_VAL_INT_PLUS_NANO to improve precision.
- Fix an issue with unchecked return value.
* stm32-adc
- Fix a missing return introduced in dev_err_probe() patch earlier in
cycle.
* sx9310
- Prefer async mode for probe as paticularly slow startup.
* vcnl4000
- Add missing interrupt property to dt binding.
* tag 'iio-for-5.10b-take2' of https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (126 commits)
dt-bindings: iio: vishay,vcnl4000: add interrupts property
iio:imu:inv_mpu6050: Use regmap_noinc_read for fifo reads.
iio:imu:inv_mpu6050 Fix dma and ts alignment and data leak issues.
iio:adc:ti-adc12138 Fix alignment issue with timestamp
iio:adc:ti-adc0832 Fix alignment issue with timestamp
iio:imu:st_lsm6dsx Fix alignment and data leak issues
iio:light:si1145: Fix timestamp alignment and prevent data leak.
iio:gyro:itg3200: Fix timestamp alignment and prevent data leak.
iio:imu:st_lsm6dsx: check st_lsm6dsx_shub_read_output return
iio: adc: exynos_adc: Replace indio_dev->mlock with own device lock
dt-bindings:iio:adc:holt,hi8435 yaml conversion
dt-bindings:iio:adc:adi,ad7768-1 yaml conversion
dt-bindings:iio:adc:adi,ad7949 yaml conversion
dt-bindings:iio:adc:dlg,da9150-gpadc yaml conversion
dt-bindings:iio:adc:motorola,cpcap-adc yaml conversion
dt-bindings:iio:adc:nxp,lpc3220-adc yaml conversion
dt-bindings:iio:adc:nxp,lpc1850-adc yaml conversion
dt-bindings:iio:adc:fsl,imx25-gcq yaml conversion
dt-bindings:iio:adc:fsl,imx7d-adc yaml conversion
dt-bindings:iio:adc:ti,ads1015 yaml conversion
...
Diffstat (limited to 'drivers/iio/imu')
-rw-r--r-- | drivers/iio/imu/adis16400.c | 72 | ||||
-rw-r--r-- | drivers/iio/imu/adis16460.c | 25 | ||||
-rw-r--r-- | drivers/iio/imu/adis16475.c | 18 | ||||
-rw-r--r-- | drivers/iio/imu/adis16480.c | 55 | ||||
-rw-r--r-- | drivers/iio/imu/adis_buffer.c | 76 | ||||
-rw-r--r-- | drivers/iio/imu/adis_trigger.c | 60 | ||||
-rw-r--r-- | drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 12 | ||||
-rw-r--r-- | drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 14 | ||||
-rw-r--r-- | drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h | 6 | ||||
-rw-r--r-- | drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 42 | ||||
-rw-r--r-- | drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 134 | ||||
-rw-r--r-- | drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c | 2 |
12 files changed, 197 insertions, 319 deletions
diff --git a/drivers/iio/imu/adis16400.c b/drivers/iio/imu/adis16400.c index 1ebe3e50d3e6..54af2ed664f6 100644 --- a/drivers/iio/imu/adis16400.c +++ b/drivers/iio/imu/adis16400.c @@ -173,6 +173,8 @@ struct adis16400_chip_info { * @variant: chip variant info * @filt_int: integer part of requested filter frequency * @adis: adis device + * @avail_scan_mask: NULL terminated array of bitmaps of channels + * that must be enabled together **/ struct adis16400_state { struct adis16400_chip_info *variant; @@ -317,11 +319,6 @@ enum adis16400_chip_variant { ADIS16448, }; -static struct adis_burst adis16400_burst = { - .en = true, - .reg_cmd = ADIS16400_GLOB_CMD, -}; - static int adis16334_get_freq(struct adis16400_state *st) { int ret; @@ -947,7 +944,7 @@ static const char * const adis16400_status_error_msgs[] = { [ADIS16400_DIAG_STAT_POWER_LOW] = "Power supply below 4.75V", }; -#define ADIS16400_DATA(_timeouts) \ +#define ADIS16400_DATA(_timeouts, _burst_len) \ { \ .msc_ctrl_reg = ADIS16400_MSC_CTRL, \ .glob_cmd_reg = ADIS16400_GLOB_CMD, \ @@ -973,6 +970,8 @@ static const char * const adis16400_status_error_msgs[] = { BIT(ADIS16400_DIAG_STAT_POWER_HIGH) | \ BIT(ADIS16400_DIAG_STAT_POWER_LOW), \ .timeouts = (_timeouts), \ + .burst_reg_cmd = ADIS16400_GLOB_CMD, \ + .burst_len = (_burst_len) \ } static const struct adis_timeout adis16300_timeouts = { @@ -1023,7 +1022,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16300_timeouts), + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 18), }, [ADIS16334] = { .channels = adis16334_channels, @@ -1036,7 +1035,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 67850, /* 25 C = 0x00 */ .set_freq = adis16334_set_freq, .get_freq = adis16334_get_freq, - .adis_data = ADIS16400_DATA(&adis16334_timeouts), + .adis_data = ADIS16400_DATA(&adis16334_timeouts, 0), }, [ADIS16350] = { .channels = adis16350_channels, @@ -1048,7 +1047,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .flags = ADIS16400_NO_BURST | ADIS16400_HAS_SLOW_MODE, .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16300_timeouts), + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 0), }, [ADIS16360] = { .channels = adis16350_channels, @@ -1061,7 +1060,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16300_timeouts), + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 28), }, [ADIS16362] = { .channels = adis16350_channels, @@ -1074,7 +1073,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16362_timeouts), + .adis_data = ADIS16400_DATA(&adis16362_timeouts, 28), }, [ADIS16364] = { .channels = adis16350_channels, @@ -1087,7 +1086,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16362_timeouts), + .adis_data = ADIS16400_DATA(&adis16362_timeouts, 28), }, [ADIS16367] = { .channels = adis16350_channels, @@ -1100,7 +1099,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 136000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16300_timeouts), + .adis_data = ADIS16400_DATA(&adis16300_timeouts, 28), }, [ADIS16400] = { .channels = adis16400_channels, @@ -1112,7 +1111,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 25000000 / 140000, /* 25 C = 0x00 */ .set_freq = adis16400_set_freq, .get_freq = adis16400_get_freq, - .adis_data = ADIS16400_DATA(&adis16400_timeouts), + .adis_data = ADIS16400_DATA(&adis16400_timeouts, 24), }, [ADIS16445] = { .channels = adis16445_channels, @@ -1126,7 +1125,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ .set_freq = adis16334_set_freq, .get_freq = adis16334_get_freq, - .adis_data = ADIS16400_DATA(&adis16445_timeouts), + .adis_data = ADIS16400_DATA(&adis16445_timeouts, 16), }, [ADIS16448] = { .channels = adis16448_channels, @@ -1140,7 +1139,7 @@ static struct adis16400_chip_info adis16400_chips[] = { .temp_offset = 31000000 / 73860, /* 31 C = 0x00 */ .set_freq = adis16334_set_freq, .get_freq = adis16334_get_freq, - .adis_data = ADIS16400_DATA(&adis16448_timeouts), + .adis_data = ADIS16400_DATA(&adis16448_timeouts, 24), } }; @@ -1164,6 +1163,12 @@ static void adis16400_setup_chan_mask(struct adis16400_state *st) st->avail_scan_mask[0] |= BIT(ch->scan_index); } } + +static void adis16400_stop(void *data) +{ + adis16400_stop_device(data); +} + static int adis16400_probe(struct spi_device *spi) { struct adis16400_state *st; @@ -1190,9 +1195,6 @@ static int adis16400_probe(struct spi_device *spi) if (!(st->variant->flags & ADIS16400_NO_BURST)) { adis16400_setup_chan_mask(st); indio_dev->available_scan_masks = st->avail_scan_mask; - st->adis.burst = &adis16400_burst; - if (st->variant->flags & ADIS16400_BURST_DIAG_STAT) - st->adis.burst_extra_len = sizeof(u16); } adis16400_data = &st->variant->adis_data; @@ -1201,37 +1203,24 @@ static int adis16400_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, - adis16400_trigger_handler); + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, adis16400_trigger_handler); if (ret) return ret; /* Get the device into a sane initial state */ ret = adis16400_initial_setup(indio_dev); if (ret) - goto error_cleanup_buffer; - ret = iio_device_register(indio_dev); - if (ret) - goto error_cleanup_buffer; - - adis16400_debugfs_init(indio_dev); - return 0; - -error_cleanup_buffer: - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); - return ret; -} - -static int adis16400_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16400_state *st = iio_priv(indio_dev); + return ret; - iio_device_unregister(indio_dev); - adis16400_stop_device(indio_dev); + ret = devm_add_action_or_reset(&spi->dev, adis16400_stop, indio_dev); + if (ret) + return ret; - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); + if (ret) + return ret; + adis16400_debugfs_init(indio_dev); return 0; } @@ -1261,7 +1250,6 @@ static struct spi_driver adis16400_driver = { }, .id_table = adis16400_id, .probe = adis16400_probe, - .remove = adis16400_remove, }; module_spi_driver(adis16400_driver); diff --git a/drivers/iio/imu/adis16460.c b/drivers/iio/imu/adis16460.c index b26a5f1bc51a..74a161e39733 100644 --- a/drivers/iio/imu/adis16460.c +++ b/drivers/iio/imu/adis16460.c @@ -403,7 +403,7 @@ static int adis16460_probe(struct spi_device *spi) if (ret) return ret; - ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); if (ret) return ret; @@ -411,31 +411,15 @@ static int adis16460_probe(struct spi_device *spi) ret = __adis_initial_startup(&st->adis); if (ret) - goto error_cleanup_buffer; + return ret; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) - goto error_cleanup_buffer; + return ret; adis16460_debugfs_init(indio_dev); return 0; - -error_cleanup_buffer: - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); - return ret; -} - -static int adis16460_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16460 *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); - - return 0; } static const struct spi_device_id adis16460_ids[] = { @@ -457,7 +441,6 @@ static struct spi_driver adis16460_driver = { }, .id_table = adis16460_ids, .probe = adis16460_probe, - .remove = adis16460_remove, }; module_spi_driver(adis16460_driver); diff --git a/drivers/iio/imu/adis16475.c b/drivers/iio/imu/adis16475.c index 35d10ccb66c2..197d48240991 100644 --- a/drivers/iio/imu/adis16475.c +++ b/drivers/iio/imu/adis16475.c @@ -565,6 +565,9 @@ static int adis16475_enable_irq(struct adis *adis, bool enable) BIT(ADIS16475_DIAG_STAT_CLK), \ .enable_irq = adis16475_enable_irq, \ .timeouts = (_timeouts), \ + .burst_reg_cmd = ADIS16475_REG_GLOB_CMD, \ + .burst_len = ADIS16475_BURST_MAX_DATA, \ + .burst_max_len = ADIS16475_BURST32_MAX_DATA \ } static const struct adis16475_sync adis16475_sync_mode[] = { @@ -910,20 +913,6 @@ static const struct iio_info adis16475_info = { .debugfs_reg_access = adis_debugfs_reg_access, }; -static struct adis_burst adis16475_burst = { - .en = true, - .reg_cmd = ADIS16475_REG_GLOB_CMD, - /* - * adis_update_scan_mode_burst() sets the burst length in respect with - * the number of channels and allocates 16 bits for each. However, - * adis1647x devices also need space for DIAG_STAT, DATA_CNTR or - * TIME_STAMP (depending on the clock mode but for us these bytes are - * don't care...) and CRC. - */ - .extra_len = 3 * sizeof(u16), - .burst_max_len = ADIS16475_BURST32_MAX_DATA, -}; - static bool adis16475_validate_crc(const u8 *buffer, u16 crc, const bool burst32) { @@ -1279,7 +1268,6 @@ static int adis16475_probe(struct spi_device *spi) st = iio_priv(indio_dev); spi_set_drvdata(spi, indio_dev); - st->adis.burst = &adis16475_burst; st->info = device_get_match_data(&spi->dev); if (!st->info) diff --git a/drivers/iio/imu/adis16480.c b/drivers/iio/imu/adis16480.c index 1eb4f98076f1..dfe86c589325 100644 --- a/drivers/iio/imu/adis16480.c +++ b/drivers/iio/imu/adis16480.c @@ -1212,6 +1212,16 @@ static int adis16480_get_ext_clocks(struct adis16480 *st) return 0; } +static void adis16480_stop(void *data) +{ + adis16480_stop_device(data); +} + +static void adis16480_clk_disable(void *data) +{ + clk_disable_unprepare(data); +} + static int adis16480_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); @@ -1245,18 +1255,26 @@ static int adis16480_probe(struct spi_device *spi) if (ret) return ret; + ret = devm_add_action_or_reset(&spi->dev, adis16480_stop, indio_dev); + if (ret) + return ret; + ret = adis16480_config_irq_pin(spi->dev.of_node, st); if (ret) - goto error_stop_device; + return ret; ret = adis16480_get_ext_clocks(st); if (ret) - goto error_stop_device; + return ret; if (!IS_ERR_OR_NULL(st->ext_clk)) { ret = adis16480_ext_clk_config(st, spi->dev.of_node, true); if (ret) - goto error_stop_device; + return ret; + + ret = devm_add_action_or_reset(&spi->dev, adis16480_clk_disable, st->ext_clk); + if (ret) + return ret; st->clk_freq = clk_get_rate(st->ext_clk); st->clk_freq *= 1000; /* micro */ @@ -1264,39 +1282,17 @@ static int adis16480_probe(struct spi_device *spi) st->clk_freq = st->chip_info->int_clk; } - ret = adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); + ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL); if (ret) - goto error_clk_disable_unprepare; + return ret; - ret = iio_device_register(indio_dev); + ret = devm_iio_device_register(&spi->dev, indio_dev); if (ret) - goto error_cleanup_buffer; + return ret; adis16480_debugfs_init(indio_dev); return 0; - -error_cleanup_buffer: - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); -error_clk_disable_unprepare: - clk_disable_unprepare(st->ext_clk); -error_stop_device: - adis16480_stop_device(indio_dev); - return ret; -} - -static int adis16480_remove(struct spi_device *spi) -{ - struct iio_dev *indio_dev = spi_get_drvdata(spi); - struct adis16480 *st = iio_priv(indio_dev); - - iio_device_unregister(indio_dev); - adis16480_stop_device(indio_dev); - - adis_cleanup_buffer_and_trigger(&st->adis, indio_dev); - clk_disable_unprepare(st->ext_clk); - - return 0; } static const struct spi_device_id adis16480_ids[] = { @@ -1338,7 +1334,6 @@ static struct spi_driver adis16480_driver = { }, .id_table = adis16480_ids, .probe = adis16480_probe, - .remove = adis16480_remove, }; module_spi_driver(adis16480_driver); diff --git a/drivers/iio/imu/adis_buffer.c b/drivers/iio/imu/adis_buffer.c index 5b4225ee09b9..ac354321f63a 100644 --- a/drivers/iio/imu/adis_buffer.c +++ b/drivers/iio/imu/adis_buffer.c @@ -26,12 +26,10 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, unsigned int burst_length, burst_max_length; u8 *tx; - /* All but the timestamp channel */ - burst_length = (indio_dev->num_channels - 1) * sizeof(u16); - burst_length += adis->burst->extra_len + adis->burst_extra_len; + burst_length = adis->data->burst_len + adis->burst_extra_len; - if (adis->burst->burst_max_len) - burst_max_length = adis->burst->burst_max_len; + if (adis->data->burst_max_len) + burst_max_length = adis->data->burst_max_len; else burst_max_length = burst_length; @@ -47,7 +45,7 @@ static int adis_update_scan_mode_burst(struct iio_dev *indio_dev, } tx = adis->buffer + burst_max_length; - tx[0] = ADIS_READ_REG(adis->burst->reg_cmd); + tx[0] = ADIS_READ_REG(adis->data->burst_reg_cmd); tx[1] = 0; adis->xfer[0].tx_buf = tx; @@ -76,7 +74,7 @@ int adis_update_scan_mode(struct iio_dev *indio_dev, kfree(adis->xfer); kfree(adis->buffer); - if (adis->burst && adis->burst->en) + if (adis->data->burst_len) return adis_update_scan_mode_burst(indio_dev, scan_mask); scan_count = indio_dev->scan_bytes / 2; @@ -170,48 +168,6 @@ static void adis_buffer_cleanup(void *arg) } /** - * adis_setup_buffer_and_trigger() - Sets up buffer and trigger for the adis device - * @adis: The adis device. - * @indio_dev: The IIO device. - * @trigger_handler: Optional trigger handler, may be NULL. - * - * Returns 0 on success, a negative error code otherwise. - * - * This function sets up the buffer and trigger for a adis devices. If - * 'trigger_handler' is NULL the default trigger handler will be used. The - * default trigger handler will simply read the registers assigned to the - * currently active channels. - * - * adis_cleanup_buffer_and_trigger() should be called to free the resources - * allocated by this function. - */ -int adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, - irqreturn_t (*trigger_handler)(int, void *)) -{ - int ret; - - if (!trigger_handler) - trigger_handler = adis_trigger_handler; - - ret = iio_triggered_buffer_setup(indio_dev, &iio_pollfunc_store_time, - trigger_handler, NULL); - if (ret) - return ret; - - if (adis->spi->irq) { - ret = adis_probe_trigger(adis, indio_dev); - if (ret) - goto error_buffer_cleanup; - } - return 0; - -error_buffer_cleanup: - iio_triggered_buffer_cleanup(indio_dev); - return ret; -} -EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); - -/** * devm_adis_setup_buffer_and_trigger() - Sets up buffer and trigger for * the managed adis device * @adis: The adis device @@ -220,7 +176,10 @@ EXPORT_SYMBOL_GPL(adis_setup_buffer_and_trigger); * * Returns 0 on success, a negative error code otherwise. * - * This function perfoms exactly the same as adis_setup_buffer_and_trigger() + * This function sets up the buffer and trigger for a adis devices. If + * 'trigger_handler' is NULL the default trigger handler will be used. The + * default trigger handler will simply read the registers assigned to the + * currently active channels. */ int devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, @@ -248,20 +207,3 @@ devm_adis_setup_buffer_and_trigger(struct adis *adis, struct iio_dev *indio_dev, } EXPORT_SYMBOL_GPL(devm_adis_setup_buffer_and_trigger); -/** - * adis_cleanup_buffer_and_trigger() - Free buffer and trigger resources - * @adis: The adis device. - * @indio_dev: The IIO device. - * - * Frees resources allocated by adis_setup_buffer_and_trigger() - */ -void adis_cleanup_buffer_and_trigger(struct adis *adis, - struct iio_dev *indio_dev) -{ - if (adis->spi->irq) - adis_remove_trigger(adis); - kfree(adis->buffer); - kfree(adis->xfer); - iio_triggered_buffer_cleanup(indio_dev); -} -EXPORT_SYMBOL_GPL(adis_cleanup_buffer_and_trigger); diff --git a/drivers/iio/imu/adis_trigger.c b/drivers/iio/imu/adis_trigger.c index 8afe71947c00..64e0ba51cb18 100644 --- a/drivers/iio/imu/adis_trigger.c +++ b/drivers/iio/imu/adis_trigger.c @@ -55,53 +55,6 @@ static int adis_validate_irq_flag(struct adis *adis) return 0; } -/** - * adis_probe_trigger() - Sets up trigger for a adis device - * @adis: The adis device - * @indio_dev: The IIO device - * - * Returns 0 on success or a negative error code - * - * adis_remove_trigger() should be used to free the trigger. - */ -int adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) -{ - int ret; - - adis->trig = iio_trigger_alloc("%s-dev%d", indio_dev->name, - indio_dev->id); - if (adis->trig == NULL) - return -ENOMEM; - - adis_trigger_setup(adis); - - ret = adis_validate_irq_flag(adis); - if (ret) - return ret; - - ret = request_irq(adis->spi->irq, - &iio_trigger_generic_data_rdy_poll, - adis->irq_flag, - indio_dev->name, - adis->trig); - if (ret) - goto error_free_trig; - - ret = iio_trigger_register(adis->trig); - - indio_dev->trig = iio_trigger_get(adis->trig); - if (ret) - goto error_free_irq; - - return 0; - -error_free_irq: - free_irq(adis->spi->irq, adis->trig); -error_free_trig: - iio_trigger_free(adis->trig); - return ret; -} -EXPORT_SYMBOL_GPL(adis_probe_trigger); /** * devm_adis_probe_trigger() - Sets up trigger for a managed adis device @@ -137,16 +90,3 @@ int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev) } EXPORT_SYMBOL_GPL(devm_adis_probe_trigger); -/** - * adis_remove_trigger() - Remove trigger for a adis devices - * @adis: The adis device - * - * Removes the trigger previously registered with adis_probe_trigger(). - */ -void adis_remove_trigger(struct adis *adis) -{ - iio_trigger_unregister(adis->trig); - free_irq(adis->spi->irq, adis->trig); - iio_trigger_free(adis->trig); -} -EXPORT_SYMBOL_GPL(adis_remove_trigger); diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index cd38b3fccc7b..eb522b38acf3 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -122,6 +122,13 @@ struct inv_mpu6050_chip_config { u8 user_ctrl; }; +/* + * Maximum of 6 + 6 + 2 + 7 (for MPU9x50) = 21 round up to 24 and plus 8. + * May be less if fewer channels are enabled, as long as the timestamp + * remains 8 byte aligned + */ +#define INV_MPU6050_OUTPUT_DATA_SIZE 32 + /** * struct inv_mpu6050_hw - Other important hardware information. * @whoami: Self identification byte from WHO_AM_I register @@ -165,6 +172,7 @@ struct inv_mpu6050_hw { * @magn_raw_to_gauss: coefficient to convert mag raw value to Gauss. * @magn_orient: magnetometer sensor chip orientation if available. * @suspended_sensors: sensors mask of sensors turned off for suspend + * @data: dma safe buffer used for bulk reads. */ struct inv_mpu6050_state { struct mutex lock; @@ -190,6 +198,7 @@ struct inv_mpu6050_state { s32 magn_raw_to_gauss[3]; struct iio_mount_matrix magn_orient; unsigned int suspended_sensors; + u8 data[INV_MPU6050_OUTPUT_DATA_SIZE] ____cacheline_aligned; }; /*register and associated bit definition*/ @@ -334,9 +343,6 @@ struct inv_mpu6050_state { #define INV_ICM20608_TEMP_OFFSET 8170 #define INV_ICM20608_TEMP_SCALE 3059976 -/* 6 + 6 + 2 + 7 (for MPU9x50) = 21 round up to 24 and plus 8 */ -#define INV_MPU6050_OUTPUT_DATA_SIZE 32 - #define INV_MPU6050_REG_INT_PIN_CFG 0x37 #define INV_MPU6050_ACTIVE_HIGH 0x00 #define INV_MPU6050_ACTIVE_LOW 0x80 diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c index b533fa2dad0a..45c37525c2f1 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c @@ -13,7 +13,6 @@ #include <linux/interrupt.h> #include <linux/poll.h> #include <linux/math64.h> -#include <asm/unaligned.h> #include "inv_mpu_iio.h" /** @@ -121,7 +120,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) struct inv_mpu6050_state *st = iio_priv(indio_dev); size_t bytes_per_datum; int result; - u8 data[INV_MPU6050_OUTPUT_DATA_SIZE]; u16 fifo_count; s64 timestamp; int int_status; @@ -160,11 +158,11 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) * read fifo_count register to know how many bytes are inside the FIFO * right now */ - result = regmap_bulk_read(st->map, st->reg->fifo_count_h, data, - INV_MPU6050_FIFO_COUNT_BYTE); + result = regmap_bulk_read(st->map, st->reg->fifo_count_h, + st->data, INV_MPU6050_FIFO_COUNT_BYTE); if (result) goto end_session; - fifo_count = get_unaligned_be16(&data[0]); + fifo_count = be16_to_cpup((__be16 *)&st->data[0]); /* * Handle fifo overflow by resetting fifo. @@ -181,8 +179,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) nb = fifo_count / bytes_per_datum; inv_mpu6050_update_period(st, pf->timestamp, nb); for (i = 0; i < nb; ++i) { - result = regmap_bulk_read(st->map, st->reg->fifo_r_w, - data, bytes_per_datum); + result = regmap_noinc_read(st->map, st->reg->fifo_r_w, + st->data, bytes_per_datum); if (result) goto flush_fifo; /* skip first samples if needed */ @@ -191,7 +189,7 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) continue; } timestamp = inv_mpu6050_get_timestamp(st); - iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp); + iio_push_to_buffers_with_timestamp(indio_dev, st->data, timestamp); } end_session: diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h index d80ba2e688ed..9275346a9cc1 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h @@ -383,6 +383,7 @@ struct st_lsm6dsx_sensor { * @iio_devs: Pointers to acc/gyro iio_dev instances. * @settings: Pointer to the specific sensor settings in use. * @orientation: sensor chip orientation relative to main hardware. + * @scan: Temporary buffers used to align data before iio_push_to_buffers() */ struct st_lsm6dsx_hw { struct device *dev; @@ -411,6 +412,11 @@ struct st_lsm6dsx_hw { const struct st_lsm6dsx_settings *settings; struct iio_mount_matrix orientation; + /* Ensure natural alignment of buffer elements */ + struct { + __le16 channels[3]; + s64 ts __aligned(8); + } scan[3]; }; static __maybe_unused const struct iio_event_spec st_lsm6dsx_event = { diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c index 7de10bd636ea..12ed0a2e55e4 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c @@ -353,9 +353,6 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) int err, sip, acc_sip, gyro_sip, ts_sip, ext_sip, read_len, offset; u16 fifo_len, pattern_len = hw->sip * ST_LSM6DSX_SAMPLE_SIZE; u16 fifo_diff_mask = hw->settings->fifo_ops.fifo_diff.mask; - u8 gyro_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; - u8 acc_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; - u8 ext_buff[ST_LSM6DSX_IIO_BUFF_SIZE]; bool reset_ts = false; __le16 fifo_status; s64 ts = 0; @@ -416,19 +413,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) while (acc_sip > 0 || gyro_sip > 0 || ext_sip > 0) { if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { - memcpy(gyro_buff, &hw->buff[offset], - ST_LSM6DSX_SAMPLE_SIZE); - offset += ST_LSM6DSX_SAMPLE_SIZE; + memcpy(hw->scan[ST_LSM6DSX_ID_GYRO].channels, + &hw->buff[offset], + sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels)); + offset += sizeof(hw->scan[ST_LSM6DSX_ID_GYRO].channels); } if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { - memcpy(acc_buff, &hw->buff[offset], - ST_LSM6DSX_SAMPLE_SIZE); - offset += ST_LSM6DSX_SAMPLE_SIZE; + memcpy(hw->scan[ST_LSM6DSX_ID_ACC].channels, + &hw->buff[offset], + sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels)); + offset += sizeof(hw->scan[ST_LSM6DSX_ID_ACC].channels); } if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { - memcpy(ext_buff, &hw->buff[offset], - ST_LSM6DSX_SAMPLE_SIZE); - offset += ST_LSM6DSX_SAMPLE_SIZE; + memcpy(hw->scan[ST_LSM6DSX_ID_EXT0].channels, + &hw->buff[offset], + sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels)); + offset += sizeof(hw->scan[ST_LSM6DSX_ID_EXT0].channels); } if (ts_sip-- > 0) { @@ -458,19 +458,22 @@ int st_lsm6dsx_read_fifo(struct st_lsm6dsx_hw *hw) if (gyro_sip > 0 && !(sip % gyro_sensor->decimator)) { iio_push_to_buffers_with_timestamp( hw->iio_devs[ST_LSM6DSX_ID_GYRO], - gyro_buff, gyro_sensor->ts_ref + ts); + &hw->scan[ST_LSM6DSX_ID_GYRO], + gyro_sensor->ts_ref + ts); gyro_sip--; } if (acc_sip > 0 && !(sip % acc_sensor->decimator)) { iio_push_to_buffers_with_timestamp( hw->iio_devs[ST_LSM6DSX_ID_ACC], - acc_buff, acc_sensor->ts_ref + ts); + &hw->scan[ST_LSM6DSX_ID_ACC], + acc_sensor->ts_ref + ts); acc_sip--; } if (ext_sip > 0 && !(sip % ext_sensor->decimator)) { iio_push_to_buffers_with_timestamp( hw->iio_devs[ST_LSM6DSX_ID_EXT0], - ext_buff, ext_sensor->ts_ref + ts); + &hw->scan[ST_LSM6DSX_ID_EXT0], + ext_sensor->ts_ref + ts); ext_sip--; } sip++; @@ -555,7 +558,14 @@ int st_lsm6dsx_read_tagged_fifo(struct st_lsm6dsx_hw *hw) { u16 pattern_len = hw->sip * ST_LSM6DSX_TAGGED_SAMPLE_SIZE; u16 fifo_len, fifo_diff_mask; - u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE], tag; + /* + * Alignment needed as this can ultimately be passed to a + * call to iio_push_to_buffers_with_timestamp() which + * must be passed a buffer that is aligned to 8 bytes so + * as to allow insertion of a naturally aligned timestamp. + */ + u8 iio_buff[ST_LSM6DSX_IIO_BUFF_SIZE] __aligned(8); + u8 tag; bool reset_ts = false; int i, err, read_len; __le16 fifo_status; diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c index 346c24281d26..42f485634d04 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c @@ -157,10 +157,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x20, .mask = GENMASK(4, 3), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(732), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(732000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -169,9 +169,9 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .mask = GENMASK(4, 3), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 3, }, }, @@ -259,10 +259,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -270,10 +270,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -425,10 +425,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -436,10 +436,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -600,10 +600,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -611,10 +611,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -816,10 +816,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -827,10 +827,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -1021,10 +1021,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -1032,10 +1032,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -1200,10 +1200,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x10, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_G_TO_M_S_2(61), 0x0 }, - .fs_avl[1] = { IIO_G_TO_M_S_2(122), 0x2 }, - .fs_avl[2] = { IIO_G_TO_M_S_2(244), 0x3 }, - .fs_avl[3] = { IIO_G_TO_M_S_2(488), 0x1 }, + .fs_avl[0] = { IIO_G_TO_M_S_2(61000), 0x0 }, + .fs_avl[1] = { IIO_G_TO_M_S_2(122000), 0x2 }, + .fs_avl[2] = { IIO_G_TO_M_S_2(244000), 0x3 }, + .fs_avl[3] = { IIO_G_TO_M_S_2(488000), 0x1 }, .fs_len = 4, }, [ST_LSM6DSX_ID_GYRO] = { @@ -1211,10 +1211,10 @@ static const struct st_lsm6dsx_settings st_lsm6dsx_sensor_settings[] = { .addr = 0x11, .mask = GENMASK(3, 2), }, - .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750), 0x0 }, - .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500), 0x1 }, - .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000), 0x2 }, - .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000), 0x3 }, + .fs_avl[0] = { IIO_DEGREE_TO_RAD(8750000), 0x0 }, + .fs_avl[1] = { IIO_DEGREE_TO_RAD(17500000), 0x1 }, + .fs_avl[2] = { IIO_DEGREE_TO_RAD(35000000), 0x2 }, + .fs_avl[3] = { IIO_DEGREE_TO_RAD(70000000), 0x3 }, .fs_len = 4, }, }, @@ -1598,7 +1598,7 @@ static int st_lsm6dsx_read_raw(struct iio_dev *iio_dev, case IIO_CHAN_INFO_SCALE: *val = 0; *val2 = sensor->gain; - ret = IIO_VAL_INT_PLUS_MICRO; + ret = IIO_VAL_INT_PLUS_NANO; break; default: ret = -EINVAL; @@ -1836,13 +1836,31 @@ static ssize_t st_lsm6dsx_sysfs_scale_avail(struct device *dev, fs_table = &hw->settings->fs_table[sensor->id]; for (i = 0; i < fs_table->fs_len; i++) - len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ", + len += scnprintf(buf + len, PAGE_SIZE - len, "0.%09u ", fs_table->fs_avl[i].gain); buf[len - 1] = '\n'; return len; } +static int st_lsm6dsx_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + switch (mask) { + case IIO_CHAN_INFO_SCALE: + switch (chan->type) { + case IIO_ANGL_VEL: + case IIO_ACCEL: + return IIO_VAL_INT_PLUS_NANO; + default: + return IIO_VAL_INT_PLUS_MICRO; + } + default: + return IIO_VAL_INT_PLUS_MICRO; + } +} + static IIO_DEV_ATTR_SAMP_FREQ_AVAIL(st_lsm6dsx_sysfs_sampling_frequency_avail); static IIO_DEVICE_ATTR(in_accel_scale_available, 0444, st_lsm6dsx_sysfs_scale_avail, NULL, 0); @@ -1868,6 +1886,7 @@ static const struct iio_info st_lsm6dsx_acc_info = { .read_event_config = st_lsm6dsx_read_event_config, .write_event_config = st_lsm6dsx_write_event_config, .hwfifo_set_watermark = st_lsm6dsx_set_watermark, + .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, }; static struct attribute *st_lsm6dsx_gyro_attributes[] = { @@ -1885,6 +1904,7 @@ static const struct iio_info st_lsm6dsx_gyro_info = { .read_raw = st_lsm6dsx_read_raw, .write_raw = st_lsm6dsx_write_raw, .hwfifo_set_watermark = st_lsm6dsx_set_watermark, + .write_raw_get_fmt = st_lsm6dsx_write_raw_get_fmt, }; static int st_lsm6dsx_get_drdy_pin(struct st_lsm6dsx_hw *hw, int *drdy_pin) diff --git a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c index ed83471dc7dd..8c8d8870ca07 100644 --- a/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c +++ b/drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c @@ -313,6 +313,8 @@ st_lsm6dsx_shub_read(struct st_lsm6dsx_sensor *sensor, u8 addr, err = st_lsm6dsx_shub_read_output(hw, data, len & ST_LS6DSX_READ_OP_MASK); + if (err < 0) + return err; st_lsm6dsx_shub_master_enable(sensor, false); |