Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'iio-for-6.19a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio into char-misc-next

Jonathan writes:

IIO: New device support, features and cleanup for 6.19

The usual bunch of new device support, but also quite a bit of cleanup
of the core and older drivers which is always good to see.

New device support
------------------

adi,ad4080
- Add support for AD4081, AD4083, AD4084, AD4086 and AD4087 ADCs with
slightly different features to existing supported parts (max CNV clock
count, resolution etc)
adi,adxl380
- Add support for ADXL318 and ADXL319 which have reduced functionality
compared to other supported parts, particularly around event detection.
aosong,adp810
- New driver for this differential pressure and temperature sensor.
aspeed,adc
- Add support for the AST2700 SoC ADCs which differ in small ways from
already supported parts.
bosch,sm330
- New driver for this IMU (accelerometer + gyroscop) with I2C and SPI bus
support.
invensense,icm45600
- New driver for this family of IMUs with sub drivers for accelerometer
and gyroscope elements. I2C, I3C and SPI busses all supported.
* Supports ICM45605, ICM45606, ICM45608, ICM45634, ICM45686, ICM45687,
ICM45688P, ICM45689.
* Support basic features and FIFO.
maxim,max14001
- New driver for the MAX14001 and MAX14002 ADCs.
renesas,rzt2h
- New driver supporting the RZ/T2H and RZ/N2H ADCs found in various SoCs.
renesas,rznl
- New driver supporting the RZ/NL ADC found in various SoCs.

Features
--------

adi,ad5446
- Add a DT binding doc for the 29 variants currently covered by the driver.
- Add adi,ad5542 which is compatiable with the adi,ad5542a which was
already supported.
bosch,bma220
- I2C support including an I2C bus watchdog.
- Power supply control
- Data ready trigger.
- Low pass filter control.
- Debugfs register access.
- Add Petre Rodan as a maintainer of this driver (thanks!)
bosch,bmi270
- Add support for motion events.
fsl,mpl3115
- Add a dataready trigger and related sampling frequency control.
- Add threshold events.
infineon,dps310
- Add a specific device tree binding.
maxim,max30100
- Allow control of LED pulse-width in dt-binding. Optimum value depends
on physical characteristics of the device which contains this sensor.
mediatek,mt2701
- Add dt compatible for the mt8189.
rockchip,saradc
- Add rk3506 compatible which is functionally the same as the already
supported rk3528 (which is therefore the fallback)
st,lsm6dsx
- Make sampling more flexible when both fifo and events are of interest
by decoupling the FIFO fill rate from actual sampling.

Cleanup and minor fixes
-----------------------

core
- Document and add might_sleep() to iio_push_to_buffers_with_ts_unaligned()
as it allocates a buffer, typically just on 1st call.
- Add documentation for iio_push_to_buffers_with_ts() which is being used
to replace iio_push_to_buffers_with_timestamp() in new code as it
validates the buffer size. Make the deprecation of the old function
clear.
- Document that the store_to() callback in struct iio_buffer_access_funcs
may be called from contexts that cannot sleep.
- Document that the cb() provided to a callback buffer may be called
from contexts that cannot sleep.
- Cleanup up industrialio-backend.c comments.
- Call mutex_destroy() in cleanup of buffers.
- Call device_initialize() later to avoid having to call device_put()
before configuration is otherwise complete.
- Use mutex_init_with_key() to replace opencoded version.
- Use dma_buf_unmap_attachment_unlocked() to replace opencoded version.
- Reorder Makefile for pressure sensors.
various
- Uses sysfs_emit() to replace sprintf() in read_label() and other
callbacks that typically are used to write data to sysfs buffers.
- Switch to REGCACHE_MAPLE in various drivers.
adi,docs
- Fix up formatting of cross references and other kernel-doc issues.
adi,ad4080
- Fix wrong masking of product IDs.
adi,ad5446
- Use DMA safe buffers as needed for SPI.
- Drop a duplicate device chip specific data structure where two parts
are functionally identical.
- Fail probe if reference is not available.
- Split up the massive array of chip type specific structures into
separate structures as this tends to be easier to read and maintain.
- Add explicit of_device_id entries for all supported parts.
- Split I2C and SPI parts away from core to avoid ifdef complexity.
- Switch to devm_mutex_init().
- Make use of guard() to simplify code.
- Applying IWYU principles and reorder headers.
- Various other minor cleanup.
adi,ad7124
- Add debugfs to support single cycle mode, typically only used for cases
such as validate performance of the ADC.
- Various other minor cleanup including removing some layers of indirection
that weren't necessary.
- Add extended attributes to the temperature channel which follows the same
signal path as other channels.
- Replace the setup register allocation strategy with a simpler more
predictable one (a fix for OOB from this code follows later in this pull
request).
adi,adxl345
- Ensure dt-binding allows for both interrupt wired at the same time.
arm,scmi
- Replace const_ilog2() with the resulting value which ends up simpler
to read.
bosch,bma220
- Add correct SPI mode specification to the device tree binding.
- Fix up interrupt type in dt binding example to match that the driver
expects.
- Relax hard constraint on matching chip ID with a message only so as to
enable fallback DT compatibles to work.
- Use local struct device *dev to replaces lots of indirect look ups.
- Improve includes on approximate IWYU basis.
- Explicit of_match_table.
- Reset some registers during probe.
- Move to regmap.
- Ensure a timestamp is available when filling the buffer by using a
locally acquired one rather than relying on trigger top half running.
- Add a utility function to search value pair tables for a match.
- Various other minor improvements.
- Move code to avoid a false dependency of the core code on the I2C module.
bosch,bma400
- Improve register and field naming + organization. Use with FIELD_GET()
and FIELD_PREP() to allow dropping of shift defines.
- Use macros to define event related fields.
- Switch to an address lookup based on an index variable to replace lots of
very similar register macros.
- Rename activity_event_en() to generic_event_en() to better reflect what
it does.
- Improve comments around interrupt register handling.
fsl,mpl3115
- Factor out code for triggered buffer data collection.
- Use more consistent register field naming style.
- Use get_unaligned_be24() to get the pressure.
invensense,mpu6050
- Drop false requirement in DT binding for the interrupt. The driver will
be able to do less if one is not provided, but some features are still
available.
invensense,icm45600_i3c
- Fix missing return on failure to match part.
linear,ltc2688
- Use devm_mutex_init() so mutex_destroy() is called in tear down path.
- Use guard() to simplify lock handling in error return paths.
qcom,vadc
- Fix up some kernel-doc related warnings.
rohm,bd79112 and bd79124
- Use regmap_reg_range() helper to set the ranges.
st,lsm6dsx
- Fix units of ODR in structure documentation.
ti,am335x
- Add range checks to avoid a compiler warning.
ti,pac1934
- Switch to system_percpu_wq.

Various other minor typo fixes etc.

* tag 'iio-for-6.19a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (150 commits)
staging: iio: adt7316: replace sprintf() with sysfs_emit()
iio: pressure: Arrange Makefile alphabetically
iio: ABI: document pressure event attributes
iio: mpl3115: add threshold events support
iio: mpl3115: use get_unaligned_be24() to retrieve pressure data
iio: buffer: use dma_buf_unmap_attachment_unlocked() helper
iio: core: Replace lockdep_set_class() + mutex_init() by combined call
iio: core: Clean up device correctly on iio_device_alloc() failure
iio: core: add missing mutex_destroy in iio_dev_release()
iio: accel: adxl380: add support for ADXL318 and ADXL319
dt-bindings: iio: accel: adxl380: add new supported parts
iio: imu: inv_icm45600: Initializes inv_icm45600_buffer_postdisable() sleep
iio: adc: pac1934: replace use of system_wq with system_percpu_wq
iio: dac: ad5446: Add AD5542 to the spi id table
iio: dac: ad5446: Fix coding style issues
iio: dac: ad5446: Refactor header inclusion
iio: dac: ad5446: Make use of the cleanup helpers
iio: dac: ad5446: Make use of devm_mutex_init()
iio: dac: ad5446: Separate I2C/SPI into different drivers
iio: dac: ad5456: Add missing DT compatibles
...

+10734 -1503
+36
Documentation/ABI/testing/sysfs-bus-iio
··· 898 898 What: /sys/.../iio:deviceX/events/in_tempY_thresh_falling_en 899 899 What: /sys/.../iio:deviceX/events/in_capacitanceY_thresh_rising_en 900 900 What: /sys/.../iio:deviceX/events/in_capacitanceY_thresh_falling_en 901 + What: /sys/.../iio:deviceX/events/in_pressure_thresh_rising_en 901 902 KernelVersion: 2.6.37 902 903 Contact: linux-iio@vger.kernel.org 903 904 Description: ··· 927 926 What: /sys/.../iio:deviceX/events/in_accel_y_roc_falling_en 928 927 What: /sys/.../iio:deviceX/events/in_accel_z_roc_rising_en 929 928 What: /sys/.../iio:deviceX/events/in_accel_z_roc_falling_en 929 + What: /sys/.../iio:deviceX/events/in_accel_x&y&z_roc_rising_en 930 930 What: /sys/.../iio:deviceX/events/in_anglvel_x_roc_rising_en 931 931 What: /sys/.../iio:deviceX/events/in_anglvel_x_roc_falling_en 932 932 What: /sys/.../iio:deviceX/events/in_anglvel_y_roc_rising_en ··· 1003 1001 to the raw signal, allowing slow tracking to resume and the 1004 1002 adaptive threshold event detection to function as expected. 1005 1003 1004 + What: /sys/.../events/in_accel_mag_adaptive_rising_value 1006 1005 What: /sys/.../events/in_accel_thresh_rising_value 1007 1006 What: /sys/.../events/in_accel_thresh_falling_value 1008 1007 What: /sys/.../events/in_accel_x_raw_thresh_rising_value ··· 1048 1045 What: /sys/.../events/in_capacitanceY_thresh_falling_value 1049 1046 What: /sys/.../events/in_capacitanceY_thresh_adaptive_rising_value 1050 1047 What: /sys/.../events/in_capacitanceY_thresh_falling_rising_value 1048 + What: /sys/.../events/in_pressure_thresh_rising_value 1051 1049 KernelVersion: 2.6.37 1052 1050 Contact: linux-iio@vger.kernel.org 1053 1051 Description: ··· 1151 1147 will get activated once in_voltage0_raw goes above 1200 and will become 1152 1148 deactivated again once the value falls below 1150. 1153 1149 1150 + What: /sys/.../events/in_accel_roc_rising_value 1154 1151 What: /sys/.../events/in_accel_x_raw_roc_rising_value 1155 1152 What: /sys/.../events/in_accel_x_raw_roc_falling_value 1156 1153 What: /sys/.../events/in_accel_y_raw_roc_rising_value ··· 1198 1193 value is in raw device units or in processed units (as _raw 1199 1194 and _input do on sysfs direct channel read attributes). 1200 1195 1196 + What: /sys/.../events/in_accel_mag_adaptive_rising_period 1197 + What: /sys/.../events/in_accel_roc_rising_period 1201 1198 What: /sys/.../events/in_accel_x_thresh_rising_period 1202 1199 What: /sys/.../events/in_accel_x_thresh_falling_period 1203 1200 What: /sys/.../events/in_accel_x_roc_rising_period ··· 1368 1361 The value to which the magnitude of the channel is compared. If 1369 1362 number or direction is not specified, applies to all channels of 1370 1363 this type. 1364 + 1365 + What: /sys/.../iio:deviceX/events/in_accel_x_mag_adaptive_rising_en 1366 + What: /sys/.../iio:deviceX/events/in_accel_y_mag_adaptive_rising_en 1367 + What: /sys/.../iio:deviceX/events/in_accel_z_mag_adaptive_rising_en 1368 + KernelVersion: 2.6.37 1369 + Contact: linux-iio@vger.kernel.org 1370 + Description: 1371 + Similar to in_accel_x_thresh[_rising|_falling]_en, but here the 1372 + magnitude of the channel is compared to the adaptive threshold. 1371 1373 1372 1374 What: /sys/.../iio:deviceX/events/in_accel_mag_referenced_en 1373 1375 What: /sys/.../iio:deviceX/events/in_accel_mag_referenced_rising_en ··· 2438 2422 Value representing the user's attention to the system expressed 2439 2423 in units as percentage. This usually means if the user is 2440 2424 looking at the screen or not. 2425 + 2426 + What: /sys/.../events/in_accel_value_available 2427 + KernelVersion: 6.18 2428 + Contact: linux-iio@vger.kernel.org 2429 + Description: 2430 + List of available threshold values for acceleration event 2431 + generation. Applies to all event types on in_accel channels. 2432 + Units after application of scale and offset are m/s^2. 2433 + Expressed as: 2434 + 2435 + - a range specified as "[min step max]" 2436 + 2437 + What: /sys/.../events/in_accel_period_available 2438 + KernelVersion: 6.18 2439 + Contact: linux-iio@vger.kernel.org 2440 + Description: 2441 + List of available periods for accelerometer event detection in 2442 + seconds, expressed as: 2443 + 2444 + - a range specified as "[min step max]"
+7 -4
Documentation/devicetree/bindings/iio/accel/adi,adxl345.yaml
··· 35 35 spi-3wire: true 36 36 37 37 interrupts: 38 - maxItems: 1 38 + minItems: 1 39 + maxItems: 2 39 40 40 41 interrupt-names: 42 + minItems: 1 41 43 items: 42 44 - enum: [INT1, INT2] 45 + - const: INT2 43 46 44 47 dependencies: 45 48 interrupts: [ interrupt-names ] 46 - interrupt-names: [ interrupts ] 47 49 48 50 required: 49 51 - compatible ··· 86 84 spi-cpol; 87 85 spi-cpha; 88 86 interrupt-parent = <&gpio0>; 89 - interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; 90 - interrupt-names = "INT2"; 87 + interrupts = <0 IRQ_TYPE_LEVEL_HIGH>, 88 + <1 IRQ_TYPE_LEVEL_HIGH>; 89 + interrupt-names = "INT1", "INT2"; 91 90 }; 92 91 };
+7 -4
Documentation/devicetree/bindings/iio/accel/adi,adxl380.yaml
··· 11 11 - Antoniu Miclaus <antoniu.miclaus@analog.com> 12 12 13 13 description: | 14 - The ADXL380/ADXL382 is a low noise density, low power, 3-axis 15 - accelerometer with selectable measurement ranges. The ADXL380 16 - supports the ±4 g, ±8 g, and ±16 g ranges, and the ADXL382 supports 17 - ±15 g, ±30 g, and ±60 g ranges. 14 + The ADXL380/ADXL382 and ADXL318/ADXL319 are low noise density, 15 + low power, 3-axis accelerometers with selectable measurement ranges. 16 + The ADXL380 and ADXL318 support the ±4 g, ±8 g, and ±16 g ranges, 17 + while the ADXL382 and ADXL319 support ±15 g, ±30 g, and ±60 g ranges. 18 18 19 + https://www.analog.com/en/products/adxl318.html 19 20 https://www.analog.com/en/products/adxl380.html 20 21 21 22 properties: 22 23 compatible: 23 24 enum: 25 + - adi,adxl318 26 + - adi,adxl319 24 27 - adi,adxl380 25 28 - adi,adxl382 26 29
+7 -2
Documentation/devicetree/bindings/iio/accel/bosch,bma220.yaml
··· 4 4 $id: http://devicetree.org/schemas/iio/accel/bosch,bma220.yaml# 5 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 6 6 7 - title: Bosch BMA220 Trixial Acceleration Sensor 7 + title: Bosch BMA220 Triaxial Acceleration Sensor 8 8 9 9 maintainers: 10 10 - Jonathan Cameron <Jonathan.Cameron@huawei.com> ··· 19 19 20 20 interrupts: 21 21 maxItems: 1 22 + 23 + spi-cpha: true 24 + spi-cpol: true 22 25 23 26 vdda-supply: true 24 27 vddd-supply: true ··· 47 44 compatible = "bosch,bma220"; 48 45 reg = <0>; 49 46 spi-max-frequency = <2500000>; 47 + spi-cpol; 48 + spi-cpha; 50 49 interrupt-parent = <&gpio0>; 51 - interrupts = <0 IRQ_TYPE_LEVEL_HIGH>; 50 + interrupts = <0 IRQ_TYPE_EDGE_RISING>; 52 51 }; 53 52 }; 54 53 ...
+5
Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
··· 26 26 compatible: 27 27 enum: 28 28 - adi,ad4080 29 + - adi,ad4081 30 + - adi,ad4083 31 + - adi,ad4084 32 + - adi,ad4086 33 + - adi,ad4087 29 34 30 35 reg: 31 36 maxItems: 1
+89
Documentation/devicetree/bindings/iio/adc/adi,max14001.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + # Copyright 2023-2025 Analog Devices Inc. 3 + # Copyright 2023 Kim Seer Paller 4 + # Copyright 2025 Marilene Andrade Garcia 5 + %YAML 1.2 6 + --- 7 + $id: http://devicetree.org/schemas/iio/adc/adi,max14001.yaml# 8 + $schema: http://devicetree.org/meta-schemas/core.yaml# 9 + 10 + title: Analog Devices MAX14001-MAX14002 ADC 11 + 12 + maintainers: 13 + - Kim Seer Paller <kimseer.paller@analog.com> 14 + - Marilene Andrade Garcia <marilene.agarcia@gmail.com> 15 + 16 + description: | 17 + Single channel 10 bit ADC with SPI interface. 18 + Datasheet can be found here 19 + https://www.analog.com/media/en/technical-documentation/data-sheets/MAX14001-MAX14002.pdf 20 + 21 + $ref: /schemas/spi/spi-peripheral-props.yaml# 22 + 23 + properties: 24 + compatible: 25 + oneOf: 26 + - const: adi,max14002 27 + - items: 28 + - const: adi,max14001 29 + - const: adi,max14002 30 + 31 + reg: 32 + maxItems: 1 33 + 34 + spi-max-frequency: 35 + maximum: 5000000 36 + 37 + vdd-supply: 38 + description: 39 + Isolated DC-DC power supply input voltage. 40 + 41 + vddl-supply: 42 + description: 43 + Logic power supply. 44 + 45 + refin-supply: 46 + description: 47 + ADC voltage reference supply. 48 + 49 + interrupts: 50 + minItems: 1 51 + items: 52 + - description: | 53 + cout: comparator output signal that asserts high on the COUT pin 54 + when ADC readings exceed the upper threshold and low when readings 55 + fall below the lower threshold. 56 + - description: | 57 + fault: when fault reporting is enabled, the FAULT pin is asserted 58 + low whenever one of the monitored fault conditions occurs. 59 + 60 + interrupt-names: 61 + minItems: 1 62 + items: 63 + - const: cout 64 + - const: fault 65 + 66 + required: 67 + - compatible 68 + - reg 69 + - vdd-supply 70 + - vddl-supply 71 + 72 + unevaluatedProperties: false 73 + 74 + examples: 75 + - | 76 + spi { 77 + #address-cells = <1>; 78 + #size-cells = <0>; 79 + 80 + adc@0 { 81 + compatible = "adi,max14001", "adi,max14002"; 82 + reg = <0>; 83 + spi-max-frequency = <5000000>; 84 + spi-lsb-first; 85 + vdd-supply = <&vdd>; 86 + vddl-supply = <&vddl>; 87 + }; 88 + }; 89 + ...
+2
Documentation/devicetree/bindings/iio/adc/aspeed,ast2600-adc.yaml
··· 29 29 enum: 30 30 - aspeed,ast2600-adc0 31 31 - aspeed,ast2600-adc1 32 + - aspeed,ast2700-adc0 33 + - aspeed,ast2700-adc1 32 34 description: 33 35 Their trimming data, which is used to calibrate internal reference volage, 34 36 locates in different address of OTP.
+1
Documentation/devicetree/bindings/iio/adc/mediatek,mt2701-auxadc.yaml
··· 42 42 - mediatek,mt8183-auxadc 43 43 - mediatek,mt8186-auxadc 44 44 - mediatek,mt8188-auxadc 45 + - mediatek,mt8189-auxadc 45 46 - mediatek,mt8195-auxadc 46 47 - mediatek,mt8516-auxadc 47 48 - const: mediatek,mt8173-auxadc
+135
Documentation/devicetree/bindings/iio/adc/renesas,r9a09g077-adc.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/iio/adc/renesas,r9a09g077-adc.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Renesas RZ/T2H / RZ/N2H ADC12 8 + 9 + maintainers: 10 + - Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> 11 + 12 + description: | 13 + A/D Converter block is a successive approximation analog-to-digital converter 14 + with a 12-bit accuracy. Up to 16 analog input channels can be selected. 15 + Conversions can be performed in single or continuous mode. Result of the ADC 16 + is stored in a 16-bit data register corresponding to each channel. 17 + 18 + properties: 19 + compatible: 20 + oneOf: 21 + - items: 22 + - const: renesas,r9a09g087-adc # RZ/N2H 23 + - const: renesas,r9a09g077-adc # RZ/T2H 24 + - items: 25 + - const: renesas,r9a09g077-adc # RZ/T2H 26 + 27 + reg: 28 + maxItems: 1 29 + 30 + interrupts: 31 + items: 32 + - description: A/D scan end interrupt 33 + - description: A/D scan end interrupt for Group B 34 + - description: A/D scan end interrupt for Group C 35 + - description: Window A compare match 36 + - description: Window B compare match 37 + - description: Compare match 38 + - description: Compare mismatch 39 + 40 + interrupt-names: 41 + items: 42 + - const: adi 43 + - const: gbadi 44 + - const: gcadi 45 + - const: cmpai 46 + - const: cmpbi 47 + - const: wcmpm 48 + - const: wcmpum 49 + 50 + clocks: 51 + items: 52 + - description: Converter clock 53 + - description: Peripheral clock 54 + 55 + clock-names: 56 + items: 57 + - const: adclk 58 + - const: pclk 59 + 60 + power-domains: 61 + maxItems: 1 62 + 63 + '#address-cells': 64 + const: 1 65 + 66 + '#size-cells': 67 + const: 0 68 + 69 + "#io-channel-cells": 70 + const: 1 71 + 72 + patternProperties: 73 + "^channel@[0-9a-f]$": 74 + $ref: adc.yaml 75 + type: object 76 + description: The external channels which are connected to the ADC. 77 + 78 + properties: 79 + reg: 80 + description: The channel number. 81 + maximum: 15 82 + 83 + required: 84 + - reg 85 + 86 + additionalProperties: false 87 + 88 + required: 89 + - compatible 90 + - reg 91 + - interrupts 92 + - clocks 93 + - clock-names 94 + - power-domains 95 + 96 + additionalProperties: false 97 + 98 + examples: 99 + - | 100 + #include <dt-bindings/clock/renesas,r9a09g077-cpg-mssr.h> 101 + #include <dt-bindings/interrupt-controller/arm-gic.h> 102 + 103 + adc@80008000 { 104 + compatible = "renesas,r9a09g077-adc"; 105 + reg = <0x80008000 0x400>; 106 + interrupts = <GIC_SPI 708 IRQ_TYPE_EDGE_RISING>, 107 + <GIC_SPI 709 IRQ_TYPE_EDGE_RISING>, 108 + <GIC_SPI 710 IRQ_TYPE_EDGE_RISING>, 109 + <GIC_SPI 711 IRQ_TYPE_LEVEL_HIGH>, 110 + <GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>, 111 + <GIC_SPI 855 IRQ_TYPE_EDGE_RISING>, 112 + <GIC_SPI 856 IRQ_TYPE_EDGE_RISING>; 113 + interrupt-names = "adi", "gbadi", "gcadi", 114 + "cmpai", "cmpbi", "wcmpm", "wcmpum"; 115 + clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKL>, 116 + <&cpg CPG_MOD 225>; 117 + clock-names = "adclk", "pclk"; 118 + power-domains = <&cpg>; 119 + #address-cells = <1>; 120 + #size-cells = <0>; 121 + #io-channel-cells = <1>; 122 + 123 + channel@0 { 124 + reg = <0x0>; 125 + }; 126 + channel@1 { 127 + reg = <0x1>; 128 + }; 129 + channel@2 { 130 + reg = <0x2>; 131 + }; 132 + channel@3 { 133 + reg = <0x3>; 134 + }; 135 + };
+111
Documentation/devicetree/bindings/iio/adc/renesas,rzn1-adc.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/iio/adc/renesas,rzn1-adc.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Renesas RZ/N1 Analog to Digital Converter (ADC) 8 + 9 + maintainers: 10 + - Herve Codina <herve.codina@bootlin.com> 11 + 12 + description: 13 + The Renesas RZ/N1 ADC controller available in the Renesas RZ/N1 SoCs family 14 + can use up to two internal ADC cores (ADC1 and ADC2) those internal cores are 15 + handled through ADC controller virtual channels. 16 + 17 + properties: 18 + compatible: 19 + items: 20 + - const: renesas,r9a06g032-adc # RZ/N1D 21 + - const: renesas,rzn1-adc 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + clocks: 27 + items: 28 + - description: APB internal bus clock 29 + - description: ADC clock 30 + 31 + clock-names: 32 + items: 33 + - const: pclk 34 + - const: adc 35 + 36 + power-domains: 37 + maxItems: 1 38 + 39 + adc1-avdd-supply: 40 + description: 41 + ADC1 analog power supply. 42 + 43 + adc1-vref-supply: 44 + description: 45 + ADC1 reference voltage supply. 46 + 47 + adc2-avdd-supply: 48 + description: 49 + ADC2 analog power supply. 50 + 51 + adc2-vref-supply: 52 + description: 53 + ADC2 reference voltage supply. 54 + 55 + '#io-channel-cells': 56 + const: 1 57 + description: | 58 + Channels numbers available: 59 + if ADC1 is used (i.e. adc1-{avdd,vref}-supply present): 60 + - 0: ADC1 IN0 61 + - 1: ADC1 IN1 62 + - 2: ADC1 IN2 63 + - 3: ADC1 IN3 64 + - 4: ADC1 IN4 65 + - 5: ADC1 IN6 66 + - 6: ADC1 IN7 67 + - 7: ADC1 IN8 68 + if ADC2 is used (i.e. adc2-{avdd,vref}-supply present): 69 + - 8: ADC2 IN0 70 + - 9: ADC2 IN1 71 + - 10: ADC2 IN2 72 + - 11: ADC2 IN3 73 + - 12: ADC2 IN4 74 + - 13: ADC2 IN6 75 + - 14: ADC2 IN7 76 + - 15: ADC2 IN8 77 + 78 + required: 79 + - compatible 80 + - reg 81 + - clocks 82 + - clock-names 83 + - power-domains 84 + - '#io-channel-cells' 85 + 86 + # At least one of avvd/vref supplies 87 + anyOf: 88 + - required: 89 + - adc1-vref-supply 90 + - adc1-avdd-supply 91 + - required: 92 + - adc2-vref-supply 93 + - adc2-avdd-supply 94 + 95 + additionalProperties: false 96 + 97 + examples: 98 + - | 99 + #include <dt-bindings/clock/r9a06g032-sysctrl.h> 100 + 101 + adc: adc@40065000 { 102 + compatible = "renesas,r9a06g032-adc", "renesas,rzn1-adc"; 103 + reg = <0x40065000 0x200>; 104 + clocks = <&sysctrl R9A06G032_HCLK_ADC>, <&sysctrl R9A06G032_CLK_ADC>; 105 + clock-names = "pclk", "adc"; 106 + power-domains = <&sysctrl>; 107 + adc1-avdd-supply = <&adc1_avdd>; 108 + adc1-vref-supply = <&adc1_vref>; 109 + #io-channel-cells = <1>; 110 + }; 111 + ...
+3
Documentation/devicetree/bindings/iio/adc/rockchip-saradc.yaml
··· 16 16 - const: rockchip,rk3066-tsadc 17 17 - const: rockchip,rk3399-saradc 18 18 - const: rockchip,rk3528-saradc 19 + - items: 20 + - const: rockchip,rk3506-saradc 21 + - const: rockchip,rk3528-saradc 19 22 - const: rockchip,rk3562-saradc 20 23 - const: rockchip,rk3588-saradc 21 24 - items:
+138
Documentation/devicetree/bindings/iio/dac/adi,ad5446.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/iio/dac/adi,ad5446.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Analog Devices AD5446 and similar DACs 8 + 9 + maintainers: 10 + - Michael Hennerich <michael.hennerich@analog.com> 11 + - Nuno Sá <nuno.sa@analog.com> 12 + 13 + description: 14 + Digital to Analog Converter devices supporting both SPI and I2C interfaces. 15 + These devices feature a range of resolutions from 8-bit to 16-bit. 16 + 17 + properties: 18 + compatible: 19 + oneOf: 20 + - description: SPI DACs 21 + enum: 22 + - adi,ad5300 23 + - adi,ad5310 24 + - adi,ad5320 25 + - adi,ad5444 26 + - adi,ad5446 27 + - adi,ad5450 28 + - adi,ad5451 29 + - adi,ad5452 30 + - adi,ad5453 31 + - adi,ad5512a 32 + - adi,ad5541a 33 + - adi,ad5542 34 + - adi,ad5542a 35 + - adi,ad5543 36 + - adi,ad5553 37 + - adi,ad5600 38 + - adi,ad5601 39 + - adi,ad5611 40 + - adi,ad5621 41 + - adi,ad5641 42 + - adi,ad5620-2500 43 + - adi,ad5620-1250 44 + - adi,ad5640-2500 45 + - adi,ad5640-1250 46 + - adi,ad5660-2500 47 + - adi,ad5660-1250 48 + - adi,ad5662 49 + - ti,dac081s101 50 + - ti,dac101s101 51 + - ti,dac121s101 52 + - description: I2C DACs 53 + enum: 54 + - adi,ad5301 55 + - adi,ad5311 56 + - adi,ad5321 57 + - adi,ad5602 58 + - adi,ad5612 59 + - adi,ad5622 60 + 61 + reg: 62 + maxItems: 1 63 + 64 + vcc-supply: 65 + description: 66 + Reference voltage supply. If not supplied, devices with internal 67 + voltage reference will use that. 68 + 69 + required: 70 + - compatible 71 + - reg 72 + 73 + allOf: 74 + - if: 75 + properties: 76 + compatible: 77 + contains: 78 + enum: 79 + - adi,ad5300 80 + - adi,ad5310 81 + - adi,ad5320 82 + - adi,ad5444 83 + - adi,ad5446 84 + - adi,ad5450 85 + - adi,ad5451 86 + - adi,ad5452 87 + - adi,ad5453 88 + - adi,ad5512a 89 + - adi,ad5541a 90 + - adi,ad5542 91 + - adi,ad5542a 92 + - adi,ad5543 93 + - adi,ad5553 94 + - adi,ad5600 95 + - adi,ad5601 96 + - adi,ad5611 97 + - adi,ad5621 98 + - adi,ad5641 99 + - adi,ad5620-2500 100 + - adi,ad5620-1250 101 + - adi,ad5640-2500 102 + - adi,ad5640-1250 103 + - adi,ad5660-2500 104 + - adi,ad5660-1250 105 + - adi,ad5662 106 + - ti,dac081s101 107 + - ti,dac101s101 108 + - ti,dac121s101 109 + then: 110 + allOf: 111 + - $ref: /schemas/spi/spi-peripheral-props.yaml# 112 + 113 + unevaluatedProperties: false 114 + 115 + examples: 116 + - | 117 + spi { 118 + #address-cells = <1>; 119 + #size-cells = <0>; 120 + 121 + dac@0 { 122 + compatible = "adi,ad5446"; 123 + reg = <0>; 124 + vcc-supply = <&dac_vref>; 125 + }; 126 + }; 127 + - | 128 + i2c { 129 + #address-cells = <1>; 130 + #size-cells = <0>; 131 + 132 + dac@42 { 133 + compatible = "adi,ad5622"; 134 + reg = <0x42>; 135 + vcc-supply = <&dac_vref>; 136 + }; 137 + }; 138 + ...
+8
Documentation/devicetree/bindings/iio/health/maxim,max30100.yaml
··· 27 27 LED current whilst the engine is running. First indexed value is 28 28 the configuration for the RED LED, and second value is for the IR LED. 29 29 30 + maxim,pulse-width-us: 31 + description: | 32 + LED pulse width in microseconds. Appropriate pulse width depends on 33 + factors such as optical window absorption, LED-to-sensor distance, 34 + and expected reflectivity of the skin or contact surface. 35 + enum: [200, 400, 800, 1600] 36 + default: 1600 37 + 30 38 additionalProperties: false 31 39 32 40 required:
+90
Documentation/devicetree/bindings/iio/imu/bosch,smi330.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/iio/imu/bosch,smi330.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Bosch SMI330 6-Axis IMU 8 + 9 + maintainers: 10 + - Stefan Gutmann <stefam.gutmann@de.bosch.com> 11 + 12 + description: 13 + SMI330 is a 6-axis inertial measurement unit that supports acceleration and 14 + gyroscopic measurements with hardware fifo buffering. Sensor also provides 15 + events information such as motion, no-motion and tilt detection. 16 + 17 + properties: 18 + compatible: 19 + const: bosch,smi330 20 + 21 + reg: 22 + maxItems: 1 23 + 24 + vdd-supply: 25 + description: provide VDD power to the sensor. 26 + 27 + vddio-supply: 28 + description: provide VDD IO power to the sensor. 29 + 30 + interrupts: 31 + minItems: 1 32 + maxItems: 2 33 + 34 + interrupt-names: 35 + minItems: 1 36 + maxItems: 2 37 + items: 38 + enum: 39 + - INT1 40 + - INT2 41 + 42 + drive-open-drain: 43 + type: boolean 44 + description: 45 + set if the interrupt pin(s) should be configured as 46 + open drain. If not set, defaults to push-pull. 47 + 48 + required: 49 + - compatible 50 + - reg 51 + 52 + allOf: 53 + - $ref: /schemas/spi/spi-peripheral-props.yaml# 54 + 55 + unevaluatedProperties: false 56 + 57 + examples: 58 + - | 59 + // Example for I2C 60 + #include <dt-bindings/interrupt-controller/irq.h> 61 + i2c { 62 + #address-cells = <1>; 63 + #size-cells = <0>; 64 + 65 + imu@68 { 66 + compatible = "bosch,smi330"; 67 + reg = <0x68>; 68 + vddio-supply = <&vddio>; 69 + vdd-supply = <&vdd>; 70 + interrupt-parent = <&gpio>; 71 + interrupts = <26 IRQ_TYPE_EDGE_RISING>; 72 + interrupt-names = "INT1"; 73 + }; 74 + }; 75 + 76 + // Example for SPI 77 + #include <dt-bindings/interrupt-controller/irq.h> 78 + spi { 79 + #address-cells = <1>; 80 + #size-cells = <0>; 81 + 82 + imu@0 { 83 + compatible = "bosch,smi330"; 84 + reg = <0>; 85 + spi-max-frequency = <10000000>; 86 + interrupt-parent = <&gpio>; 87 + interrupts = <26 IRQ_TYPE_EDGE_RISING>; 88 + interrupt-names = "INT1"; 89 + }; 90 + };
+90
Documentation/devicetree/bindings/iio/imu/invensense,icm45600.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/iio/imu/invensense,icm45600.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: InvenSense ICM-45600 Inertial Measurement Unit 8 + 9 + maintainers: 10 + - Remi Buisson <remi.buisson@tdk.com> 11 + 12 + description: | 13 + 6-axis MotionTracking device that combines a 3-axis gyroscope and a 3-axis 14 + accelerometer. 15 + 16 + It has a configurable host interface that supports I3C, I2C and SPI serial 17 + communication, features up to 8kB FIFO and 2 programmable interrupts with 18 + ultra-low-power wake-on-motion support to minimize system power consumption. 19 + 20 + Other industry-leading features include InvenSense on-chip APEX Motion 21 + Processing engine for gesture recognition, activity classification, and 22 + pedometer, along with programmable digital filters, and an embedded 23 + temperature sensor. 24 + 25 + https://invensense.tdk.com/wp-content/uploads/documentation/DS-000576_ICM-45605.pdf 26 + 27 + properties: 28 + compatible: 29 + enum: 30 + - invensense,icm45605 31 + - invensense,icm45606 32 + - invensense,icm45608 33 + - invensense,icm45634 34 + - invensense,icm45686 35 + - invensense,icm45687 36 + - invensense,icm45688p 37 + - invensense,icm45689 38 + 39 + reg: 40 + maxItems: 1 41 + 42 + interrupts: 43 + minItems: 1 44 + maxItems: 2 45 + 46 + interrupt-names: 47 + minItems: 1 48 + items: 49 + - enum: [int1, int2] 50 + - const: int2 51 + description: Choose chip interrupt pin to be used as interrupt input. 52 + 53 + drive-open-drain: 54 + type: boolean 55 + 56 + vdd-supply: true 57 + 58 + vddio-supply: true 59 + 60 + mount-matrix: true 61 + 62 + required: 63 + - compatible 64 + - reg 65 + - vdd-supply 66 + - vddio-supply 67 + 68 + unevaluatedProperties: false 69 + 70 + examples: 71 + - | 72 + #include <dt-bindings/gpio/gpio.h> 73 + #include <dt-bindings/interrupt-controller/irq.h> 74 + i2c { 75 + #address-cells = <1>; 76 + #size-cells = <0>; 77 + 78 + imu@68 { 79 + compatible = "invensense,icm45605"; 80 + reg = <0x68>; 81 + interrupt-parent = <&gpio2>; 82 + interrupt-names = "int1"; 83 + interrupts = <7 IRQ_TYPE_EDGE_RISING>; 84 + vdd-supply = <&vdd>; 85 + vddio-supply = <&vddio>; 86 + mount-matrix = "0", "-1", "0", 87 + "1", "0", "0", 88 + "0", "0", "1"; 89 + }; 90 + };
-1
Documentation/devicetree/bindings/iio/imu/invensense,mpu6050.yaml
··· 86 86 required: 87 87 - compatible 88 88 - reg 89 - - interrupts 90 89 91 90 examples: 92 91 - |
+45
Documentation/devicetree/bindings/iio/pressure/aosong,adp810.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/iio/pressure/aosong,adp810.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: aosong adp810 differential pressure sensor 8 + 9 + maintainers: 10 + - Akhilesh Patil <akhilesh@ee.iitb.ac.in> 11 + 12 + description: 13 + ADP810 is differential pressure and temperature sensor. It has I2C bus 14 + interface with fixed address of 0x25. This sensor supports 8 bit CRC for 15 + reliable data transfer. It can measure differential pressure in the 16 + range -500 to 500Pa and temperate in the range -40 to +85 degree celsius. 17 + 18 + properties: 19 + compatible: 20 + enum: 21 + - aosong,adp810 22 + 23 + reg: 24 + maxItems: 1 25 + 26 + vdd-supply: true 27 + 28 + required: 29 + - compatible 30 + - reg 31 + - vdd-supply 32 + 33 + additionalProperties: false 34 + 35 + examples: 36 + - | 37 + i2c { 38 + #address-cells = <1>; 39 + #size-cells = <0>; 40 + pressure-sensor@25 { 41 + compatible = "aosong,adp810"; 42 + reg = <0x25>; 43 + vdd-supply = <&vdd_regulator>; 44 + }; 45 + };
+71
Documentation/devicetree/bindings/iio/pressure/fsl,mpl3115.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/iio/pressure/fsl,mpl3115.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: MPL3115 precision pressure sensor with altimetry 8 + 9 + maintainers: 10 + - Antoni Pokusinski <apokusinski01@gmail.com> 11 + 12 + description: | 13 + MPL3115 is a pressure/altitude and temperature sensor with I2C interface. 14 + It features two programmable interrupt lines which indicate events such as 15 + data ready or pressure/temperature threshold reached. 16 + https://www.nxp.com/docs/en/data-sheet/MPL3115A2.pdf 17 + 18 + properties: 19 + compatible: 20 + const: fsl,mpl3115 21 + 22 + reg: 23 + maxItems: 1 24 + 25 + vdd-supply: true 26 + 27 + vddio-supply: true 28 + 29 + interrupts: 30 + minItems: 1 31 + maxItems: 2 32 + 33 + interrupt-names: 34 + minItems: 1 35 + maxItems: 2 36 + items: 37 + enum: 38 + - INT1 39 + - INT2 40 + 41 + drive-open-drain: 42 + type: boolean 43 + description: 44 + set if the specified interrupt pins should be configured as 45 + open drain. If not set, defaults to push-pull. 46 + 47 + required: 48 + - compatible 49 + - reg 50 + - vdd-supply 51 + - vddio-supply 52 + 53 + additionalProperties: false 54 + 55 + examples: 56 + - | 57 + #include <dt-bindings/interrupt-controller/irq.h> 58 + i2c { 59 + #address-cells = <1>; 60 + #size-cells = <0>; 61 + 62 + pressure@60 { 63 + compatible = "fsl,mpl3115"; 64 + reg = <0x60>; 65 + vdd-supply = <&vdd>; 66 + vddio-supply = <&vddio>; 67 + interrupt-parent = <&gpio1>; 68 + interrupts = <4 IRQ_TYPE_EDGE_FALLING>; 69 + interrupt-names = "INT2"; 70 + }; 71 + };
+54
Documentation/devicetree/bindings/iio/pressure/infineon,dps310.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/iio/pressure/infineon,dps310.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Infineon DPS310 barometric pressure and temperature sensor 8 + 9 + maintainers: 10 + - Eddie James <eajames@linux.ibm.com> 11 + 12 + description: 13 + The DPS310 is a barometric pressure and temperature sensor with an I2C 14 + interface. 15 + 16 + properties: 17 + compatible: 18 + enum: 19 + - infineon,dps310 20 + 21 + reg: 22 + maxItems: 1 23 + 24 + "#io-channel-cells": 25 + const: 0 26 + 27 + vdd-supply: 28 + description: 29 + Voltage supply for the chip's analog blocks. 30 + 31 + vddio-supply: 32 + description: 33 + Digital voltage supply for the chip's digital blocks and I/O interface. 34 + 35 + required: 36 + - compatible 37 + - reg 38 + 39 + additionalProperties: false 40 + 41 + examples: 42 + - | 43 + i2c { 44 + #address-cells = <1>; 45 + #size-cells = <0>; 46 + 47 + dps: pressure-sensor@76 { 48 + compatible = "infineon,dps310"; 49 + reg = <0x76>; 50 + #io-channel-cells = <0>; 51 + vdd-supply = <&vref1>; 52 + vddio-supply = <&vref2>; 53 + }; 54 + };
-4
Documentation/devicetree/bindings/trivial-devices.yaml
··· 113 113 - fsl,mma7660 114 114 # MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer 115 115 - fsl,mma8450 116 - # MPL3115: Absolute Digital Pressure Sensor 117 - - fsl,mpl3115 118 116 # MPR121: Proximity Capacitive Touch Sensor Controller 119 117 - fsl,mpr121 120 118 # Honeywell Humidicon HIH-6130 humidity/temperature sensor ··· 125 127 - ibm,cffps2 126 128 # IBM On-Chip Controller hwmon device 127 129 - ibm,p8-occ-hwmon 128 - # Infineon barometric pressure and temperature sensor 129 - - infineon,dps310 130 130 # Infineon IR36021 digital POL buck controller 131 131 - infineon,ir36021 132 132 # Infineon IRPS5401 Voltage Regulator (PMIC)
+1 -1
Documentation/iio/ade9000.rst
··· 264 264 8. IIO Interfacing Tools 265 265 ======================== 266 266 267 - See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO 267 + See Documentation/iio/iio_tools.rst for the description of the available IIO 268 268 interfacing tools.
+2 -2
Documentation/iio/adis16475.rst
··· 374 374 00001740 01 1a 00 00 ff ff fe 31 00 00 46 aa 00 03 37 f7 |.......1..F...7.| 375 375 ... 376 376 377 - See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered 377 + See Documentation/iio/iio_devbuf.rst for more information about how buffered 378 378 data is structured. 379 379 380 380 4. IIO Interfacing Tools 381 381 ======================== 382 382 383 - See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO 383 + See Documentation/iio/iio_tools.rst for the description of the available IIO 384 384 interfacing tools.
+2 -2
Documentation/iio/adis16480.rst
··· 436 436 00006b60 09 63 00 00 00 00 1b 13 00 00 22 2f 00 03 23 91 |.c........"/..#.| 437 437 ... 438 438 439 - See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered 439 + See Documentation/iio/iio_devbuf.rst for more information about how buffered 440 440 data is structured. 441 441 442 442 4. IIO Interfacing Tools 443 443 ======================== 444 444 445 - See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO 445 + See Documentation/iio/iio_tools.rst for the description of the available IIO 446 446 interfacing tools.
+2 -2
Documentation/iio/adis16550.rst
··· 366 366 0000ceb0 00 00 0d 2f 00 00 05 25 00 00 07 8d 00 00 a2 ce |.../...%........| 367 367 ... 368 368 369 - See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered 369 + See Documentation/iio/iio_devbuf.rst for more information about how buffered 370 370 data is structured. 371 371 372 372 4. IIO Interfacing Tools 373 373 ======================== 374 374 375 - See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO 375 + See Documentation/iio/iio_tools.rst for the description of the available IIO 376 376 interfacing tools.
+2 -2
Documentation/iio/adxl345.rst
··· 433 433 00000f0 00004 00014 00015 00005 00012 00011 00005 00012 434 434 ... 435 435 436 - See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered 436 + See Documentation/iio/iio_devbuf.rst for more information about how buffered 437 437 data is structured. 438 438 439 439 4. IIO Interfacing Tools 440 440 ======================== 441 441 442 - See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO 442 + See Documentation/iio/iio_tools.rst for the description of the available IIO 443 443 interfacing tools.
+2 -2
Documentation/iio/adxl380.rst
··· 223 223 002bc3c0 f7 fd 00 cb fb 94 24 80 f7 e3 00 f2 fb b8 24 80 |......$.......$.| 224 224 ... 225 225 226 - See ``Documentation/iio/iio_devbuf.rst`` for more information about how buffered 226 + See Documentation/iio/iio_devbuf.rst for more information about how buffered 227 227 data is structured. 228 228 229 229 4. IIO Interfacing Tools 230 230 ======================== 231 231 232 - See ``Documentation/iio/iio_tools.rst`` for the description of the available IIO 232 + See Documentation/iio/iio_tools.rst for the description of the available IIO 233 233 interfacing tools.
+59
MAINTAINERS
··· 440 440 W: https://ez.analog.com/linux-software-drivers 441 441 F: drivers/regulator/ad5398.c 442 442 443 + AD5446 ANALOG DEVICES INC AD5446 DAC DRIVER 444 + M: Michael Hennerich <michael.hennerich@analog.com> 445 + M: Nuno Sá <nuno.sa@analog.com> 446 + L: linux-iio@vger.kernel.org 447 + S: Supported 448 + W: https://ez.analog.com/linux-software-drivers 449 + F: Documentation/devicetree/bindings/iio/dac/adi,ad5446.yaml 450 + F: drivers/iio/dac/ad5446-i2c.c 451 + F: drivers/iio/dac/ad5446-spi.c 452 + F: drivers/iio/dac/ad5446.c 453 + F: drivers/iio/dac/ad5446.h 454 + 443 455 AD714X CAPACITANCE TOUCH SENSOR DRIVER (AD7142/3/7/8/7A) 444 456 M: Michael Hennerich <michael.hennerich@analog.com> 445 457 S: Supported ··· 3761 3749 F: Documentation/devicetree/bindings/iio/chemical/aosong,ags02ma.yaml 3762 3750 F: drivers/iio/chemical/ags02ma.c 3763 3751 3752 + AOSONG ADP810 DIFFERENTIAL PRESSURE SENSOR DRIVER 3753 + M: Akhilesh Patil <akhilesh@ee.iitb.ac.in> 3754 + L: linux-iio@vger.kernel.org 3755 + S: Maintained 3756 + F: Documentation/devicetree/bindings/iio/pressure/aosong,adp810.yaml 3757 + F: drivers/iio/pressure/adp810.c 3758 + 3764 3759 ASC7621 HARDWARE MONITOR DRIVER 3765 3760 M: George Joseph <george.joseph@fairview5.com> 3766 3761 L: linux-hwmon@vger.kernel.org ··· 4490 4471 F: include/net/bond* 4491 4472 F: include/uapi/linux/if_bonding.h 4492 4473 F: tools/testing/selftests/drivers/net/bonding/ 4474 + 4475 + BOSCH SENSORTEC BMA220 ACCELEROMETER IIO DRIVER 4476 + M: Petre Rodan <petre.rodan@subdimension.ro> 4477 + L: linux-iio@vger.kernel.org 4478 + S: Maintained 4479 + F: Documentation/devicetree/bindings/iio/accel/bosch,bma220.yaml 4480 + F: drivers/iio/accel/bma220* 4493 4481 4494 4482 BOSCH SENSORTEC BMA400 ACCELEROMETER IIO DRIVER 4495 4483 M: Dan Robertson <dan@dlrobertson.com> ··· 12254 12228 M: Eddie James <eajames@linux.ibm.com> 12255 12229 L: linux-iio@vger.kernel.org 12256 12230 S: Maintained 12231 + F: Documentation/devicetree/bindings/iio/pressure/infineon,dps310.yaml 12257 12232 F: drivers/iio/pressure/dps310.c 12258 12233 12259 12234 INFINEON PEB2466 ASoC CODEC ··· 13065 13038 F: Documentation/ABI/testing/sysfs-bus-iio-inv_icm42600 13066 13039 F: Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml 13067 13040 F: drivers/iio/imu/inv_icm42600/ 13041 + 13042 + INVENSENSE ICM-456xx IMU DRIVER 13043 + M: Remi Buisson <remi.buisson@tdk.com> 13044 + L: linux-iio@vger.kernel.org 13045 + S: Maintained 13046 + W: https://invensense.tdk.com/ 13047 + F: Documentation/devicetree/bindings/iio/imu/invensense,icm45600.yaml 13048 + F: drivers/iio/imu/inv_icm45600/ 13068 13049 13069 13050 INVENSENSE MPU-3050 GYROSCOPE DRIVER 13070 13051 M: Linus Walleij <linus.walleij@linaro.org> ··· 15209 15174 S: Orphan 15210 15175 F: drivers/video/fbdev/matrox/matroxfb_* 15211 15176 F: include/uapi/linux/matroxfb.h 15177 + 15178 + MAX14001/MAX14002 IIO ADC DRIVER 15179 + M: Kim Seer Paller <kimseer.paller@analog.com> 15180 + M: Marilene Andrade Garcia <marilene.agarcia@gmail.com> 15181 + L: linux-iio@vger.kernel.org 15182 + S: Maintained 15183 + W: https://ez.analog.com/linux-software-drivers 15184 + F: Documentation/devicetree/bindings/iio/adc/adi,max14001.yaml 15185 + F: drivers/iio/adc/max14001.c 15212 15186 15213 15187 MAX15301 DRIVER 15214 15188 M: Daniel Nilsson <daniel.nilsson@flex.com> ··· 21924 21880 F: Documentation/devicetree/bindings/timer/renesas,rz-mtu3.yaml 21925 21881 F: drivers/counter/rz-mtu3-cnt.c 21926 21882 21883 + RENESAS RZ/T2H / RZ/N2H A/D DRIVER 21884 + M: Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com> 21885 + L: linux-iio@vger.kernel.org 21886 + L: linux-renesas-soc@vger.kernel.org 21887 + S: Supported 21888 + F: Documentation/devicetree/bindings/iio/adc/renesas,r9a09g077-adc.yaml 21889 + F: drivers/iio/adc/rzt2h_adc.c 21890 + 21927 21891 RENESAS RTCA-3 RTC DRIVER 21928 21892 M: Claudiu Beznea <claudiu.beznea.uj@bp.renesas.com> 21929 21893 L: linux-rtc@vger.kernel.org ··· 21952 21900 F: include/dt-bindings/net/pcs-rzn1-miic.h 21953 21901 F: include/linux/pcs-rzn1-miic.h 21954 21902 F: net/dsa/tag_rzn1_a5psw.c 21903 + 21904 + RENESAS RZ/N1 ADC DRIVER 21905 + M: Herve Codina <herve.codina@bootlin.com> 21906 + L: linux-renesas-soc@vger.kernel.org 21907 + S: Supported 21908 + F: Documentation/devicetree/bindings/iio/adc/renesas,rzn1-adc.yaml 21909 + F: drivers/iio/adc/rzn1-adc.c 21955 21910 21956 21911 RENESAS RZ/N1 DWMAC GLUE LAYER 21957 21912 M: Romain Gantois <romain.gantois@bootlin.com>
+17 -2
drivers/iio/accel/Kconfig
··· 218 218 219 219 config BMA220 220 220 tristate "Bosch BMA220 3-Axis Accelerometer Driver" 221 - depends on SPI 221 + depends on I2C || SPI 222 + select REGMAP 222 223 select IIO_BUFFER 223 224 select IIO_TRIGGERED_BUFFER 225 + select BMA220_I2C if I2C 226 + select BMA220_SPI if SPI 224 227 help 225 228 Say yes here to add support for the Bosch BMA220 triaxial 226 229 acceleration sensor. 227 230 228 231 To compile this driver as a module, choose M here: the 229 - module will be called bma220_spi. 232 + module will be called bma220_core and you will also get 233 + bma220_i2c if I2C is enabled and bma220_spi if SPI is 234 + enabled. 235 + 236 + config BMA220_I2C 237 + tristate 238 + select REGMAP_I2C 239 + depends on BMA220 240 + 241 + config BMA220_SPI 242 + tristate 243 + select REGMAP_SPI 244 + depends on BMA220 230 245 231 246 config BMA400 232 247 tristate "Bosch BMA400 3-Axis Accelerometer Driver"
+3 -1
drivers/iio/accel/Makefile
··· 25 25 obj-$(CONFIG_ADXL380_I2C) += adxl380_i2c.o 26 26 obj-$(CONFIG_ADXL380_SPI) += adxl380_spi.o 27 27 obj-$(CONFIG_BMA180) += bma180.o 28 - obj-$(CONFIG_BMA220) += bma220_spi.o 28 + obj-$(CONFIG_BMA220) += bma220_core.o 29 + obj-$(CONFIG_BMA220_I2C) += bma220_i2c.o 30 + obj-$(CONFIG_BMA220_SPI) += bma220_spi.o 29 31 obj-$(CONFIG_BMA400) += bma400_core.o 30 32 obj-$(CONFIG_BMA400_I2C) += bma400_i2c.o 31 33 obj-$(CONFIG_BMA400_SPI) += bma400_spi.o
+95 -39
drivers/iio/accel/adxl380.c
··· 26 26 #include "adxl380.h" 27 27 28 28 #define ADXL380_ID_VAL 380 29 + #define ADXL318_ID_VAL 380 29 30 #define ADXL382_ID_VAL 382 31 + #define ADXL319_ID_VAL 382 30 32 31 33 #define ADXL380_DEVID_AD_REG 0x00 32 34 #define ADLX380_PART_ID_REG 0x02 ··· 180 178 181 179 static const int adxl380_range_scale_factor_tbl[] = { 1, 2, 4 }; 182 180 183 - const struct adxl380_chip_info adxl380_chip_info = { 184 - .name = "adxl380", 185 - .chip_id = ADXL380_ID_VAL, 186 - .scale_tbl = { 187 - [ADXL380_OP_MODE_4G_RANGE] = { 0, 1307226 }, 188 - [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 }, 189 - [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 }, 190 - }, 191 - .samp_freq_tbl = { 8000, 16000, 32000 }, 192 - /* 193 - * The datasheet defines an intercept of 470 LSB at 25 degC 194 - * and a sensitivity of 10.2 LSB/C. 195 - */ 196 - .temp_offset = 25 * 102 / 10 - 470, 197 - 198 - }; 199 - EXPORT_SYMBOL_NS_GPL(adxl380_chip_info, "IIO_ADXL380"); 200 - 201 - const struct adxl380_chip_info adxl382_chip_info = { 202 - .name = "adxl382", 203 - .chip_id = ADXL382_ID_VAL, 204 - .scale_tbl = { 205 - [ADXL382_OP_MODE_15G_RANGE] = { 0, 4903325 }, 206 - [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 }, 207 - [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 }, 208 - }, 209 - .samp_freq_tbl = { 16000, 32000, 64000 }, 210 - /* 211 - * The datasheet defines an intercept of 570 LSB at 25 degC 212 - * and a sensitivity of 10.2 LSB/C. 213 - */ 214 - .temp_offset = 25 * 102 / 10 - 570, 215 - }; 216 - EXPORT_SYMBOL_NS_GPL(adxl382_chip_info, "IIO_ADXL380"); 217 - 218 181 static const unsigned int adxl380_th_reg_high_addr[2] = { 219 182 [ADXL380_ACTIVITY] = ADXL380_THRESH_ACT_H_REG, 220 183 [ADXL380_INACTIVITY] = ADXL380_THRESH_INACT_H_REG, ··· 243 276 if (ret) 244 277 return ret; 245 278 246 - /* Activity/ Inactivity detection available only in VLP/ULP mode */ 247 - if (FIELD_GET(ADXL380_ACT_EN_MSK, act_inact_ctl) || 248 - FIELD_GET(ADXL380_INACT_EN_MSK, act_inact_ctl)) 279 + /* 280 + * Activity/Inactivity detection available only in VLP/ULP 281 + * mode and for devices that support low power modes. Otherwise 282 + * go straight to measure mode (same bits as ADXL380_OP_MODE_HP). 283 + */ 284 + if (st->chip_info->has_low_power && 285 + (FIELD_GET(ADXL380_ACT_EN_MSK, act_inact_ctl) || 286 + FIELD_GET(ADXL380_INACT_EN_MSK, act_inact_ctl))) 249 287 op_mode = ADXL380_OP_MODE_VLP; 250 288 else 251 289 op_mode = ADXL380_OP_MODE_HP; ··· 1590 1618 return 0; 1591 1619 } 1592 1620 1621 + static const struct iio_info adxl318_info = { 1622 + .read_raw = adxl380_read_raw, 1623 + .read_avail = &adxl380_read_avail, 1624 + .write_raw = adxl380_write_raw, 1625 + .write_raw_get_fmt = adxl380_write_raw_get_fmt, 1626 + .debugfs_reg_access = &adxl380_reg_access, 1627 + .hwfifo_set_watermark = adxl380_set_watermark, 1628 + }; 1629 + 1593 1630 static const struct iio_info adxl380_info = { 1594 1631 .read_raw = adxl380_read_raw, 1595 1632 .read_avail = &adxl380_read_avail, ··· 1612 1631 .debugfs_reg_access = &adxl380_reg_access, 1613 1632 .hwfifo_set_watermark = adxl380_set_watermark, 1614 1633 }; 1634 + 1635 + const struct adxl380_chip_info adxl318_chip_info = { 1636 + .name = "adxl318", 1637 + .chip_id = ADXL318_ID_VAL, 1638 + .scale_tbl = { 1639 + [ADXL380_OP_MODE_4G_RANGE] = { 0, 1307226 }, 1640 + [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 }, 1641 + [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 }, 1642 + }, 1643 + .samp_freq_tbl = { 8000, 16000, 32000 }, 1644 + /* 1645 + * The datasheet defines an intercept of 550 LSB at 25 degC 1646 + * and a sensitivity of 10.2 LSB/C. 1647 + */ 1648 + .temp_offset = 25 * 102 / 10 - 550, 1649 + .info = &adxl318_info, 1650 + }; 1651 + EXPORT_SYMBOL_NS_GPL(adxl318_chip_info, "IIO_ADXL380"); 1652 + 1653 + const struct adxl380_chip_info adxl319_chip_info = { 1654 + .name = "adxl319", 1655 + .chip_id = ADXL319_ID_VAL, 1656 + .scale_tbl = { 1657 + [ADXL382_OP_MODE_15G_RANGE] = { 0, 4903325 }, 1658 + [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 }, 1659 + [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 }, 1660 + }, 1661 + .samp_freq_tbl = { 16000, 32000, 64000 }, 1662 + /* 1663 + * The datasheet defines an intercept of 550 LSB at 25 degC 1664 + * and a sensitivity of 10.2 LSB/C. 1665 + */ 1666 + .temp_offset = 25 * 102 / 10 - 550, 1667 + .info = &adxl318_info, 1668 + }; 1669 + EXPORT_SYMBOL_NS_GPL(adxl319_chip_info, "IIO_ADXL380"); 1670 + 1671 + const struct adxl380_chip_info adxl380_chip_info = { 1672 + .name = "adxl380", 1673 + .chip_id = ADXL380_ID_VAL, 1674 + .scale_tbl = { 1675 + [ADXL380_OP_MODE_4G_RANGE] = { 0, 1307226 }, 1676 + [ADXL380_OP_MODE_8G_RANGE] = { 0, 2615434 }, 1677 + [ADXL380_OP_MODE_16G_RANGE] = { 0, 5229886 }, 1678 + }, 1679 + .samp_freq_tbl = { 8000, 16000, 32000 }, 1680 + /* 1681 + * The datasheet defines an intercept of 470 LSB at 25 degC 1682 + * and a sensitivity of 10.2 LSB/C. 1683 + */ 1684 + .temp_offset = 25 * 102 / 10 - 470, 1685 + .has_low_power = true, 1686 + .info = &adxl380_info, 1687 + 1688 + }; 1689 + EXPORT_SYMBOL_NS_GPL(adxl380_chip_info, "IIO_ADXL380"); 1690 + 1691 + const struct adxl380_chip_info adxl382_chip_info = { 1692 + .name = "adxl382", 1693 + .chip_id = ADXL382_ID_VAL, 1694 + .scale_tbl = { 1695 + [ADXL382_OP_MODE_15G_RANGE] = { 0, 4903325 }, 1696 + [ADXL382_OP_MODE_30G_RANGE] = { 0, 9806650 }, 1697 + [ADXL382_OP_MODE_60G_RANGE] = { 0, 19613300 }, 1698 + }, 1699 + .samp_freq_tbl = { 16000, 32000, 64000 }, 1700 + /* 1701 + * The datasheet defines an intercept of 570 LSB at 25 degC 1702 + * and a sensitivity of 10.2 LSB/C. 1703 + */ 1704 + .temp_offset = 25 * 102 / 10 - 570, 1705 + .has_low_power = true, 1706 + .info = &adxl380_info, 1707 + }; 1708 + EXPORT_SYMBOL_NS_GPL(adxl382_chip_info, "IIO_ADXL380"); 1615 1709 1616 1710 static const struct iio_event_spec adxl380_events[] = { 1617 1711 { ··· 1922 1866 indio_dev->channels = adxl380_channels; 1923 1867 indio_dev->num_channels = ARRAY_SIZE(adxl380_channels); 1924 1868 indio_dev->name = chip_info->name; 1925 - indio_dev->info = &adxl380_info; 1869 + indio_dev->info = chip_info->info; 1926 1870 indio_dev->modes = INDIO_DIRECT_MODE; 1927 1871 1928 1872 ret = devm_regulator_get_enable(dev, "vddio");
+4
drivers/iio/accel/adxl380.h
··· 12 12 const char *name; 13 13 const int scale_tbl[3][2]; 14 14 const int samp_freq_tbl[3]; 15 + const struct iio_info *info; 15 16 const int temp_offset; 16 17 const u16 chip_id; 18 + const bool has_low_power; 17 19 }; 18 20 21 + extern const struct adxl380_chip_info adxl318_chip_info; 22 + extern const struct adxl380_chip_info adxl319_chip_info; 19 23 extern const struct adxl380_chip_info adxl380_chip_info; 20 24 extern const struct adxl380_chip_info adxl382_chip_info; 21 25
+4
drivers/iio/accel/adxl380_i2c.c
··· 33 33 } 34 34 35 35 static const struct i2c_device_id adxl380_i2c_id[] = { 36 + { "adxl318", (kernel_ulong_t)&adxl318_chip_info }, 37 + { "adxl319", (kernel_ulong_t)&adxl319_chip_info }, 36 38 { "adxl380", (kernel_ulong_t)&adxl380_chip_info }, 37 39 { "adxl382", (kernel_ulong_t)&adxl382_chip_info }, 38 40 { } ··· 42 40 MODULE_DEVICE_TABLE(i2c, adxl380_i2c_id); 43 41 44 42 static const struct of_device_id adxl380_of_match[] = { 43 + { .compatible = "adi,adxl318", .data = &adxl318_chip_info }, 44 + { .compatible = "adi,adxl319", .data = &adxl319_chip_info }, 45 45 { .compatible = "adi,adxl380", .data = &adxl380_chip_info }, 46 46 { .compatible = "adi,adxl382", .data = &adxl382_chip_info }, 47 47 { }
+4
drivers/iio/accel/adxl380_spi.c
··· 35 35 } 36 36 37 37 static const struct spi_device_id adxl380_spi_id[] = { 38 + { "adxl318", (kernel_ulong_t)&adxl318_chip_info }, 39 + { "adxl319", (kernel_ulong_t)&adxl319_chip_info }, 38 40 { "adxl380", (kernel_ulong_t)&adxl380_chip_info }, 39 41 { "adxl382", (kernel_ulong_t)&adxl382_chip_info }, 40 42 { } ··· 44 42 MODULE_DEVICE_TABLE(spi, adxl380_spi_id); 45 43 46 44 static const struct of_device_id adxl380_of_match[] = { 45 + { .compatible = "adi,adxl318", .data = &adxl318_chip_info }, 46 + { .compatible = "adi,adxl319", .data = &adxl319_chip_info }, 47 47 { .compatible = "adi,adxl380", .data = &adxl380_chip_info }, 48 48 { .compatible = "adi,adxl382", .data = &adxl382_chip_info }, 49 49 { }
+28
drivers/iio/accel/bma220.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Forward declarations needed by the bma220 sources. 4 + * 5 + * Copyright 2025 Petre Rodan <petre.rodan@subdimension.ro> 6 + */ 7 + 8 + #ifndef _BMA220_H 9 + #define _BMA220_H 10 + 11 + #include <linux/pm.h> 12 + #include <linux/regmap.h> 13 + 14 + #define BMA220_REG_WDT 0x17 15 + #define BMA220_WDT_MASK GENMASK(2, 1) 16 + #define BMA220_WDT_OFF 0x0 17 + #define BMA220_WDT_1MS 0x2 18 + #define BMA220_WDT_10MS 0x3 19 + 20 + struct device; 21 + 22 + extern const struct regmap_config bma220_i2c_regmap_config; 23 + extern const struct regmap_config bma220_spi_regmap_config; 24 + extern const struct dev_pm_ops bma220_pm_ops; 25 + 26 + int bma220_common_probe(struct device *dev, struct regmap *regmap, int irq); 27 + 28 + #endif
+585
drivers/iio/accel/bma220_core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * BMA220 Digital triaxial acceleration sensor driver 4 + * 5 + * Copyright (c) 2016,2020 Intel Corporation. 6 + * Copyright (c) 2025 Petre Rodan <petre.rodan@subdimension.ro> 7 + */ 8 + 9 + #include <linux/bits.h> 10 + #include <linux/bitfield.h> 11 + #include <linux/cleanup.h> 12 + #include <linux/device.h> 13 + #include <linux/errno.h> 14 + #include <linux/mod_devicetable.h> 15 + #include <linux/module.h> 16 + #include <linux/mutex.h> 17 + #include <linux/pm.h> 18 + #include <linux/regmap.h> 19 + #include <linux/regulator/consumer.h> 20 + #include <linux/types.h> 21 + 22 + #include <linux/iio/buffer.h> 23 + #include <linux/iio/iio.h> 24 + #include <linux/iio/sysfs.h> 25 + #include <linux/iio/trigger.h> 26 + #include <linux/iio/trigger_consumer.h> 27 + #include <linux/iio/triggered_buffer.h> 28 + 29 + #include "bma220.h" 30 + 31 + #define BMA220_REG_ID 0x00 32 + #define BMA220_REG_REVISION_ID 0x01 33 + #define BMA220_REG_ACCEL_X 0x02 34 + #define BMA220_REG_ACCEL_Y 0x03 35 + #define BMA220_REG_ACCEL_Z 0x04 36 + #define BMA220_REG_CONF0 0x05 37 + #define BMA220_HIGH_DUR_MSK GENMASK(5, 0) 38 + #define BMA220_HIGH_HY_MSK GENMASK(7, 6) 39 + #define BMA220_REG_CONF1 0x06 40 + #define BMA220_HIGH_TH_MSK GENMASK(3, 0) 41 + #define BMA220_LOW_TH_MSK GENMASK(7, 4) 42 + #define BMA220_REG_CONF2 0x07 43 + #define BMA220_LOW_DUR_MSK GENMASK(5, 0) 44 + #define BMA220_LOW_HY_MSK GENMASK(7, 6) 45 + #define BMA220_REG_CONF3 0x08 46 + #define BMA220_TT_DUR_MSK GENMASK(2, 0) 47 + #define BMA220_TT_TH_MSK GENMASK(6, 3) 48 + #define BMA220_REG_CONF4 0x09 49 + #define BMA220_SLOPE_DUR_MSK GENMASK(1, 0) 50 + #define BMA220_SLOPE_TH_MSK GENMASK(5, 2) 51 + #define BMA220_REG_CONF5 0x0a 52 + #define BMA220_TIP_EN_MSK BIT(4) 53 + #define BMA220_REG_IF0 0x0b 54 + #define BMA220_REG_IF1 0x0c 55 + #define BMA220_IF_SLOPE BIT(0) 56 + #define BMA220_IF_DRDY BIT(1) 57 + #define BMA220_IF_HIGH BIT(2) 58 + #define BMA220_IF_LOW BIT(3) 59 + #define BMA220_IF_TT BIT(4) 60 + #define BMA220_REG_IE0 0x0d 61 + #define BMA220_INT_EN_TAP_Z_MSK BIT(0) 62 + #define BMA220_INT_EN_TAP_Y_MSK BIT(1) 63 + #define BMA220_INT_EN_TAP_X_MSK BIT(2) 64 + #define BMA220_INT_EN_SLOPE_Z_MSK BIT(3) 65 + #define BMA220_INT_EN_SLOPE_Y_MSK BIT(4) 66 + #define BMA220_INT_EN_SLOPE_X_MSK BIT(5) 67 + #define BMA220_INT_EN_DRDY_MSK BIT(7) 68 + #define BMA220_REG_IE1 0x0e 69 + #define BMA220_INT_EN_HIGH_Z_MSK BIT(0) 70 + #define BMA220_INT_EN_HIGH_Y_MSK BIT(1) 71 + #define BMA220_INT_EN_HIGH_X_MSK BIT(2) 72 + #define BMA220_INT_EN_LOW_MSK BIT(3) 73 + #define BMA220_INT_LATCH_MSK GENMASK(6, 4) 74 + #define BMA220_INT_RST_MSK BIT(7) 75 + #define BMA220_REG_IE2 0x0f 76 + #define BMA220_REG_FILTER 0x10 77 + #define BMA220_FILTER_MASK GENMASK(3, 0) 78 + #define BMA220_REG_RANGE 0x11 79 + #define BMA220_RANGE_MASK GENMASK(1, 0) 80 + #define BMA220_REG_SUSPEND 0x18 81 + #define BMA220_REG_SOFTRESET 0x19 82 + 83 + #define BMA220_CHIP_ID 0xDD 84 + #define BMA220_SUSPEND_SLEEP 0xFF 85 + #define BMA220_SUSPEND_WAKE 0x00 86 + #define BMA220_RESET_MODE 0xFF 87 + #define BMA220_NONRESET_MODE 0x00 88 + 89 + #define BMA220_DEVICE_NAME "bma220" 90 + 91 + #define BMA220_COF_1000Hz 0x0 92 + #define BMA220_COF_500Hz 0x1 93 + #define BMA220_COF_250Hz 0x2 94 + #define BMA220_COF_125Hz 0x3 95 + #define BMA220_COF_64Hz 0x4 96 + #define BMA220_COF_32Hz 0x5 97 + 98 + #define BMA220_ACCEL_CHANNEL(index, reg, axis) { \ 99 + .type = IIO_ACCEL, \ 100 + .address = reg, \ 101 + .modified = 1, \ 102 + .channel2 = IIO_MOD_##axis, \ 103 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 104 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \ 105 + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ 106 + .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE) |\ 107 + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ 108 + .scan_index = index, \ 109 + .scan_type = { \ 110 + .sign = 's', \ 111 + .realbits = 6, \ 112 + .storagebits = 8, \ 113 + .shift = 2, \ 114 + .endianness = IIO_CPU, \ 115 + }, \ 116 + } 117 + 118 + enum bma220_axis { 119 + AXIS_X, 120 + AXIS_Y, 121 + AXIS_Z, 122 + }; 123 + 124 + static const int bma220_scale_table[][2] = { 125 + { 0, 623000 }, { 1, 248000 }, { 2, 491000 }, { 4, 983000 }, 126 + }; 127 + 128 + struct bma220_data { 129 + struct regmap *regmap; 130 + struct mutex lock; 131 + u8 lpf_3dB_freq_idx; 132 + u8 range_idx; 133 + struct iio_trigger *trig; 134 + struct { 135 + s8 chans[3]; 136 + /* Ensure timestamp is naturally aligned. */ 137 + aligned_s64 timestamp; 138 + } scan __aligned(IIO_DMA_MINALIGN); 139 + }; 140 + 141 + static const struct iio_chan_spec bma220_channels[] = { 142 + BMA220_ACCEL_CHANNEL(0, BMA220_REG_ACCEL_X, X), 143 + BMA220_ACCEL_CHANNEL(1, BMA220_REG_ACCEL_Y, Y), 144 + BMA220_ACCEL_CHANNEL(2, BMA220_REG_ACCEL_Z, Z), 145 + IIO_CHAN_SOFT_TIMESTAMP(3), 146 + }; 147 + 148 + /* Available cut-off frequencies of the low pass filter in Hz. */ 149 + static const int bma220_lpf_3dB_freq_Hz_table[] = { 150 + [BMA220_COF_1000Hz] = 1000, 151 + [BMA220_COF_500Hz] = 500, 152 + [BMA220_COF_250Hz] = 250, 153 + [BMA220_COF_125Hz] = 125, 154 + [BMA220_COF_64Hz] = 64, 155 + [BMA220_COF_32Hz] = 32, 156 + }; 157 + 158 + static const unsigned long bma220_accel_scan_masks[] = { 159 + BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z), 160 + 0 161 + }; 162 + 163 + static bool bma220_is_writable_reg(struct device *dev, unsigned int reg) 164 + { 165 + switch (reg) { 166 + case BMA220_REG_CONF0: 167 + case BMA220_REG_CONF1: 168 + case BMA220_REG_CONF2: 169 + case BMA220_REG_CONF3: 170 + case BMA220_REG_CONF4: 171 + case BMA220_REG_CONF5: 172 + case BMA220_REG_IE0: 173 + case BMA220_REG_IE1: 174 + case BMA220_REG_IE2: 175 + case BMA220_REG_FILTER: 176 + case BMA220_REG_RANGE: 177 + case BMA220_REG_WDT: 178 + return true; 179 + default: 180 + return false; 181 + } 182 + } 183 + 184 + const struct regmap_config bma220_spi_regmap_config = { 185 + .reg_bits = 8, 186 + .val_bits = 8, 187 + .read_flag_mask = BIT(7), 188 + .max_register = BMA220_REG_SOFTRESET, 189 + .cache_type = REGCACHE_NONE, 190 + .writeable_reg = bma220_is_writable_reg, 191 + }; 192 + EXPORT_SYMBOL_NS_GPL(bma220_spi_regmap_config, "IIO_BOSCH_BMA220"); 193 + 194 + /* 195 + * Based on the datasheet the memory map differs between the SPI and the I2C 196 + * implementations. I2C register addresses are simply shifted to the left 197 + * by 1 bit yet the register size remains unchanged. 198 + * This driver employs the SPI memory map to correlate register names to 199 + * addresses regardless of the bus type. 200 + */ 201 + 202 + const struct regmap_config bma220_i2c_regmap_config = { 203 + .reg_bits = 8, 204 + .val_bits = 8, 205 + .reg_shift = -1, 206 + .max_register = BMA220_REG_SOFTRESET, 207 + .cache_type = REGCACHE_NONE, 208 + .writeable_reg = bma220_is_writable_reg, 209 + }; 210 + EXPORT_SYMBOL_NS_GPL(bma220_i2c_regmap_config, "IIO_BOSCH_BMA220"); 211 + 212 + static int bma220_data_rdy_trigger_set_state(struct iio_trigger *trig, 213 + bool state) 214 + { 215 + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 216 + struct bma220_data *data = iio_priv(indio_dev); 217 + 218 + return regmap_update_bits(data->regmap, BMA220_REG_IE0, 219 + BMA220_INT_EN_DRDY_MSK, 220 + FIELD_PREP(BMA220_INT_EN_DRDY_MSK, state)); 221 + } 222 + 223 + static const struct iio_trigger_ops bma220_trigger_ops = { 224 + .set_trigger_state = &bma220_data_rdy_trigger_set_state, 225 + .validate_device = &iio_trigger_validate_own_device, 226 + }; 227 + 228 + static irqreturn_t bma220_trigger_handler(int irq, void *p) 229 + { 230 + int ret; 231 + struct iio_poll_func *pf = p; 232 + struct iio_dev *indio_dev = pf->indio_dev; 233 + struct bma220_data *data = iio_priv(indio_dev); 234 + 235 + ret = regmap_bulk_read(data->regmap, BMA220_REG_ACCEL_X, 236 + &data->scan.chans, 237 + sizeof(data->scan.chans)); 238 + if (ret < 0) 239 + return IRQ_NONE; 240 + 241 + iio_push_to_buffers_with_ts(indio_dev, &data->scan, sizeof(data->scan), 242 + iio_get_time_ns(indio_dev)); 243 + iio_trigger_notify_done(indio_dev->trig); 244 + 245 + return IRQ_HANDLED; 246 + } 247 + 248 + static int bma220_read_raw(struct iio_dev *indio_dev, 249 + struct iio_chan_spec const *chan, 250 + int *val, int *val2, long mask) 251 + { 252 + int ret; 253 + u8 index; 254 + unsigned int reg; 255 + struct bma220_data *data = iio_priv(indio_dev); 256 + 257 + guard(mutex)(&data->lock); 258 + 259 + switch (mask) { 260 + case IIO_CHAN_INFO_RAW: 261 + ret = regmap_read(data->regmap, chan->address, &reg); 262 + if (ret < 0) 263 + return -EINVAL; 264 + *val = sign_extend32(reg >> chan->scan_type.shift, 265 + chan->scan_type.realbits - 1); 266 + return IIO_VAL_INT; 267 + case IIO_CHAN_INFO_SCALE: 268 + index = data->range_idx; 269 + *val = bma220_scale_table[index][0]; 270 + *val2 = bma220_scale_table[index][1]; 271 + return IIO_VAL_INT_PLUS_MICRO; 272 + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 273 + index = data->lpf_3dB_freq_idx; 274 + *val = bma220_lpf_3dB_freq_Hz_table[index]; 275 + return IIO_VAL_INT; 276 + } 277 + 278 + return -EINVAL; 279 + } 280 + 281 + static int bma220_find_match_2dt(const int (*tbl)[2], const int n, 282 + const int val, const int val2) 283 + { 284 + int i; 285 + 286 + for (i = 0; i < n; i++) { 287 + if (tbl[i][0] == val && tbl[i][1] == val2) 288 + return i; 289 + } 290 + 291 + return -EINVAL; 292 + } 293 + 294 + static int bma220_find_match(const int *arr, const int n, const int val) 295 + { 296 + int i; 297 + 298 + for (i = 0; i < n; i++) { 299 + if (arr[i] == val) 300 + return i; 301 + } 302 + 303 + return -EINVAL; 304 + } 305 + 306 + static int bma220_write_raw(struct iio_dev *indio_dev, 307 + struct iio_chan_spec const *chan, 308 + int val, int val2, long mask) 309 + { 310 + int ret; 311 + int index = -1; 312 + struct bma220_data *data = iio_priv(indio_dev); 313 + 314 + guard(mutex)(&data->lock); 315 + 316 + switch (mask) { 317 + case IIO_CHAN_INFO_SCALE: 318 + index = bma220_find_match_2dt(bma220_scale_table, 319 + ARRAY_SIZE(bma220_scale_table), 320 + val, val2); 321 + if (index < 0) 322 + return -EINVAL; 323 + 324 + ret = regmap_update_bits(data->regmap, BMA220_REG_RANGE, 325 + BMA220_RANGE_MASK, 326 + FIELD_PREP(BMA220_RANGE_MASK, index)); 327 + if (ret < 0) 328 + return ret; 329 + data->range_idx = index; 330 + 331 + return 0; 332 + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 333 + index = bma220_find_match(bma220_lpf_3dB_freq_Hz_table, 334 + ARRAY_SIZE(bma220_lpf_3dB_freq_Hz_table), 335 + val); 336 + if (index < 0) 337 + return -EINVAL; 338 + 339 + ret = regmap_update_bits(data->regmap, BMA220_REG_FILTER, 340 + BMA220_FILTER_MASK, 341 + FIELD_PREP(BMA220_FILTER_MASK, index)); 342 + if (ret < 0) 343 + return ret; 344 + data->lpf_3dB_freq_idx = index; 345 + 346 + return 0; 347 + } 348 + 349 + return -EINVAL; 350 + } 351 + 352 + static int bma220_read_avail(struct iio_dev *indio_dev, 353 + struct iio_chan_spec const *chan, 354 + const int **vals, int *type, int *length, 355 + long mask) 356 + { 357 + switch (mask) { 358 + case IIO_CHAN_INFO_SCALE: 359 + *vals = (int *)bma220_scale_table; 360 + *type = IIO_VAL_INT_PLUS_MICRO; 361 + *length = ARRAY_SIZE(bma220_scale_table) * 2; 362 + return IIO_AVAIL_LIST; 363 + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 364 + *vals = (const int *)bma220_lpf_3dB_freq_Hz_table; 365 + *type = IIO_VAL_INT; 366 + *length = ARRAY_SIZE(bma220_lpf_3dB_freq_Hz_table); 367 + return IIO_AVAIL_LIST; 368 + default: 369 + return -EINVAL; 370 + } 371 + } 372 + 373 + static int bma220_reg_access(struct iio_dev *indio_dev, unsigned int reg, 374 + unsigned int writeval, unsigned int *readval) 375 + { 376 + struct bma220_data *data = iio_priv(indio_dev); 377 + 378 + if (readval) 379 + return regmap_read(data->regmap, reg, readval); 380 + return regmap_write(data->regmap, reg, writeval); 381 + } 382 + 383 + static const struct iio_info bma220_info = { 384 + .read_raw = bma220_read_raw, 385 + .write_raw = bma220_write_raw, 386 + .read_avail = bma220_read_avail, 387 + .debugfs_reg_access = &bma220_reg_access, 388 + }; 389 + 390 + static int bma220_reset(struct bma220_data *data, bool up) 391 + { 392 + int ret; 393 + unsigned int i, val; 394 + 395 + /* 396 + * The chip can be reset by a simple register read. 397 + * We need up to 2 register reads of the softreset register 398 + * to make sure that the device is in the desired state. 399 + */ 400 + for (i = 0; i < 2; i++) { 401 + ret = regmap_read(data->regmap, BMA220_REG_SOFTRESET, &val); 402 + if (ret < 0) 403 + return ret; 404 + 405 + if (up && val == BMA220_RESET_MODE) 406 + return 0; 407 + 408 + if (!up && val == BMA220_NONRESET_MODE) 409 + return 0; 410 + } 411 + 412 + return -EBUSY; 413 + } 414 + 415 + static int bma220_power(struct bma220_data *data, bool up) 416 + { 417 + int ret; 418 + unsigned int i, val; 419 + 420 + /* 421 + * The chip can be suspended/woken up by a simple register read. 422 + * So, we need up to 2 register reads of the suspend register 423 + * to make sure that the device is in the desired state. 424 + */ 425 + for (i = 0; i < 2; i++) { 426 + ret = regmap_read(data->regmap, BMA220_REG_SUSPEND, &val); 427 + if (ret < 0) 428 + return ret; 429 + 430 + if (up && val == BMA220_SUSPEND_SLEEP) 431 + return 0; 432 + 433 + if (!up && val == BMA220_SUSPEND_WAKE) 434 + return 0; 435 + } 436 + 437 + return -EBUSY; 438 + } 439 + 440 + static int bma220_init(struct device *dev, struct bma220_data *data) 441 + { 442 + int ret; 443 + unsigned int val; 444 + static const char * const regulator_names[] = { "vddd", "vddio", "vdda" }; 445 + 446 + ret = devm_regulator_bulk_get_enable(dev, 447 + ARRAY_SIZE(regulator_names), 448 + regulator_names); 449 + if (ret) 450 + return dev_err_probe(dev, ret, "Failed to get regulators\n"); 451 + 452 + ret = regmap_read(data->regmap, BMA220_REG_ID, &val); 453 + if (ret) 454 + return dev_err_probe(dev, ret, 455 + "Failed to read chip id register\n"); 456 + 457 + if (val != BMA220_CHIP_ID) 458 + dev_info(dev, "Unknown chip found: 0x%02x\n", val); 459 + 460 + ret = bma220_power(data, true); 461 + if (ret) 462 + return dev_err_probe(dev, ret, "Failed to power-on chip\n"); 463 + 464 + ret = bma220_reset(data, true); 465 + if (ret) 466 + return dev_err_probe(dev, ret, "Failed to soft reset chip\n"); 467 + 468 + return 0; 469 + } 470 + 471 + static void bma220_deinit(void *data_ptr) 472 + { 473 + struct bma220_data *data = data_ptr; 474 + int ret; 475 + struct device *dev = regmap_get_device(data->regmap); 476 + 477 + ret = bma220_power(data, false); 478 + if (ret) 479 + dev_warn(dev, 480 + "Failed to put device into suspend mode (%pe)\n", 481 + ERR_PTR(ret)); 482 + } 483 + 484 + static irqreturn_t bma220_irq_handler(int irq, void *private) 485 + { 486 + struct iio_dev *indio_dev = private; 487 + struct bma220_data *data = iio_priv(indio_dev); 488 + int ret; 489 + unsigned int bma220_reg_if1; 490 + 491 + ret = regmap_read(data->regmap, BMA220_REG_IF1, &bma220_reg_if1); 492 + if (ret) 493 + return IRQ_NONE; 494 + 495 + if (FIELD_GET(BMA220_IF_DRDY, bma220_reg_if1)) 496 + iio_trigger_poll_nested(data->trig); 497 + 498 + return IRQ_HANDLED; 499 + } 500 + 501 + int bma220_common_probe(struct device *dev, struct regmap *regmap, int irq) 502 + { 503 + int ret; 504 + struct iio_dev *indio_dev; 505 + struct bma220_data *data; 506 + 507 + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 508 + if (!indio_dev) 509 + return -ENOMEM; 510 + 511 + data = iio_priv(indio_dev); 512 + data->regmap = regmap; 513 + 514 + ret = bma220_init(dev, data); 515 + if (ret) 516 + return ret; 517 + 518 + ret = devm_mutex_init(dev, &data->lock); 519 + if (ret) 520 + return ret; 521 + 522 + indio_dev->info = &bma220_info; 523 + indio_dev->name = BMA220_DEVICE_NAME; 524 + indio_dev->modes = INDIO_DIRECT_MODE; 525 + indio_dev->channels = bma220_channels; 526 + indio_dev->num_channels = ARRAY_SIZE(bma220_channels); 527 + indio_dev->available_scan_masks = bma220_accel_scan_masks; 528 + 529 + if (irq > 0) { 530 + data->trig = devm_iio_trigger_alloc(dev, "%s-dev%d", 531 + indio_dev->name, 532 + iio_device_id(indio_dev)); 533 + if (!data->trig) 534 + return -ENOMEM; 535 + 536 + data->trig->ops = &bma220_trigger_ops; 537 + iio_trigger_set_drvdata(data->trig, indio_dev); 538 + 539 + ret = devm_iio_trigger_register(dev, data->trig); 540 + if (ret) 541 + return dev_err_probe(dev, ret, 542 + "iio trigger register fail\n"); 543 + indio_dev->trig = iio_trigger_get(data->trig); 544 + ret = devm_request_threaded_irq(dev, irq, NULL, 545 + &bma220_irq_handler, IRQF_ONESHOT, 546 + indio_dev->name, indio_dev); 547 + if (ret) 548 + return dev_err_probe(dev, ret, 549 + "request irq %d failed\n", irq); 550 + } 551 + 552 + ret = devm_add_action_or_reset(dev, bma220_deinit, data); 553 + if (ret) 554 + return ret; 555 + 556 + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, 557 + bma220_trigger_handler, NULL); 558 + if (ret < 0) 559 + dev_err_probe(dev, ret, "iio triggered buffer setup failed\n"); 560 + 561 + return devm_iio_device_register(dev, indio_dev); 562 + } 563 + EXPORT_SYMBOL_NS_GPL(bma220_common_probe, "IIO_BOSCH_BMA220"); 564 + 565 + static int bma220_suspend(struct device *dev) 566 + { 567 + struct iio_dev *indio_dev = dev_get_drvdata(dev); 568 + struct bma220_data *data = iio_priv(indio_dev); 569 + 570 + return bma220_power(data, false); 571 + } 572 + 573 + static int bma220_resume(struct device *dev) 574 + { 575 + struct iio_dev *indio_dev = dev_get_drvdata(dev); 576 + struct bma220_data *data = iio_priv(indio_dev); 577 + 578 + return bma220_power(data, true); 579 + } 580 + EXPORT_NS_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume, 581 + IIO_BOSCH_BMA220); 582 + 583 + MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>"); 584 + MODULE_DESCRIPTION("BMA220 acceleration sensor driver"); 585 + MODULE_LICENSE("GPL");
+69
drivers/iio/accel/bma220_i2c.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Bosch triaxial acceleration sensor 4 + * 5 + * Copyright (c) 2025 Petre Rodan <petre.rodan@subdimension.ro> 6 + * 7 + * Datasheet: https://media.digikey.com/pdf/Data%20Sheets/Bosch/BMA220.pdf 8 + * I2C address is either 0x0b or 0x0a depending on CSB (pin 10) 9 + */ 10 + 11 + #include <linux/bitfield.h> 12 + #include <linux/i2c.h> 13 + #include <linux/mod_devicetable.h> 14 + #include <linux/module.h> 15 + #include <linux/regmap.h> 16 + #include <linux/types.h> 17 + 18 + #include "bma220.h" 19 + 20 + static int bma220_set_wdt(struct regmap *regmap, const u8 val) 21 + { 22 + return regmap_update_bits(regmap, BMA220_REG_WDT, BMA220_WDT_MASK, 23 + FIELD_PREP(BMA220_WDT_MASK, val)); 24 + } 25 + 26 + static int bma220_i2c_probe(struct i2c_client *client) 27 + { 28 + struct regmap *regmap; 29 + int ret; 30 + 31 + regmap = devm_regmap_init_i2c(client, &bma220_i2c_regmap_config); 32 + if (IS_ERR(regmap)) 33 + return dev_err_probe(&client->dev, PTR_ERR(regmap), 34 + "failed to create regmap\n"); 35 + 36 + ret = bma220_common_probe(&client->dev, regmap, client->irq); 37 + if (ret) 38 + return ret; 39 + 40 + return bma220_set_wdt(regmap, BMA220_WDT_1MS); 41 + } 42 + 43 + static const struct of_device_id bma220_i2c_match[] = { 44 + { .compatible = "bosch,bma220" }, 45 + { } 46 + }; 47 + MODULE_DEVICE_TABLE(of, bma220_i2c_match); 48 + 49 + static const struct i2c_device_id bma220_i2c_id[] = { 50 + { "bma220" }, 51 + { } 52 + }; 53 + MODULE_DEVICE_TABLE(i2c, bma220_i2c_id); 54 + 55 + static struct i2c_driver bma220_i2c_driver = { 56 + .driver = { 57 + .name = "bma220_i2c", 58 + .pm = pm_sleep_ptr(&bma220_pm_ops), 59 + .of_match_table = bma220_i2c_match, 60 + }, 61 + .probe = bma220_i2c_probe, 62 + .id_table = bma220_i2c_id, 63 + }; 64 + module_i2c_driver(bma220_i2c_driver); 65 + 66 + MODULE_AUTHOR("Petre Rodan <petre.rodan@subdimension.ro>"); 67 + MODULE_DESCRIPTION("Bosch triaxial acceleration sensor i2c driver"); 68 + MODULE_LICENSE("GPL"); 69 + MODULE_IMPORT_NS("IIO_BOSCH_BMA220");
+26 -296
drivers/iio/accel/bma220_spi.c
··· 5 5 * Copyright (c) 2016,2020 Intel Corporation. 6 6 */ 7 7 8 - #include <linux/bits.h> 9 - #include <linux/kernel.h> 10 8 #include <linux/mod_devicetable.h> 11 9 #include <linux/module.h> 10 + #include <linux/regmap.h> 12 11 #include <linux/types.h> 13 12 #include <linux/spi/spi.h> 14 13 15 - #include <linux/iio/buffer.h> 16 - #include <linux/iio/iio.h> 17 - #include <linux/iio/sysfs.h> 18 - #include <linux/iio/trigger_consumer.h> 19 - #include <linux/iio/triggered_buffer.h> 14 + #include "bma220.h" 20 15 21 - #define BMA220_REG_ID 0x00 22 - #define BMA220_REG_ACCEL_X 0x02 23 - #define BMA220_REG_ACCEL_Y 0x03 24 - #define BMA220_REG_ACCEL_Z 0x04 25 - #define BMA220_REG_RANGE 0x11 26 - #define BMA220_REG_SUSPEND 0x18 27 - 28 - #define BMA220_CHIP_ID 0xDD 29 - #define BMA220_READ_MASK BIT(7) 30 - #define BMA220_RANGE_MASK GENMASK(1, 0) 31 - #define BMA220_SUSPEND_SLEEP 0xFF 32 - #define BMA220_SUSPEND_WAKE 0x00 33 - 34 - #define BMA220_DEVICE_NAME "bma220" 35 - 36 - #define BMA220_ACCEL_CHANNEL(index, reg, axis) { \ 37 - .type = IIO_ACCEL, \ 38 - .address = reg, \ 39 - .modified = 1, \ 40 - .channel2 = IIO_MOD_##axis, \ 41 - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 42 - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 43 - .scan_index = index, \ 44 - .scan_type = { \ 45 - .sign = 's', \ 46 - .realbits = 6, \ 47 - .storagebits = 8, \ 48 - .shift = 2, \ 49 - .endianness = IIO_CPU, \ 50 - }, \ 51 - } 52 - 53 - enum bma220_axis { 54 - AXIS_X, 55 - AXIS_Y, 56 - AXIS_Z, 57 - }; 58 - 59 - static const int bma220_scale_table[][2] = { 60 - {0, 623000}, {1, 248000}, {2, 491000}, {4, 983000}, 61 - }; 62 - 63 - struct bma220_data { 64 - struct spi_device *spi_device; 65 - struct mutex lock; 66 - struct { 67 - s8 chans[3]; 68 - /* Ensure timestamp is naturally aligned. */ 69 - aligned_s64 timestamp; 70 - } scan; 71 - u8 tx_buf[2] __aligned(IIO_DMA_MINALIGN); 72 - }; 73 - 74 - static const struct iio_chan_spec bma220_channels[] = { 75 - BMA220_ACCEL_CHANNEL(0, BMA220_REG_ACCEL_X, X), 76 - BMA220_ACCEL_CHANNEL(1, BMA220_REG_ACCEL_Y, Y), 77 - BMA220_ACCEL_CHANNEL(2, BMA220_REG_ACCEL_Z, Z), 78 - IIO_CHAN_SOFT_TIMESTAMP(3), 79 - }; 80 - 81 - static inline int bma220_read_reg(struct spi_device *spi, u8 reg) 16 + static int bma220_spi_probe(struct spi_device *spi) 82 17 { 83 - return spi_w8r8(spi, reg | BMA220_READ_MASK); 18 + struct regmap *regmap; 19 + 20 + regmap = devm_regmap_init_spi(spi, &bma220_spi_regmap_config); 21 + if (IS_ERR(regmap)) 22 + return dev_err_probe(&spi->dev, PTR_ERR(regmap), 23 + "failed to create regmap\n"); 24 + 25 + return bma220_common_probe(&spi->dev, regmap, spi->irq); 84 26 } 85 - 86 - static const unsigned long bma220_accel_scan_masks[] = { 87 - BIT(AXIS_X) | BIT(AXIS_Y) | BIT(AXIS_Z), 88 - 0 89 - }; 90 - 91 - static irqreturn_t bma220_trigger_handler(int irq, void *p) 92 - { 93 - int ret; 94 - struct iio_poll_func *pf = p; 95 - struct iio_dev *indio_dev = pf->indio_dev; 96 - struct bma220_data *data = iio_priv(indio_dev); 97 - struct spi_device *spi = data->spi_device; 98 - 99 - mutex_lock(&data->lock); 100 - data->tx_buf[0] = BMA220_REG_ACCEL_X | BMA220_READ_MASK; 101 - ret = spi_write_then_read(spi, data->tx_buf, 1, &data->scan.chans, 102 - ARRAY_SIZE(bma220_channels) - 1); 103 - if (ret < 0) 104 - goto err; 105 - 106 - iio_push_to_buffers_with_ts(indio_dev, &data->scan, sizeof(data->scan), 107 - pf->timestamp); 108 - err: 109 - mutex_unlock(&data->lock); 110 - iio_trigger_notify_done(indio_dev->trig); 111 - 112 - return IRQ_HANDLED; 113 - } 114 - 115 - static int bma220_read_raw(struct iio_dev *indio_dev, 116 - struct iio_chan_spec const *chan, 117 - int *val, int *val2, long mask) 118 - { 119 - int ret; 120 - u8 range_idx; 121 - struct bma220_data *data = iio_priv(indio_dev); 122 - 123 - switch (mask) { 124 - case IIO_CHAN_INFO_RAW: 125 - ret = bma220_read_reg(data->spi_device, chan->address); 126 - if (ret < 0) 127 - return -EINVAL; 128 - *val = sign_extend32(ret >> chan->scan_type.shift, 129 - chan->scan_type.realbits - 1); 130 - return IIO_VAL_INT; 131 - case IIO_CHAN_INFO_SCALE: 132 - ret = bma220_read_reg(data->spi_device, BMA220_REG_RANGE); 133 - if (ret < 0) 134 - return ret; 135 - range_idx = ret & BMA220_RANGE_MASK; 136 - *val = bma220_scale_table[range_idx][0]; 137 - *val2 = bma220_scale_table[range_idx][1]; 138 - return IIO_VAL_INT_PLUS_MICRO; 139 - } 140 - 141 - return -EINVAL; 142 - } 143 - 144 - static int bma220_write_raw(struct iio_dev *indio_dev, 145 - struct iio_chan_spec const *chan, 146 - int val, int val2, long mask) 147 - { 148 - int i; 149 - int ret; 150 - int index = -1; 151 - struct bma220_data *data = iio_priv(indio_dev); 152 - 153 - switch (mask) { 154 - case IIO_CHAN_INFO_SCALE: 155 - for (i = 0; i < ARRAY_SIZE(bma220_scale_table); i++) 156 - if (val == bma220_scale_table[i][0] && 157 - val2 == bma220_scale_table[i][1]) { 158 - index = i; 159 - break; 160 - } 161 - if (index < 0) 162 - return -EINVAL; 163 - 164 - mutex_lock(&data->lock); 165 - data->tx_buf[0] = BMA220_REG_RANGE; 166 - data->tx_buf[1] = index; 167 - ret = spi_write(data->spi_device, data->tx_buf, 168 - sizeof(data->tx_buf)); 169 - if (ret < 0) 170 - dev_err(&data->spi_device->dev, 171 - "failed to set measurement range\n"); 172 - mutex_unlock(&data->lock); 173 - 174 - return 0; 175 - } 176 - 177 - return -EINVAL; 178 - } 179 - 180 - static int bma220_read_avail(struct iio_dev *indio_dev, 181 - struct iio_chan_spec const *chan, 182 - const int **vals, int *type, int *length, 183 - long mask) 184 - { 185 - switch (mask) { 186 - case IIO_CHAN_INFO_SCALE: 187 - *vals = (int *)bma220_scale_table; 188 - *type = IIO_VAL_INT_PLUS_MICRO; 189 - *length = ARRAY_SIZE(bma220_scale_table) * 2; 190 - return IIO_AVAIL_LIST; 191 - default: 192 - return -EINVAL; 193 - } 194 - } 195 - 196 - static const struct iio_info bma220_info = { 197 - .read_raw = bma220_read_raw, 198 - .write_raw = bma220_write_raw, 199 - .read_avail = bma220_read_avail, 200 - }; 201 - 202 - static int bma220_init(struct spi_device *spi) 203 - { 204 - int ret; 205 - 206 - ret = bma220_read_reg(spi, BMA220_REG_ID); 207 - if (ret != BMA220_CHIP_ID) 208 - return -ENODEV; 209 - 210 - /* Make sure the chip is powered on */ 211 - ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); 212 - if (ret == BMA220_SUSPEND_WAKE) 213 - ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); 214 - if (ret < 0) 215 - return ret; 216 - if (ret == BMA220_SUSPEND_WAKE) 217 - return -EBUSY; 218 - 219 - return 0; 220 - } 221 - 222 - static int bma220_power(struct spi_device *spi, bool up) 223 - { 224 - int i, ret; 225 - 226 - /** 227 - * The chip can be suspended/woken up by a simple register read. 228 - * So, we need up to 2 register reads of the suspend register 229 - * to make sure that the device is in the desired state. 230 - */ 231 - for (i = 0; i < 2; i++) { 232 - ret = bma220_read_reg(spi, BMA220_REG_SUSPEND); 233 - if (ret < 0) 234 - return ret; 235 - 236 - if (up && ret == BMA220_SUSPEND_SLEEP) 237 - return 0; 238 - 239 - if (!up && ret == BMA220_SUSPEND_WAKE) 240 - return 0; 241 - } 242 - 243 - return -EBUSY; 244 - } 245 - 246 - static void bma220_deinit(void *spi) 247 - { 248 - bma220_power(spi, false); 249 - } 250 - 251 - static int bma220_probe(struct spi_device *spi) 252 - { 253 - int ret; 254 - struct iio_dev *indio_dev; 255 - struct bma220_data *data; 256 - 257 - indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data)); 258 - if (!indio_dev) 259 - return -ENOMEM; 260 - 261 - data = iio_priv(indio_dev); 262 - data->spi_device = spi; 263 - mutex_init(&data->lock); 264 - 265 - indio_dev->info = &bma220_info; 266 - indio_dev->name = BMA220_DEVICE_NAME; 267 - indio_dev->modes = INDIO_DIRECT_MODE; 268 - indio_dev->channels = bma220_channels; 269 - indio_dev->num_channels = ARRAY_SIZE(bma220_channels); 270 - indio_dev->available_scan_masks = bma220_accel_scan_masks; 271 - 272 - ret = bma220_init(data->spi_device); 273 - if (ret) 274 - return ret; 275 - 276 - ret = devm_add_action_or_reset(&spi->dev, bma220_deinit, spi); 277 - if (ret) 278 - return ret; 279 - 280 - ret = devm_iio_triggered_buffer_setup(&spi->dev, indio_dev, 281 - iio_pollfunc_store_time, 282 - bma220_trigger_handler, NULL); 283 - if (ret < 0) { 284 - dev_err(&spi->dev, "iio triggered buffer setup failed\n"); 285 - return ret; 286 - } 287 - 288 - return devm_iio_device_register(&spi->dev, indio_dev); 289 - } 290 - 291 - static int bma220_suspend(struct device *dev) 292 - { 293 - struct spi_device *spi = to_spi_device(dev); 294 - 295 - return bma220_power(spi, false); 296 - } 297 - 298 - static int bma220_resume(struct device *dev) 299 - { 300 - struct spi_device *spi = to_spi_device(dev); 301 - 302 - return bma220_power(spi, true); 303 - } 304 - static DEFINE_SIMPLE_DEV_PM_OPS(bma220_pm_ops, bma220_suspend, bma220_resume); 305 27 306 28 static const struct spi_device_id bma220_spi_id[] = { 307 - {"bma220", 0}, 29 + { "bma220", 0 }, 308 30 { } 309 31 }; 310 32 311 33 static const struct acpi_device_id bma220_acpi_id[] = { 312 - {"BMA0220", 0}, 34 + { "BMA0220", 0 }, 313 35 { } 314 36 }; 315 37 MODULE_DEVICE_TABLE(spi, bma220_spi_id); 316 38 317 - static struct spi_driver bma220_driver = { 39 + static const struct of_device_id bma220_of_spi_match[] = { 40 + { .compatible = "bosch,bma220" }, 41 + { } 42 + }; 43 + MODULE_DEVICE_TABLE(of, bma220_of_spi_match); 44 + 45 + static struct spi_driver bma220_spi_driver = { 318 46 .driver = { 319 47 .name = "bma220_spi", 320 48 .pm = pm_sleep_ptr(&bma220_pm_ops), 49 + .of_match_table = bma220_of_spi_match, 321 50 .acpi_match_table = bma220_acpi_id, 322 51 }, 323 - .probe = bma220_probe, 52 + .probe = bma220_spi_probe, 324 53 .id_table = bma220_spi_id, 325 54 }; 326 - module_spi_driver(bma220_driver); 55 + module_spi_driver(bma220_spi_driver); 327 56 328 57 MODULE_AUTHOR("Tiberiu Breana <tiberiu.a.breana@intel.com>"); 329 - MODULE_DESCRIPTION("BMA220 acceleration sensor driver"); 330 - MODULE_LICENSE("GPL v2"); 58 + MODULE_DESCRIPTION("BMA220 triaxial acceleration sensor spi driver"); 59 + MODULE_LICENSE("GPL"); 60 + MODULE_IMPORT_NS("IIO_BOSCH_BMA220");
+99 -56
drivers/iio/accel/bma400.h
··· 16 16 * Read-Only Registers 17 17 */ 18 18 19 + /* Chip ID of BMA 400 devices found in the chip ID register. */ 20 + #define BMA400_ID_REG_VAL 0x90 21 + 19 22 /* Status and ID registers */ 20 23 #define BMA400_CHIP_ID_REG 0x00 21 24 #define BMA400_ERR_REG 0x02 22 25 #define BMA400_STATUS_REG 0x03 23 26 24 27 /* Acceleration registers */ 25 - #define BMA400_X_AXIS_LSB_REG 0x04 26 - #define BMA400_X_AXIS_MSB_REG 0x05 27 - #define BMA400_Y_AXIS_LSB_REG 0x06 28 - #define BMA400_Y_AXIS_MSB_REG 0x07 29 - #define BMA400_Z_AXIS_LSB_REG 0x08 30 - #define BMA400_Z_AXIS_MSB_REG 0x09 28 + #define BMA400_ACC_X_LSB_REG 0x04 29 + #define BMA400_ACC_X_MSB_REG 0x05 30 + #define BMA400_ACC_Y_LSB_REG 0x06 31 + #define BMA400_ACC_Y_MSB_REG 0x07 32 + #define BMA400_ACC_Z_LSB_REG 0x08 33 + #define BMA400_ACC_Z_MSB_REG 0x09 31 34 32 35 /* Sensor time registers */ 33 - #define BMA400_SENSOR_TIME0 0x0a 34 - #define BMA400_SENSOR_TIME1 0x0b 35 - #define BMA400_SENSOR_TIME2 0x0c 36 + #define BMA400_SENSOR_TIME0_REG 0x0a 37 + #define BMA400_SENSOR_TIME1_REG 0x0b 38 + #define BMA400_SENSOR_TIME2_REG 0x0c 36 39 37 40 /* Event and interrupt registers */ 38 41 #define BMA400_EVENT_REG 0x0d 42 + 39 43 #define BMA400_INT_STAT0_REG 0x0e 44 + #define BMA400_INT_STAT0_GEN1_MASK BIT(2) 45 + #define BMA400_INT_STAT0_GEN2_MASK BIT(3) 46 + #define BMA400_INT_STAT0_DRDY_MASK BIT(7) 47 + 40 48 #define BMA400_INT_STAT1_REG 0x0f 49 + #define BMA400_INT_STAT1_STEP_INT_MASK GENMASK(9, 8) 50 + #define BMA400_INT_STAT1_S_TAP_MASK BIT(10) 51 + #define BMA400_INT_STAT1_D_TAP_MASK BIT(11) 52 + 41 53 #define BMA400_INT_STAT2_REG 0x10 42 - #define BMA400_INT12_MAP_REG 0x23 43 - #define BMA400_INT_ENG_OVRUN_MSK BIT(4) 54 + 55 + /* Bit present in all INT_STAT registers */ 56 + #define BMA400_INT_STAT_ENG_OVRRUN_MASK BIT(4) 44 57 45 58 /* Temperature register */ 46 59 #define BMA400_TEMP_DATA_REG 0x11 ··· 68 55 #define BMA400_STEP_CNT1_REG 0x16 69 56 #define BMA400_STEP_CNT3_REG 0x17 70 57 #define BMA400_STEP_STAT_REG 0x18 71 - #define BMA400_STEP_INT_MSK BIT(0) 72 58 #define BMA400_STEP_RAW_LEN 0x03 73 - #define BMA400_STEP_STAT_MASK GENMASK(9, 8) 74 59 75 60 /* 76 61 * Read-write configuration registers 77 62 */ 78 - #define BMA400_ACC_CONFIG0_REG 0x19 79 - #define BMA400_ACC_CONFIG1_REG 0x1a 63 + #define BMA400_ACC_CONFIG0_REG 0x19 64 + #define BMA400_ACC_CONFIG0_LP_OSR_MASK GENMASK(6, 5) 65 + 66 + #define BMA400_ACC_CONFIG1_REG 0x1a 67 + #define BMA400_ACC_CONFIG1_ODR_MASK GENMASK(3, 0) 68 + #define BMA400_ACC_CONFIG1_ODR_MIN_RAW 0x05 69 + #define BMA400_ACC_CONFIG1_ODR_LP_RAW 0x06 70 + #define BMA400_ACC_CONFIG1_ODR_MAX_RAW 0x0b 71 + #define BMA400_ACC_CONFIG1_ODR_MAX_HZ 800 72 + #define BMA400_ACC_CONFIG1_ODR_MIN_WHOLE_HZ 25 73 + #define BMA400_ACC_CONFIG1_ODR_MIN_HZ 12 74 + #define BMA400_ACC_CONFIG1_NP_OSR_MASK GENMASK(5, 4) 75 + #define BMA400_ACC_CONFIG1_ACC_RANGE_MASK GENMASK(7, 6) 76 + 80 77 #define BMA400_ACC_CONFIG2_REG 0x1b 81 - #define BMA400_CMD_REG 0x7e 82 78 83 79 /* Interrupt registers */ 84 80 #define BMA400_INT_CONFIG0_REG 0x1f 81 + #define BMA400_INT_CONFIG0_GEN1_MASK BIT(2) 82 + #define BMA400_INT_CONFIG0_GEN2_MASK BIT(3) 83 + #define BMA400_INT_CONFIG0_DRDY_MASK BIT(7) 84 + 85 + enum bma400_generic_intr { 86 + BMA400_GEN1_INTR = 0x1, 87 + BMA400_GEN2_INTR = 0x2, 88 + }; 89 + 85 90 #define BMA400_INT_CONFIG1_REG 0x20 91 + #define BMA400_INT_CONFIG1_STEP_INT_MASK BIT(0) 92 + #define BMA400_INT_CONFIG1_S_TAP_MASK BIT(2) 93 + #define BMA400_INT_CONFIG1_D_TAP_MASK BIT(3) 94 + 86 95 #define BMA400_INT1_MAP_REG 0x21 96 + #define BMA400_INT12_MAP_REG 0x23 87 97 #define BMA400_INT_IO_CTRL_REG 0x24 88 - #define BMA400_INT_DRDY_MSK BIT(7) 89 - 90 - /* Chip ID of BMA 400 devices found in the chip ID register. */ 91 - #define BMA400_ID_REG_VAL 0x90 92 - 93 - #define BMA400_LP_OSR_SHIFT 5 94 - #define BMA400_NP_OSR_SHIFT 4 95 - #define BMA400_SCALE_SHIFT 6 96 98 97 99 #define BMA400_TWO_BITS_MASK GENMASK(1, 0) 98 - #define BMA400_LP_OSR_MASK GENMASK(6, 5) 99 - #define BMA400_NP_OSR_MASK GENMASK(5, 4) 100 - #define BMA400_ACC_ODR_MASK GENMASK(3, 0) 101 - #define BMA400_ACC_SCALE_MASK GENMASK(7, 6) 102 - 103 - #define BMA400_ACC_ODR_MIN_RAW 0x05 104 - #define BMA400_ACC_ODR_LP_RAW 0x06 105 - #define BMA400_ACC_ODR_MAX_RAW 0x0b 106 - 107 - #define BMA400_ACC_ODR_MAX_HZ 800 108 - #define BMA400_ACC_ODR_MIN_WHOLE_HZ 25 109 - #define BMA400_ACC_ODR_MIN_HZ 12 110 100 111 101 /* Generic interrupts register */ 112 - #define BMA400_GEN1INT_CONFIG0 0x3f 113 - #define BMA400_GEN2INT_CONFIG0 0x4A 102 + #define BMA400_GENINT_CONFIG_REG_BASE 0x3f 103 + #define BMA400_NUM_GENINT_CONFIG_REGS 11 104 + #define BMA400_GENINT_CONFIG_REG(gen_intr, config_idx) \ 105 + (BMA400_GENINT_CONFIG_REG_BASE + \ 106 + (gen_intr - 1) * BMA400_NUM_GENINT_CONFIG_REGS + \ 107 + (config_idx)) 108 + #define BMA400_GENINT_CONFIG0_HYST_MASK GENMASK(1, 0) 109 + #define BMA400_GENINT_CONFIG0_REF_UPD_MODE_MASK GENMASK(3, 2) 110 + #define BMA400_GENINT_CONFIG0_DATA_SRC_MASK BIT(4) 111 + #define BMA400_GENINT_CONFIG0_X_EN_MASK BIT(5) 112 + #define BMA400_GENINT_CONFIG0_Y_EN_MASK BIT(6) 113 + #define BMA400_GENINT_CONFIG0_Z_EN_MASK BIT(7) 114 + 115 + enum bma400_accel_data_src { 116 + ACCEL_FILT1 = 0x0, 117 + ACCEL_FILT2 = 0x1, 118 + }; 119 + 120 + enum bma400_ref_updt_mode { 121 + BMA400_REF_MANUAL_UPDT_MODE = 0x0, 122 + BMA400_REF_ONETIME_UPDT_MODE = 0x1, 123 + BMA400_REF_EVERYTIME_UPDT_MODE = 0x2, 124 + BMA400_REF_EVERYTIME_LP_UPDT_MODE = 0x3, 125 + }; 126 + 114 127 #define BMA400_GEN_CONFIG1_OFF 0x01 115 - #define BMA400_GEN_CONFIG2_OFF 0x02 116 - #define BMA400_GEN_CONFIG3_OFF 0x03 117 - #define BMA400_GEN_CONFIG31_OFF 0x04 118 - #define BMA400_INT_GEN1_MSK BIT(2) 119 - #define BMA400_INT_GEN2_MSK BIT(3) 120 - #define BMA400_GEN_HYST_MSK GENMASK(1, 0) 128 + #define BMA400_GENINT_CONFIG1_AXES_COMB_MASK BIT(0) 129 + #define BMA400_GENINT_CONFIG1_DETCT_CRIT_MASK BIT(1) 130 + 131 + enum bma400_genintr_acceleval_axescomb { 132 + BMA400_EVAL_X_OR_Y_OR_Z = 0x0, 133 + BMA400_EVAL_X_AND_Y_AND_Z = 0x1, 134 + }; 135 + 136 + enum bma400_detect_criterion { 137 + BMA400_DETECT_INACTIVITY = 0x0, 138 + BMA400_DETECT_ACTIVITY = 0x1, 139 + }; 121 140 122 141 /* TAP config registers */ 123 - #define BMA400_TAP_CONFIG 0x57 124 - #define BMA400_TAP_CONFIG1 0x58 125 - #define BMA400_S_TAP_MSK BIT(2) 126 - #define BMA400_D_TAP_MSK BIT(3) 127 - #define BMA400_INT_S_TAP_MSK BIT(10) 128 - #define BMA400_INT_D_TAP_MSK BIT(11) 129 - #define BMA400_TAP_SEN_MSK GENMASK(2, 0) 130 - #define BMA400_TAP_TICSTH_MSK GENMASK(1, 0) 131 - #define BMA400_TAP_QUIET_MSK GENMASK(3, 2) 132 - #define BMA400_TAP_QUIETDT_MSK GENMASK(5, 4) 142 + #define BMA400_TAP_CONFIG_REG 0x57 143 + #define BMA400_TAP_CONFIG_SEN_MASK GENMASK(2, 0) 144 + 145 + #define BMA400_TAP_CONFIG1_REG 0x58 146 + #define BMA400_TAP_CONFIG1_TICSTH_MASK GENMASK(1, 0) 147 + #define BMA400_TAP_CONFIG1_QUIET_MASK GENMASK(3, 2) 148 + #define BMA400_TAP_CONFIG1_QUIETDT_MASK GENMASK(5, 4) 133 149 #define BMA400_TAP_TIM_LIST_LEN 4 134 150 151 + #define BMA400_CMD_REG 0x7e 135 152 /* 136 153 * BMA400_SCALE_MIN macro value represents m/s^2 for 1 LSB before 137 154 * converting to micro values for +-2g range. ··· 181 138 * To select +-8g = 9577 << 2 = raw value to write is 2. 182 139 * To select +-16g = 9577 << 3 = raw value to write is 3. 183 140 */ 184 - #define BMA400_SCALE_MIN 9577 185 - #define BMA400_SCALE_MAX 76617 141 + #define BMA400_ACC_SCALE_MIN 9577 142 + #define BMA400_ACC_SCALE_MAX 76617 186 143 187 144 extern const struct regmap_config bma400_regmap_config; 188 145
+193 -156
drivers/iio/accel/bma400_core.c
··· 121 121 __be16 duration; 122 122 }; 123 123 124 + struct bma400_genintr_info { 125 + enum bma400_generic_intr genintr; 126 + unsigned int intrmask; 127 + enum iio_event_direction dir; 128 + enum bma400_detect_criterion detect_mode; 129 + }; 130 + 131 + /* Lookup struct for determining GEN1/GEN2 based on dir */ 132 + static const struct bma400_genintr_info bma400_genintrs[] = { 133 + [IIO_EV_DIR_RISING] = { 134 + .genintr = BMA400_GEN1_INTR, 135 + .intrmask = BMA400_INT_CONFIG0_GEN1_MASK, 136 + .dir = IIO_EV_DIR_RISING, 137 + .detect_mode = BMA400_DETECT_ACTIVITY, 138 + }, 139 + [IIO_EV_DIR_FALLING] = { 140 + .genintr = BMA400_GEN2_INTR, 141 + .intrmask = BMA400_INT_CONFIG0_GEN2_MASK, 142 + .dir = IIO_EV_DIR_FALLING, 143 + .detect_mode = BMA400_DETECT_INACTIVITY, 144 + } 145 + }; 146 + 147 + static inline const struct bma400_genintr_info * 148 + get_bma400_genintr_info(enum iio_event_direction dir) 149 + { 150 + switch (dir) { 151 + case IIO_EV_DIR_RISING: 152 + case IIO_EV_DIR_FALLING: 153 + return &bma400_genintrs[dir]; 154 + default: 155 + return NULL; 156 + }; 157 + } 158 + 124 159 static bool bma400_is_writable_reg(struct device *dev, unsigned int reg) 125 160 { 126 161 switch (reg) { 127 162 case BMA400_CHIP_ID_REG: 128 163 case BMA400_ERR_REG: 129 164 case BMA400_STATUS_REG: 130 - case BMA400_X_AXIS_LSB_REG: 131 - case BMA400_X_AXIS_MSB_REG: 132 - case BMA400_Y_AXIS_LSB_REG: 133 - case BMA400_Y_AXIS_MSB_REG: 134 - case BMA400_Z_AXIS_LSB_REG: 135 - case BMA400_Z_AXIS_MSB_REG: 136 - case BMA400_SENSOR_TIME0: 137 - case BMA400_SENSOR_TIME1: 138 - case BMA400_SENSOR_TIME2: 165 + case BMA400_ACC_X_LSB_REG: 166 + case BMA400_ACC_X_MSB_REG: 167 + case BMA400_ACC_Y_LSB_REG: 168 + case BMA400_ACC_Y_MSB_REG: 169 + case BMA400_ACC_Z_LSB_REG: 170 + case BMA400_ACC_Z_MSB_REG: 171 + case BMA400_SENSOR_TIME0_REG: 172 + case BMA400_SENSOR_TIME1_REG: 173 + case BMA400_SENSOR_TIME2_REG: 139 174 case BMA400_EVENT_REG: 140 175 case BMA400_INT_STAT0_REG: 141 176 case BMA400_INT_STAT1_REG: ··· 194 159 switch (reg) { 195 160 case BMA400_ERR_REG: 196 161 case BMA400_STATUS_REG: 197 - case BMA400_X_AXIS_LSB_REG: 198 - case BMA400_X_AXIS_MSB_REG: 199 - case BMA400_Y_AXIS_LSB_REG: 200 - case BMA400_Y_AXIS_MSB_REG: 201 - case BMA400_Z_AXIS_LSB_REG: 202 - case BMA400_Z_AXIS_MSB_REG: 203 - case BMA400_SENSOR_TIME0: 204 - case BMA400_SENSOR_TIME1: 205 - case BMA400_SENSOR_TIME2: 162 + case BMA400_ACC_X_LSB_REG: 163 + case BMA400_ACC_X_MSB_REG: 164 + case BMA400_ACC_Y_LSB_REG: 165 + case BMA400_ACC_Y_MSB_REG: 166 + case BMA400_ACC_Z_LSB_REG: 167 + case BMA400_ACC_Z_MSB_REG: 168 + case BMA400_SENSOR_TIME0_REG: 169 + case BMA400_SENSOR_TIME1_REG: 170 + case BMA400_SENSOR_TIME2_REG: 206 171 case BMA400_EVENT_REG: 207 172 case BMA400_INT_STAT0_REG: 208 173 case BMA400_INT_STAT1_REG: ··· 310 275 struct bma400_data *data = iio_priv(indio_dev); 311 276 int ret, reg_val, raw, vals[2]; 312 277 313 - ret = regmap_read(data->regmap, BMA400_TAP_CONFIG1, &reg_val); 278 + ret = regmap_read(data->regmap, BMA400_TAP_CONFIG1_REG, &reg_val); 314 279 if (ret) 315 280 return ret; 316 281 317 - raw = FIELD_GET(BMA400_TAP_TICSTH_MSK, reg_val); 282 + raw = FIELD_GET(BMA400_TAP_CONFIG1_TICSTH_MASK, reg_val); 318 283 vals[0] = 0; 319 284 vals[1] = tap_max2min_time[raw]; 320 285 ··· 337 302 if (raw < 0) 338 303 return -EINVAL; 339 304 340 - ret = regmap_update_bits(data->regmap, BMA400_TAP_CONFIG1, 341 - BMA400_TAP_TICSTH_MSK, 342 - FIELD_PREP(BMA400_TAP_TICSTH_MSK, raw)); 305 + ret = regmap_update_bits(data->regmap, BMA400_TAP_CONFIG1_REG, 306 + BMA400_TAP_CONFIG1_TICSTH_MASK, 307 + FIELD_PREP(BMA400_TAP_CONFIG1_TICSTH_MASK, raw)); 343 308 if (ret) 344 309 return ret; 345 310 ··· 484 449 485 450 switch (chan->channel2) { 486 451 case IIO_MOD_X: 487 - lsb_reg = BMA400_X_AXIS_LSB_REG; 452 + lsb_reg = BMA400_ACC_X_LSB_REG; 488 453 break; 489 454 case IIO_MOD_Y: 490 - lsb_reg = BMA400_Y_AXIS_LSB_REG; 455 + lsb_reg = BMA400_ACC_Y_LSB_REG; 491 456 break; 492 457 case IIO_MOD_Z: 493 - lsb_reg = BMA400_Z_AXIS_LSB_REG; 458 + lsb_reg = BMA400_ACC_Z_LSB_REG; 494 459 break; 495 460 default: 496 461 dev_err(data->dev, "invalid axis channel modifier\n"); ··· 510 475 static void bma400_output_data_rate_from_raw(int raw, unsigned int *val, 511 476 unsigned int *val2) 512 477 { 513 - *val = BMA400_ACC_ODR_MAX_HZ >> (BMA400_ACC_ODR_MAX_RAW - raw); 514 - if (raw > BMA400_ACC_ODR_MIN_RAW) 478 + *val = BMA400_ACC_CONFIG1_ODR_MAX_HZ >> (BMA400_ACC_CONFIG1_ODR_MAX_RAW - raw); 479 + if (raw > BMA400_ACC_CONFIG1_ODR_MIN_RAW) 515 480 *val2 = 0; 516 481 else 517 482 *val2 = 500000; ··· 529 494 * Runs at a fixed rate in low-power mode. See section 4.3 530 495 * in the datasheet. 531 496 */ 532 - bma400_output_data_rate_from_raw(BMA400_ACC_ODR_LP_RAW, 497 + bma400_output_data_rate_from_raw(BMA400_ACC_CONFIG1_ODR_LP_RAW, 533 498 &data->sample_freq.hz, 534 499 &data->sample_freq.uhz); 535 500 return 0; ··· 542 507 if (ret) 543 508 goto error; 544 509 545 - odr = val & BMA400_ACC_ODR_MASK; 546 - if (odr < BMA400_ACC_ODR_MIN_RAW || 547 - odr > BMA400_ACC_ODR_MAX_RAW) { 510 + odr = val & BMA400_ACC_CONFIG1_ODR_MASK; 511 + if (odr < BMA400_ACC_CONFIG1_ODR_MIN_RAW || 512 + odr > BMA400_ACC_CONFIG1_ODR_MAX_RAW) { 548 513 ret = -EINVAL; 549 514 goto error; 550 515 } ··· 574 539 unsigned int val; 575 540 int ret; 576 541 577 - if (hz >= BMA400_ACC_ODR_MIN_WHOLE_HZ) { 578 - if (uhz || hz > BMA400_ACC_ODR_MAX_HZ) 542 + if (hz >= BMA400_ACC_CONFIG1_ODR_MIN_WHOLE_HZ) { 543 + if (uhz || hz > BMA400_ACC_CONFIG1_ODR_MAX_HZ) 579 544 return -EINVAL; 580 545 581 546 /* Note this works because MIN_WHOLE_HZ is odd */ 582 547 idx = __ffs(hz); 583 548 584 - if (hz >> idx != BMA400_ACC_ODR_MIN_WHOLE_HZ) 549 + if (hz >> idx != BMA400_ACC_CONFIG1_ODR_MIN_WHOLE_HZ) 585 550 return -EINVAL; 586 551 587 - idx += BMA400_ACC_ODR_MIN_RAW + 1; 588 - } else if (hz == BMA400_ACC_ODR_MIN_HZ && uhz == 500000) { 589 - idx = BMA400_ACC_ODR_MIN_RAW; 552 + idx += BMA400_ACC_CONFIG1_ODR_MIN_RAW + 1; 553 + } else if (hz == BMA400_ACC_CONFIG1_ODR_MIN_HZ && uhz == 500000) { 554 + idx = BMA400_ACC_CONFIG1_ODR_MIN_RAW; 590 555 } else { 591 556 return -EINVAL; 592 557 } ··· 596 561 return ret; 597 562 598 563 /* preserve the range and normal mode osr */ 599 - odr = (~BMA400_ACC_ODR_MASK & val) | idx; 564 + odr = (~BMA400_ACC_CONFIG1_ODR_MASK & val) | idx; 600 565 601 566 ret = regmap_write(data->regmap, BMA400_ACC_CONFIG1_REG, odr); 602 567 if (ret) ··· 627 592 return ret; 628 593 } 629 594 630 - osr = (val & BMA400_LP_OSR_MASK) >> BMA400_LP_OSR_SHIFT; 595 + osr = FIELD_GET(BMA400_ACC_CONFIG0_LP_OSR_MASK, val); 631 596 632 597 data->oversampling_ratio = osr; 633 598 return 0; ··· 638 603 return ret; 639 604 } 640 605 641 - osr = (val & BMA400_NP_OSR_MASK) >> BMA400_NP_OSR_SHIFT; 606 + osr = FIELD_GET(BMA400_ACC_CONFIG1_NP_OSR_MASK, val); 642 607 643 608 data->oversampling_ratio = osr; 644 609 return 0; ··· 672 637 return ret; 673 638 674 639 ret = regmap_write(data->regmap, BMA400_ACC_CONFIG0_REG, 675 - (acc_config & ~BMA400_LP_OSR_MASK) | 676 - (val << BMA400_LP_OSR_SHIFT)); 640 + (acc_config & ~BMA400_ACC_CONFIG0_LP_OSR_MASK) | 641 + FIELD_PREP(BMA400_ACC_CONFIG0_LP_OSR_MASK, val)); 677 642 if (ret) { 678 643 dev_err(data->dev, "Failed to write out OSR\n"); 679 644 return ret; ··· 688 653 return ret; 689 654 690 655 ret = regmap_write(data->regmap, BMA400_ACC_CONFIG1_REG, 691 - (acc_config & ~BMA400_NP_OSR_MASK) | 692 - (val << BMA400_NP_OSR_SHIFT)); 656 + (acc_config & ~BMA400_ACC_CONFIG1_NP_OSR_MASK) | 657 + FIELD_PREP(BMA400_ACC_CONFIG1_NP_OSR_MASK, val)); 693 658 if (ret) { 694 659 dev_err(data->dev, "Failed to write out OSR\n"); 695 660 return ret; ··· 714 679 /* Note this works because BMA400_SCALE_MIN is odd */ 715 680 raw = __ffs(val); 716 681 717 - if (val >> raw != BMA400_SCALE_MIN) 682 + if (val >> raw != BMA400_ACC_SCALE_MIN) 718 683 return -EINVAL; 719 684 720 685 return raw; ··· 730 695 if (ret) 731 696 return ret; 732 697 733 - raw_scale = (val & BMA400_ACC_SCALE_MASK) >> BMA400_SCALE_SHIFT; 698 + raw_scale = FIELD_GET(BMA400_ACC_CONFIG1_ACC_RANGE_MASK, val); 734 699 if (raw_scale > BMA400_TWO_BITS_MASK) 735 700 return -EINVAL; 736 701 737 - data->scale = BMA400_SCALE_MIN << raw_scale; 702 + data->scale = BMA400_ACC_SCALE_MIN << raw_scale; 738 703 739 704 return 0; 740 705 } ··· 754 719 return raw; 755 720 756 721 ret = regmap_write(data->regmap, BMA400_ACC_CONFIG1_REG, 757 - (acc_config & ~BMA400_ACC_SCALE_MASK) | 758 - (raw << BMA400_SCALE_SHIFT)); 722 + (acc_config & ~BMA400_ACC_CONFIG1_ACC_RANGE_MASK) | 723 + FIELD_PREP(BMA400_ACC_CONFIG1_ACC_RANGE_MASK, raw)); 759 724 if (ret) 760 725 return ret; 761 726 ··· 821 786 return 0; 822 787 823 788 ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG1_REG, 824 - BMA400_STEP_INT_MSK, 825 - FIELD_PREP(BMA400_STEP_INT_MSK, val ? 1 : 0)); 789 + BMA400_INT_CONFIG1_STEP_INT_MASK, 790 + FIELD_PREP(BMA400_INT_CONFIG1_STEP_INT_MASK, val ? 1 : 0)); 826 791 if (ret) 827 792 return ret; 828 793 data->steps_enabled = val; ··· 861 826 for (i = 0; i + 1 < ARRAY_SIZE(bma400_scales); i += 2) { 862 827 raw = i / 2; 863 828 bma400_scales[i] = 0; 864 - bma400_scales[i + 1] = BMA400_SCALE_MIN << raw; 829 + bma400_scales[i + 1] = BMA400_ACC_SCALE_MIN << raw; 865 830 } 866 831 } 867 832 ··· 1098 1063 return ret; 1099 1064 case IIO_CHAN_INFO_SCALE: 1100 1065 if (val != 0 || 1101 - val2 < BMA400_SCALE_MIN || val2 > BMA400_SCALE_MAX) 1066 + val2 < BMA400_ACC_SCALE_MIN || val2 > BMA400_ACC_SCALE_MAX) 1102 1067 return -EINVAL; 1103 1068 1104 1069 mutex_lock(&data->mutex); ··· 1149 1114 case IIO_ACCEL: 1150 1115 switch (dir) { 1151 1116 case IIO_EV_DIR_RISING: 1152 - return FIELD_GET(BMA400_INT_GEN1_MSK, 1117 + return FIELD_GET(BMA400_INT_CONFIG0_GEN1_MASK, 1153 1118 data->generic_event_en); 1154 1119 case IIO_EV_DIR_FALLING: 1155 - return FIELD_GET(BMA400_INT_GEN2_MSK, 1120 + return FIELD_GET(BMA400_INT_CONFIG0_GEN2_MASK, 1156 1121 data->generic_event_en); 1157 1122 case IIO_EV_DIR_SINGLETAP: 1158 - return FIELD_GET(BMA400_S_TAP_MSK, 1123 + return FIELD_GET(BMA400_INT_CONFIG1_S_TAP_MASK, 1159 1124 data->tap_event_en_bitmask); 1160 1125 case IIO_EV_DIR_DOUBLETAP: 1161 - return FIELD_GET(BMA400_D_TAP_MSK, 1126 + return FIELD_GET(BMA400_INT_CONFIG1_D_TAP_MASK, 1162 1127 data->tap_event_en_bitmask); 1163 1128 default: 1164 1129 return -EINVAL; ··· 1181 1146 return ret; 1182 1147 1183 1148 ret = regmap_update_bits(data->regmap, BMA400_INT12_MAP_REG, 1184 - BMA400_STEP_INT_MSK, 1185 - FIELD_PREP(BMA400_STEP_INT_MSK, 1149 + BMA400_INT_CONFIG1_STEP_INT_MASK, 1150 + FIELD_PREP(BMA400_INT_CONFIG1_STEP_INT_MASK, 1186 1151 state)); 1187 1152 if (ret) 1188 1153 return ret; ··· 1190 1155 return 0; 1191 1156 } 1192 1157 1193 - static int bma400_activity_event_en(struct bma400_data *data, 1194 - enum iio_event_direction dir, 1195 - int state) 1158 + static int bma400_generic_event_en(struct bma400_data *data, 1159 + enum iio_event_direction dir, 1160 + int state) 1196 1161 { 1197 - int ret, reg, msk, value; 1198 - int field_value = 0; 1162 + int ret; 1163 + unsigned int intrmask, regval; 1164 + enum bma400_generic_intr genintr; 1165 + enum bma400_detect_criterion detect_criterion; 1166 + const struct bma400_genintr_info *bma400_genintr; 1199 1167 1200 - switch (dir) { 1201 - case IIO_EV_DIR_RISING: 1202 - reg = BMA400_GEN1INT_CONFIG0; 1203 - msk = BMA400_INT_GEN1_MSK; 1204 - value = 2; 1205 - set_mask_bits(&field_value, BMA400_INT_GEN1_MSK, 1206 - FIELD_PREP(BMA400_INT_GEN1_MSK, state)); 1207 - break; 1208 - case IIO_EV_DIR_FALLING: 1209 - reg = BMA400_GEN2INT_CONFIG0; 1210 - msk = BMA400_INT_GEN2_MSK; 1211 - value = 0; 1212 - set_mask_bits(&field_value, BMA400_INT_GEN2_MSK, 1213 - FIELD_PREP(BMA400_INT_GEN2_MSK, state)); 1214 - break; 1215 - default: 1168 + bma400_genintr = get_bma400_genintr_info(dir); 1169 + if (!bma400_genintr) 1216 1170 return -EINVAL; 1217 - } 1218 1171 1219 - /* Enabling all axis for interrupt evaluation */ 1220 - ret = regmap_write(data->regmap, reg, 0xF8); 1172 + genintr = bma400_genintr->genintr; 1173 + detect_criterion = bma400_genintr->detect_mode; 1174 + intrmask = bma400_genintr->intrmask; 1175 + 1176 + /* 1177 + * Enabling all axis for interrupt evaluation 1178 + * Acc_filt2 is recommended as data source in datasheet (Section 4.7) 1179 + */ 1180 + ret = regmap_write(data->regmap, BMA400_GENINT_CONFIG_REG(genintr, 0), 1181 + BMA400_GENINT_CONFIG0_X_EN_MASK | 1182 + BMA400_GENINT_CONFIG0_Y_EN_MASK | 1183 + BMA400_GENINT_CONFIG0_Z_EN_MASK| 1184 + FIELD_PREP(BMA400_GENINT_CONFIG0_DATA_SRC_MASK, ACCEL_FILT2)| 1185 + FIELD_PREP(BMA400_GENINT_CONFIG0_REF_UPD_MODE_MASK, 1186 + BMA400_REF_EVERYTIME_UPDT_MODE)); 1221 1187 if (ret) 1222 1188 return ret; 1223 1189 1224 1190 /* OR combination of all axis for interrupt evaluation */ 1225 - ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG1_OFF, value); 1191 + regval = FIELD_PREP(BMA400_GENINT_CONFIG1_AXES_COMB_MASK, BMA400_EVAL_X_OR_Y_OR_Z) | 1192 + FIELD_PREP(BMA400_GENINT_CONFIG1_DETCT_CRIT_MASK, detect_criterion); 1193 + ret = regmap_write(data->regmap, BMA400_GENINT_CONFIG_REG(genintr, 1), regval); 1226 1194 if (ret) 1227 1195 return ret; 1228 1196 1229 - /* Initial value to avoid interrupts while enabling*/ 1230 - ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG2_OFF, 0x0A); 1197 + /* 1198 + * Initial value to avoid interrupts while enabling 1199 + * Value is in units of 8mg/lsb, i.e. effective val is val * 8mg/lsb 1200 + */ 1201 + ret = regmap_write(data->regmap, BMA400_GENINT_CONFIG_REG(genintr, 2), 0x0A); 1231 1202 if (ret) 1232 1203 return ret; 1233 1204 1234 1205 /* Initial duration value to avoid interrupts while enabling*/ 1235 - ret = regmap_write(data->regmap, reg + BMA400_GEN_CONFIG31_OFF, 0x0F); 1206 + ret = regmap_write(data->regmap, BMA400_GENINT_CONFIG_REG(genintr, 4), 0x0F); 1236 1207 if (ret) 1237 1208 return ret; 1238 1209 1239 - ret = regmap_update_bits(data->regmap, BMA400_INT1_MAP_REG, msk, 1240 - field_value); 1210 + regval = state ? intrmask : 0; 1211 + ret = regmap_update_bits(data->regmap, BMA400_INT1_MAP_REG, intrmask, regval); 1241 1212 if (ret) 1242 1213 return ret; 1243 1214 1244 - ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG0_REG, msk, 1245 - field_value); 1215 + ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG0_REG, intrmask, regval); 1246 1216 if (ret) 1247 1217 return ret; 1248 1218 1249 - set_mask_bits(&data->generic_event_en, msk, field_value); 1219 + set_mask_bits(&data->generic_event_en, intrmask, regval); 1250 1220 return 0; 1251 1221 } 1252 1222 ··· 1280 1240 } 1281 1241 1282 1242 ret = regmap_update_bits(data->regmap, BMA400_INT12_MAP_REG, 1283 - BMA400_S_TAP_MSK, 1284 - FIELD_PREP(BMA400_S_TAP_MSK, state)); 1243 + BMA400_INT_CONFIG1_S_TAP_MASK, 1244 + FIELD_PREP(BMA400_INT_CONFIG1_S_TAP_MASK, state)); 1285 1245 if (ret) 1286 1246 return ret; 1287 1247 1288 1248 switch (dir) { 1289 1249 case IIO_EV_DIR_SINGLETAP: 1290 - mask = BMA400_S_TAP_MSK; 1291 - set_mask_bits(&field_value, BMA400_S_TAP_MSK, 1292 - FIELD_PREP(BMA400_S_TAP_MSK, state)); 1250 + mask = BMA400_INT_CONFIG1_S_TAP_MASK; 1251 + set_mask_bits(&field_value, BMA400_INT_CONFIG1_S_TAP_MASK, 1252 + FIELD_PREP(BMA400_INT_CONFIG1_S_TAP_MASK, state)); 1293 1253 break; 1294 1254 case IIO_EV_DIR_DOUBLETAP: 1295 - mask = BMA400_D_TAP_MSK; 1296 - set_mask_bits(&field_value, BMA400_D_TAP_MSK, 1297 - FIELD_PREP(BMA400_D_TAP_MSK, state)); 1255 + mask = BMA400_INT_CONFIG1_D_TAP_MASK; 1256 + set_mask_bits(&field_value, BMA400_INT_CONFIG1_D_TAP_MASK, 1257 + FIELD_PREP(BMA400_INT_CONFIG1_D_TAP_MASK, state)); 1298 1258 break; 1299 1259 default: 1300 1260 return -EINVAL; ··· 1343 1303 switch (type) { 1344 1304 case IIO_EV_TYPE_MAG: 1345 1305 mutex_lock(&data->mutex); 1346 - ret = bma400_activity_event_en(data, dir, state); 1306 + ret = bma400_generic_event_en(data, dir, state); 1347 1307 mutex_unlock(&data->mutex); 1348 1308 return ret; 1349 1309 case IIO_EV_TYPE_GESTURE: ··· 1376 1336 } 1377 1337 } 1378 1338 1379 - static int get_gen_config_reg(enum iio_event_direction dir) 1380 - { 1381 - switch (dir) { 1382 - case IIO_EV_DIR_FALLING: 1383 - return BMA400_GEN2INT_CONFIG0; 1384 - case IIO_EV_DIR_RISING: 1385 - return BMA400_GEN1INT_CONFIG0; 1386 - default: 1387 - return -EINVAL; 1388 - } 1389 - } 1390 - 1391 1339 static int bma400_read_event_value(struct iio_dev *indio_dev, 1392 1340 const struct iio_chan_spec *chan, 1393 1341 enum iio_event_type type, ··· 1384 1356 int *val, int *val2) 1385 1357 { 1386 1358 struct bma400_data *data = iio_priv(indio_dev); 1387 - int ret, reg, reg_val, raw; 1359 + int ret, reg_val, raw; 1360 + enum bma400_generic_intr genintr; 1361 + const struct bma400_genintr_info *bma400_genintr; 1388 1362 1389 1363 if (chan->type != IIO_ACCEL) 1390 1364 return -EINVAL; 1391 1365 1392 1366 switch (type) { 1393 1367 case IIO_EV_TYPE_MAG: 1394 - reg = get_gen_config_reg(dir); 1395 - if (reg < 0) 1368 + bma400_genintr = get_bma400_genintr_info(dir); 1369 + if (!bma400_genintr) 1396 1370 return -EINVAL; 1371 + genintr = bma400_genintr->genintr; 1397 1372 1398 1373 *val2 = 0; 1399 1374 switch (info) { 1400 1375 case IIO_EV_INFO_VALUE: 1401 1376 ret = regmap_read(data->regmap, 1402 - reg + BMA400_GEN_CONFIG2_OFF, 1377 + BMA400_GENINT_CONFIG_REG(genintr, 2), 1403 1378 val); 1404 1379 if (ret) 1405 1380 return ret; ··· 1410 1379 case IIO_EV_INFO_PERIOD: 1411 1380 mutex_lock(&data->mutex); 1412 1381 ret = regmap_bulk_read(data->regmap, 1413 - reg + BMA400_GEN_CONFIG3_OFF, 1382 + BMA400_GENINT_CONFIG_REG(genintr, 3), 1414 1383 &data->duration, 1415 1384 sizeof(data->duration)); 1416 1385 if (ret) { ··· 1421 1390 mutex_unlock(&data->mutex); 1422 1391 return IIO_VAL_INT; 1423 1392 case IIO_EV_INFO_HYSTERESIS: 1424 - ret = regmap_read(data->regmap, reg, val); 1393 + ret = regmap_read(data->regmap, 1394 + BMA400_GENINT_CONFIG_REG(genintr, 0), 1395 + val); 1425 1396 if (ret) 1426 1397 return ret; 1427 - *val = FIELD_GET(BMA400_GEN_HYST_MSK, *val); 1398 + *val = FIELD_GET(BMA400_GENINT_CONFIG0_HYST_MASK, *val); 1428 1399 return IIO_VAL_INT; 1429 1400 default: 1430 1401 return -EINVAL; ··· 1434 1401 case IIO_EV_TYPE_GESTURE: 1435 1402 switch (info) { 1436 1403 case IIO_EV_INFO_VALUE: 1437 - ret = regmap_read(data->regmap, BMA400_TAP_CONFIG, 1404 + ret = regmap_read(data->regmap, BMA400_TAP_CONFIG_REG, 1438 1405 &reg_val); 1439 1406 if (ret) 1440 1407 return ret; 1441 1408 1442 - *val = FIELD_GET(BMA400_TAP_SEN_MSK, reg_val); 1409 + *val = FIELD_GET(BMA400_TAP_CONFIG_SEN_MASK, reg_val); 1443 1410 return IIO_VAL_INT; 1444 1411 case IIO_EV_INFO_RESET_TIMEOUT: 1445 - ret = regmap_read(data->regmap, BMA400_TAP_CONFIG1, 1412 + ret = regmap_read(data->regmap, BMA400_TAP_CONFIG1_REG, 1446 1413 &reg_val); 1447 1414 if (ret) 1448 1415 return ret; 1449 1416 1450 - raw = FIELD_GET(BMA400_TAP_QUIET_MSK, reg_val); 1417 + raw = FIELD_GET(BMA400_TAP_CONFIG1_QUIET_MASK, reg_val); 1451 1418 *val = 0; 1452 1419 *val2 = tap_reset_timeout[raw]; 1453 1420 return IIO_VAL_INT_PLUS_MICRO; 1454 1421 case IIO_EV_INFO_TAP2_MIN_DELAY: 1455 - ret = regmap_read(data->regmap, BMA400_TAP_CONFIG1, 1422 + ret = regmap_read(data->regmap, BMA400_TAP_CONFIG1_REG, 1456 1423 &reg_val); 1457 1424 if (ret) 1458 1425 return ret; 1459 1426 1460 - raw = FIELD_GET(BMA400_TAP_QUIETDT_MSK, reg_val); 1427 + raw = FIELD_GET(BMA400_TAP_CONFIG1_QUIETDT_MASK, reg_val); 1461 1428 *val = 0; 1462 1429 *val2 = double_tap2_min_delay[raw]; 1463 1430 return IIO_VAL_INT_PLUS_MICRO; ··· 1477 1444 int val, int val2) 1478 1445 { 1479 1446 struct bma400_data *data = iio_priv(indio_dev); 1480 - int reg, ret, raw; 1447 + int ret, raw; 1448 + enum bma400_generic_intr genintr; 1449 + const struct bma400_genintr_info *bma400_genintr; 1481 1450 1482 1451 if (chan->type != IIO_ACCEL) 1483 1452 return -EINVAL; 1484 1453 1485 1454 switch (type) { 1486 1455 case IIO_EV_TYPE_MAG: 1487 - reg = get_gen_config_reg(dir); 1488 - if (reg < 0) 1456 + bma400_genintr = get_bma400_genintr_info(dir); 1457 + if (!bma400_genintr) 1489 1458 return -EINVAL; 1459 + genintr = bma400_genintr->genintr; 1490 1460 1491 1461 switch (info) { 1492 1462 case IIO_EV_INFO_VALUE: ··· 1497 1461 return -EINVAL; 1498 1462 1499 1463 return regmap_write(data->regmap, 1500 - reg + BMA400_GEN_CONFIG2_OFF, 1464 + BMA400_GENINT_CONFIG_REG(genintr, 2), 1501 1465 val); 1502 1466 case IIO_EV_INFO_PERIOD: 1503 1467 if (val < 1 || val > 65535) ··· 1506 1470 mutex_lock(&data->mutex); 1507 1471 put_unaligned_be16(val, &data->duration); 1508 1472 ret = regmap_bulk_write(data->regmap, 1509 - reg + BMA400_GEN_CONFIG3_OFF, 1473 + BMA400_GENINT_CONFIG_REG(genintr, 3), 1510 1474 &data->duration, 1511 1475 sizeof(data->duration)); 1512 1476 mutex_unlock(&data->mutex); ··· 1515 1479 if (val < 0 || val > 3) 1516 1480 return -EINVAL; 1517 1481 1518 - return regmap_update_bits(data->regmap, reg, 1519 - BMA400_GEN_HYST_MSK, 1520 - FIELD_PREP(BMA400_GEN_HYST_MSK, 1482 + return regmap_update_bits(data->regmap, 1483 + BMA400_GENINT_CONFIG_REG(genintr, 0), 1484 + BMA400_GENINT_CONFIG0_HYST_MASK, 1485 + FIELD_PREP(BMA400_GENINT_CONFIG0_HYST_MASK, 1521 1486 val)); 1522 1487 default: 1523 1488 return -EINVAL; ··· 1530 1493 return -EINVAL; 1531 1494 1532 1495 return regmap_update_bits(data->regmap, 1533 - BMA400_TAP_CONFIG, 1534 - BMA400_TAP_SEN_MSK, 1535 - FIELD_PREP(BMA400_TAP_SEN_MSK, 1496 + BMA400_TAP_CONFIG_REG, 1497 + BMA400_TAP_CONFIG_SEN_MASK, 1498 + FIELD_PREP(BMA400_TAP_CONFIG_SEN_MASK, 1536 1499 val)); 1537 1500 case IIO_EV_INFO_RESET_TIMEOUT: 1538 1501 raw = usec_to_tapreg_raw(val2, tap_reset_timeout); ··· 1540 1503 return -EINVAL; 1541 1504 1542 1505 return regmap_update_bits(data->regmap, 1543 - BMA400_TAP_CONFIG1, 1544 - BMA400_TAP_QUIET_MSK, 1545 - FIELD_PREP(BMA400_TAP_QUIET_MSK, 1506 + BMA400_TAP_CONFIG1_REG, 1507 + BMA400_TAP_CONFIG1_QUIET_MASK, 1508 + FIELD_PREP(BMA400_TAP_CONFIG1_QUIET_MASK, 1546 1509 raw)); 1547 1510 case IIO_EV_INFO_TAP2_MIN_DELAY: 1548 1511 raw = usec_to_tapreg_raw(val2, double_tap2_min_delay); ··· 1550 1513 return -EINVAL; 1551 1514 1552 1515 return regmap_update_bits(data->regmap, 1553 - BMA400_TAP_CONFIG1, 1554 - BMA400_TAP_QUIETDT_MSK, 1555 - FIELD_PREP(BMA400_TAP_QUIETDT_MSK, 1516 + BMA400_TAP_CONFIG1_REG, 1517 + BMA400_TAP_CONFIG1_QUIETDT_MASK, 1518 + FIELD_PREP(BMA400_TAP_CONFIG1_QUIETDT_MASK, 1556 1519 raw)); 1557 1520 default: 1558 1521 return -EINVAL; ··· 1570 1533 int ret; 1571 1534 1572 1535 ret = regmap_update_bits(data->regmap, BMA400_INT_CONFIG0_REG, 1573 - BMA400_INT_DRDY_MSK, 1574 - FIELD_PREP(BMA400_INT_DRDY_MSK, state)); 1536 + BMA400_INT_CONFIG0_DRDY_MASK, 1537 + FIELD_PREP(BMA400_INT_CONFIG0_DRDY_MASK, state)); 1575 1538 if (ret) 1576 1539 return ret; 1577 1540 1578 1541 return regmap_update_bits(data->regmap, BMA400_INT1_MAP_REG, 1579 - BMA400_INT_DRDY_MSK, 1580 - FIELD_PREP(BMA400_INT_DRDY_MSK, state)); 1542 + BMA400_INT_CONFIG0_DRDY_MASK, 1543 + FIELD_PREP(BMA400_INT_CONFIG0_DRDY_MASK, state)); 1581 1544 } 1582 1545 1583 1546 static const unsigned long bma400_avail_scan_masks[] = { ··· 1615 1578 mutex_lock(&data->mutex); 1616 1579 1617 1580 /* bulk read six registers, with the base being the LSB register */ 1618 - ret = regmap_bulk_read(data->regmap, BMA400_X_AXIS_LSB_REG, 1581 + ret = regmap_bulk_read(data->regmap, BMA400_ACC_X_LSB_REG, 1619 1582 &data->buffer.buff, sizeof(data->buffer.buff)); 1620 1583 if (ret) 1621 1584 goto unlock_err; ··· 1665 1628 * Disable all advance interrupts if interrupt engine overrun occurs. 1666 1629 * See section 4.7 "Interrupt engine overrun" in datasheet v1.2. 1667 1630 */ 1668 - if (FIELD_GET(BMA400_INT_ENG_OVRUN_MSK, le16_to_cpu(data->status))) { 1631 + if (FIELD_GET(BMA400_INT_STAT_ENG_OVRRUN_MASK, le16_to_cpu(data->status))) { 1669 1632 bma400_disable_adv_interrupt(data); 1670 1633 dev_err(data->dev, "Interrupt engine overrun\n"); 1671 1634 goto unlock_err; 1672 1635 } 1673 1636 1674 - if (FIELD_GET(BMA400_INT_S_TAP_MSK, le16_to_cpu(data->status))) 1637 + if (FIELD_GET(BMA400_INT_STAT1_S_TAP_MASK, le16_to_cpu(data->status))) 1675 1638 iio_push_event(indio_dev, 1676 1639 IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, 1677 1640 IIO_MOD_X_OR_Y_OR_Z, ··· 1679 1642 IIO_EV_DIR_SINGLETAP), 1680 1643 timestamp); 1681 1644 1682 - if (FIELD_GET(BMA400_INT_D_TAP_MSK, le16_to_cpu(data->status))) 1645 + if (FIELD_GET(BMA400_INT_STAT1_D_TAP_MASK, le16_to_cpu(data->status))) 1683 1646 iio_push_event(indio_dev, 1684 1647 IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, 1685 1648 IIO_MOD_X_OR_Y_OR_Z, ··· 1687 1650 IIO_EV_DIR_DOUBLETAP), 1688 1651 timestamp); 1689 1652 1690 - if (FIELD_GET(BMA400_INT_GEN1_MSK, le16_to_cpu(data->status))) 1653 + if (FIELD_GET(BMA400_INT_STAT0_GEN1_MASK, le16_to_cpu(data->status))) 1691 1654 ev_dir = IIO_EV_DIR_RISING; 1692 1655 1693 - if (FIELD_GET(BMA400_INT_GEN2_MSK, le16_to_cpu(data->status))) 1656 + if (FIELD_GET(BMA400_INT_STAT0_GEN2_MASK, le16_to_cpu(data->status))) 1694 1657 ev_dir = IIO_EV_DIR_FALLING; 1695 1658 1696 1659 if (ev_dir != IIO_EV_DIR_NONE) { ··· 1701 1664 timestamp); 1702 1665 } 1703 1666 1704 - if (FIELD_GET(BMA400_STEP_STAT_MASK, le16_to_cpu(data->status))) { 1667 + if (FIELD_GET(BMA400_INT_STAT1_STEP_INT_MASK, le16_to_cpu(data->status))) { 1705 1668 iio_push_event(indio_dev, 1706 1669 IIO_MOD_EVENT_CODE(IIO_STEPS, 0, IIO_NO_MOD, 1707 1670 IIO_EV_TYPE_CHANGE, ··· 1723 1686 } 1724 1687 } 1725 1688 1726 - if (FIELD_GET(BMA400_INT_DRDY_MSK, le16_to_cpu(data->status))) { 1689 + if (FIELD_GET(BMA400_INT_STAT0_DRDY_MASK, le16_to_cpu(data->status))) { 1727 1690 mutex_unlock(&data->mutex); 1728 1691 iio_trigger_poll_nested(data->trig); 1729 1692 return IRQ_HANDLED;
+31
drivers/iio/adc/Kconfig
··· 1020 1020 To compile this driver as a module, choose M here: the module will be 1021 1021 called max1363. 1022 1022 1023 + config MAX14001 1024 + tristate "Analog Devices MAX14001/MAX14002 ADC driver" 1025 + depends on SPI 1026 + help 1027 + Say yes here to build support for Analog Devices MAX14001/MAX14002 1028 + Configurable, Isolated 10-bit ADCs for Multi-Range Binary Inputs. 1029 + 1030 + To compile this driver as a module, choose M here: the module will be 1031 + called max14001. 1032 + 1023 1033 config MAX34408 1024 1034 tristate "Maxim max34408/max344089 ADC driver" 1025 1035 depends on I2C ··· 1412 1402 1413 1403 To compile this driver as a module, choose M here: the 1414 1404 module will be called rzg2l_adc. 1405 + 1406 + config RZN1_ADC 1407 + tristate "Renesas RZ/N1 ADC driver" 1408 + depends on ARCH_RZN1 || COMPILE_TEST 1409 + help 1410 + Say yes here to build support for the ADC found in Renesas 1411 + RZ/N1 family. 1412 + 1413 + To compile this driver as a module, choose M here: the 1414 + module will be called rzn1-adc. 1415 + 1416 + config RZT2H_ADC 1417 + tristate "Renesas RZ/T2H / RZ/N2H ADC driver" 1418 + depends on ARCH_RENESAS || COMPILE_TEST 1419 + select IIO_ADC_HELPER 1420 + help 1421 + Say yes here to build support for the ADC found in Renesas 1422 + RZ/T2H / RZ/N2H SoCs. 1423 + 1424 + To compile this driver as a module, choose M here: the 1425 + module will be called rzt2h_adc. 1415 1426 1416 1427 config SC27XX_ADC 1417 1428 tristate "Spreadtrum SC27xx series PMICs ADC"
+3
drivers/iio/adc/Makefile
··· 89 89 obj-$(CONFIG_MAX11410) += max11410.o 90 90 obj-$(CONFIG_MAX1241) += max1241.o 91 91 obj-$(CONFIG_MAX1363) += max1363.o 92 + obj-$(CONFIG_MAX14001) += max14001.o 92 93 obj-$(CONFIG_MAX34408) += max34408.o 93 94 obj-$(CONFIG_MAX77541_ADC) += max77541-adc.o 94 95 obj-$(CONFIG_MAX9611) += max9611.o ··· 124 123 obj-$(CONFIG_ROHM_BD79124) += rohm-bd79124.o 125 124 obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o 126 125 obj-$(CONFIG_RZG2L_ADC) += rzg2l_adc.o 126 + obj-$(CONFIG_RZN1_ADC) += rzn1-adc.o 127 + obj-$(CONFIG_RZT2H_ADC) += rzt2h_adc.o 127 128 obj-$(CONFIG_SC27XX_ADC) += sc27xx_adc.o 128 129 obj-$(CONFIG_SD_ADC_MODULATOR) += sd_adc_modulator.o 129 130 obj-$(CONFIG_SOPHGO_CV1800B_ADC) += sophgo-cv1800b-adc.o
+2 -2
drivers/iio/adc/ad4030.c
··· 852 852 char *label) 853 853 { 854 854 if (chan->differential) 855 - return sprintf(label, "differential%lu\n", chan->address); 856 - return sprintf(label, "common-mode%lu\n", chan->address); 855 + return sysfs_emit(label, "differential%lu\n", chan->address); 856 + return sysfs_emit(label, "common-mode%lu\n", chan->address); 857 857 } 858 858 859 859 static int ad4030_get_current_scan_type(const struct iio_dev *indio_dev,
+104 -22
drivers/iio/adc/ad4080.c
··· 125 125 126 126 /* Miscellaneous Definitions */ 127 127 #define AD4080_SPI_READ BIT(7) 128 - #define AD4080_CHIP_ID GENMASK(2, 0) 128 + #define AD4080_CHIP_ID 0x0050 129 + #define AD4081_CHIP_ID 0x0051 130 + #define AD4083_CHIP_ID 0x0053 131 + #define AD4084_CHIP_ID 0x0054 132 + #define AD4086_CHIP_ID 0x0056 133 + #define AD4087_CHIP_ID 0x0057 129 134 130 135 #define AD4080_LVDS_CNV_CLK_CNT_MAX 7 131 136 ··· 172 167 const unsigned int (*scale_table)[2]; 173 168 const struct iio_chan_spec *channels; 174 169 unsigned int num_channels; 170 + unsigned int lvds_cnv_clk_cnt_max; 175 171 }; 176 172 177 173 struct ad4080_state { ··· 420 414 { } 421 415 }; 422 416 423 - static const struct iio_chan_spec ad4080_channel = { 424 - .type = IIO_VOLTAGE, 425 - .indexed = 1, 426 - .channel = 0, 427 - .info_mask_separate = BIT(IIO_CHAN_INFO_SCALE), 428 - .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | 429 - BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), 430 - .info_mask_shared_by_all_available = 431 - BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), 432 - .ext_info = ad4080_ext_info, 433 - .scan_index = 0, 434 - .scan_type = { 435 - .sign = 's', 436 - .realbits = 20, 437 - .storagebits = 32, 438 - }, 439 - }; 417 + #define AD4080_CHANNEL_DEFINE(bits, storage) { \ 418 + .type = IIO_VOLTAGE, \ 419 + .indexed = 1, \ 420 + .channel = 0, \ 421 + .info_mask_separate = BIT(IIO_CHAN_INFO_SCALE), \ 422 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ 423 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ 424 + .info_mask_shared_by_all_available = \ 425 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \ 426 + .ext_info = ad4080_ext_info, \ 427 + .scan_index = 0, \ 428 + .scan_type = { \ 429 + .sign = 's', \ 430 + .realbits = (bits), \ 431 + .storagebits = (storage), \ 432 + }, \ 433 + } 434 + 435 + static const struct iio_chan_spec ad4080_channel = AD4080_CHANNEL_DEFINE(20, 32); 436 + 437 + static const struct iio_chan_spec ad4081_channel = AD4080_CHANNEL_DEFINE(20, 32); 438 + 439 + static const struct iio_chan_spec ad4083_channel = AD4080_CHANNEL_DEFINE(16, 16); 440 + 441 + static const struct iio_chan_spec ad4084_channel = AD4080_CHANNEL_DEFINE(16, 16); 442 + 443 + static const struct iio_chan_spec ad4086_channel = AD4080_CHANNEL_DEFINE(14, 16); 444 + 445 + static const struct iio_chan_spec ad4087_channel = AD4080_CHANNEL_DEFINE(14, 16); 440 446 441 447 static const struct ad4080_chip_info ad4080_chip_info = { 442 448 .name = "ad4080", ··· 457 439 .num_scales = ARRAY_SIZE(ad4080_scale_table), 458 440 .num_channels = 1, 459 441 .channels = &ad4080_channel, 442 + .lvds_cnv_clk_cnt_max = AD4080_LVDS_CNV_CLK_CNT_MAX, 443 + }; 444 + 445 + static const struct ad4080_chip_info ad4081_chip_info = { 446 + .name = "ad4081", 447 + .product_id = AD4081_CHIP_ID, 448 + .scale_table = ad4080_scale_table, 449 + .num_scales = ARRAY_SIZE(ad4080_scale_table), 450 + .num_channels = 1, 451 + .channels = &ad4081_channel, 452 + .lvds_cnv_clk_cnt_max = 2, 453 + }; 454 + 455 + static const struct ad4080_chip_info ad4083_chip_info = { 456 + .name = "ad4083", 457 + .product_id = AD4083_CHIP_ID, 458 + .scale_table = ad4080_scale_table, 459 + .num_scales = ARRAY_SIZE(ad4080_scale_table), 460 + .num_channels = 1, 461 + .channels = &ad4083_channel, 462 + .lvds_cnv_clk_cnt_max = 5, 463 + }; 464 + 465 + static const struct ad4080_chip_info ad4084_chip_info = { 466 + .name = "ad4084", 467 + .product_id = AD4084_CHIP_ID, 468 + .scale_table = ad4080_scale_table, 469 + .num_scales = ARRAY_SIZE(ad4080_scale_table), 470 + .num_channels = 1, 471 + .channels = &ad4084_channel, 472 + .lvds_cnv_clk_cnt_max = 2, 473 + }; 474 + 475 + static const struct ad4080_chip_info ad4086_chip_info = { 476 + .name = "ad4086", 477 + .product_id = AD4086_CHIP_ID, 478 + .scale_table = ad4080_scale_table, 479 + .num_scales = ARRAY_SIZE(ad4080_scale_table), 480 + .num_channels = 1, 481 + .channels = &ad4086_channel, 482 + .lvds_cnv_clk_cnt_max = 4, 483 + }; 484 + 485 + static const struct ad4080_chip_info ad4087_chip_info = { 486 + .name = "ad4087", 487 + .product_id = AD4087_CHIP_ID, 488 + .scale_table = ad4080_scale_table, 489 + .num_scales = ARRAY_SIZE(ad4080_scale_table), 490 + .num_channels = 1, 491 + .channels = &ad4087_channel, 492 + .lvds_cnv_clk_cnt_max = 1, 460 493 }; 461 494 462 495 static int ad4080_setup(struct iio_dev *indio_dev) 463 496 { 464 497 struct ad4080_state *st = iio_priv(indio_dev); 465 498 struct device *dev = regmap_get_device(st->regmap); 466 - unsigned int id; 499 + __le16 id_le; 500 + u16 id; 467 501 int ret; 468 502 469 503 ret = regmap_write(st->regmap, AD4080_REG_INTERFACE_CONFIG_A, ··· 528 458 if (ret) 529 459 return ret; 530 460 531 - ret = regmap_read(st->regmap, AD4080_REG_CHIP_TYPE, &id); 461 + ret = regmap_bulk_read(st->regmap, AD4080_REG_PRODUCT_ID_L, &id_le, 462 + sizeof(id_le)); 532 463 if (ret) 533 464 return ret; 534 465 535 - if (id != AD4080_CHIP_ID) 466 + id = le16_to_cpu(id_le); 467 + if (id != st->info->product_id) 536 468 dev_info(dev, "Unrecognized CHIP_ID 0x%X\n", id); 537 469 538 470 ret = regmap_set_bits(st->regmap, AD4080_REG_GPIO_CONFIG_A, ··· 560 488 AD4080_REG_ADC_DATA_INTF_CONFIG_B, 561 489 AD4080_ADC_DATA_INTF_CONFIG_B_LVDS_CNV_CLK_CNT_MSK, 562 490 FIELD_PREP(AD4080_ADC_DATA_INTF_CONFIG_B_LVDS_CNV_CLK_CNT_MSK, 563 - AD4080_LVDS_CNV_CLK_CNT_MAX)); 491 + st->info->lvds_cnv_clk_cnt_max)); 564 492 if (ret) 565 493 return ret; 566 494 ··· 665 593 666 594 static const struct spi_device_id ad4080_id[] = { 667 595 { "ad4080", (kernel_ulong_t)&ad4080_chip_info }, 596 + { "ad4081", (kernel_ulong_t)&ad4081_chip_info }, 597 + { "ad4083", (kernel_ulong_t)&ad4083_chip_info }, 598 + { "ad4084", (kernel_ulong_t)&ad4084_chip_info }, 599 + { "ad4086", (kernel_ulong_t)&ad4086_chip_info }, 600 + { "ad4087", (kernel_ulong_t)&ad4087_chip_info }, 668 601 { } 669 602 }; 670 603 MODULE_DEVICE_TABLE(spi, ad4080_id); 671 604 672 605 static const struct of_device_id ad4080_of_match[] = { 673 606 { .compatible = "adi,ad4080", &ad4080_chip_info }, 607 + { .compatible = "adi,ad4081", &ad4081_chip_info }, 608 + { .compatible = "adi,ad4083", &ad4083_chip_info }, 609 + { .compatible = "adi,ad4084", &ad4084_chip_info }, 610 + { .compatible = "adi,ad4086", &ad4086_chip_info }, 611 + { .compatible = "adi,ad4087", &ad4087_chip_info }, 674 612 { } 675 613 }; 676 614 MODULE_DEVICE_TABLE(of, ad4080_of_match);
+147 -164
drivers/iio/adc/ad7124.c
··· 10 10 #include <linux/cleanup.h> 11 11 #include <linux/clk.h> 12 12 #include <linux/clk-provider.h> 13 + #include <linux/debugfs.h> 13 14 #include <linux/delay.h> 14 15 #include <linux/device.h> 15 16 #include <linux/err.h> ··· 111 110 #define AD7124_FILTER_SINGLE_CYCLE BIT(16) 112 111 #define AD7124_FILTER_FS GENMASK(10, 0) 113 112 113 + #define AD7124_CFG_SLOT_UNASSIGNED ~0U 114 + 114 115 #define AD7124_MAX_CONFIGS 8 115 116 #define AD7124_MAX_CHANNELS 16 116 117 ··· 178 175 }; 179 176 180 177 struct ad7124_channel_config { 181 - bool live; 182 178 unsigned int cfg_slot; 183 179 unsigned int requested_odr; 184 180 unsigned int requested_odr_micro; 185 181 /* 186 182 * Following fields are used to compare for equality. If you 187 183 * make adaptations in it, you most likely also have to adapt 188 - * ad7124_find_similar_live_cfg(), too. 184 + * ad7124_config_equal(), too. 189 185 */ 190 186 struct_group(config_props, 191 187 enum ad7124_ref_sel refsel; ··· 201 199 }; 202 200 203 201 struct ad7124_channel { 204 - unsigned int nr; 205 202 struct ad7124_channel_config cfg; 206 203 unsigned int ain; 207 204 unsigned int slot; ··· 216 215 unsigned int adc_control; 217 216 unsigned int num_channels; 218 217 struct mutex cfgs_lock; /* lock for configs access */ 219 - unsigned long cfg_slots_status; /* bitmap with slot status (1 means it is used) */ 218 + u8 cfg_slot_use_count[AD7124_MAX_CONFIGS]; 220 219 221 220 /* 222 221 * Stores the power-on reset value for the GAIN(x) registers which are 223 222 * needed for measurements at gain 1 (i.e. CONFIG(x).PGA == 0) 224 223 */ 225 224 unsigned int gain_default; 226 - DECLARE_KFIFO(live_cfgs_fifo, struct ad7124_channel_config *, AD7124_MAX_CONFIGS); 225 + bool enable_single_cycle; 227 226 }; 228 227 229 228 static const struct ad7124_chip_info ad7124_4_chip_info = { ··· 367 366 cfg->requested_odr_micro * factor / MICRO; 368 367 odr_sel_bits = clamp(DIV_ROUND_CLOSEST(fclk, divisor), 1, 2047); 369 368 370 - if (odr_sel_bits != st->channels[channel].cfg.odr_sel_bits) 371 - st->channels[channel].cfg.live = false; 372 - 373 369 st->channels[channel].cfg.odr_sel_bits = odr_sel_bits; 374 370 } 375 371 ··· 401 403 } 402 404 } 403 405 404 - static struct ad7124_channel_config *ad7124_find_similar_live_cfg(struct ad7124_state *st, 405 - struct ad7124_channel_config *cfg) 406 - { 407 - struct ad7124_channel_config *cfg_aux; 408 - int i; 409 - 410 - /* 411 - * This is just to make sure that the comparison is adapted after 412 - * struct ad7124_channel_config was changed. 413 - */ 414 - static_assert(sizeof_field(struct ad7124_channel_config, config_props) == 415 - sizeof(struct { 416 - enum ad7124_ref_sel refsel; 417 - bool bipolar; 418 - bool buf_positive; 419 - bool buf_negative; 420 - unsigned int vref_mv; 421 - unsigned int pga_bits; 422 - unsigned int odr_sel_bits; 423 - enum ad7124_filter_type filter_type; 424 - unsigned int calibration_offset; 425 - unsigned int calibration_gain; 426 - })); 427 - 428 - for (i = 0; i < st->num_channels; i++) { 429 - cfg_aux = &st->channels[i].cfg; 430 - 431 - if (cfg_aux->live && 432 - cfg->refsel == cfg_aux->refsel && 433 - cfg->bipolar == cfg_aux->bipolar && 434 - cfg->buf_positive == cfg_aux->buf_positive && 435 - cfg->buf_negative == cfg_aux->buf_negative && 436 - cfg->vref_mv == cfg_aux->vref_mv && 437 - cfg->pga_bits == cfg_aux->pga_bits && 438 - cfg->odr_sel_bits == cfg_aux->odr_sel_bits && 439 - cfg->filter_type == cfg_aux->filter_type && 440 - cfg->calibration_offset == cfg_aux->calibration_offset && 441 - cfg->calibration_gain == cfg_aux->calibration_gain) 442 - return cfg_aux; 443 - } 444 - 445 - return NULL; 446 - } 447 - 448 - static int ad7124_find_free_config_slot(struct ad7124_state *st) 449 - { 450 - unsigned int free_cfg_slot; 451 - 452 - free_cfg_slot = find_first_zero_bit(&st->cfg_slots_status, AD7124_MAX_CONFIGS); 453 - if (free_cfg_slot == AD7124_MAX_CONFIGS) 454 - return -1; 455 - 456 - return free_cfg_slot; 457 - } 458 - 459 406 /* Only called during probe, so dev_err_probe() can be used */ 460 407 static int ad7124_init_config_vref(struct ad7124_state *st, struct ad7124_channel_config *cfg) 461 408 { ··· 429 486 } 430 487 } 431 488 489 + static bool ad7124_config_equal(struct ad7124_channel_config *a, 490 + struct ad7124_channel_config *b) 491 + { 492 + return a->refsel == b->refsel && 493 + a->bipolar == b->bipolar && 494 + a->buf_positive == b->buf_positive && 495 + a->buf_negative == b->buf_negative && 496 + a->vref_mv == b->vref_mv && 497 + a->pga_bits == b->pga_bits && 498 + a->odr_sel_bits == b->odr_sel_bits && 499 + a->filter_type == b->filter_type && 500 + a->calibration_offset == b->calibration_offset && 501 + a->calibration_gain == b->calibration_gain; 502 + } 503 + 432 504 static int ad7124_write_config(struct ad7124_state *st, struct ad7124_channel_config *cfg, 433 505 unsigned int cfg_slot) 434 506 { ··· 452 494 unsigned int post = 0; 453 495 int ret; 454 496 455 - cfg->cfg_slot = cfg_slot; 456 - 457 - ret = ad_sd_write_reg(&st->sd, AD7124_OFFSET(cfg->cfg_slot), 3, cfg->calibration_offset); 497 + ret = ad_sd_write_reg(&st->sd, AD7124_OFFSET(cfg_slot), 3, 498 + cfg->calibration_offset); 458 499 if (ret) 459 500 return ret; 460 501 461 - ret = ad_sd_write_reg(&st->sd, AD7124_GAIN(cfg->cfg_slot), 3, cfg->calibration_gain); 502 + ret = ad_sd_write_reg(&st->sd, AD7124_GAIN(cfg_slot), 3, 503 + cfg->calibration_gain); 462 504 if (ret) 463 505 return ret; 464 506 ··· 468 510 (cfg->buf_negative ? AD7124_CONFIG_AIN_BUFM : 0) | 469 511 FIELD_PREP(AD7124_CONFIG_PGA, cfg->pga_bits); 470 512 471 - ret = ad_sd_write_reg(&st->sd, AD7124_CONFIG(cfg->cfg_slot), 2, val); 513 + ret = ad_sd_write_reg(&st->sd, AD7124_CONFIG(cfg_slot), 2, val); 472 514 if (ret < 0) 473 515 return ret; 474 516 ··· 518 560 * sampling frequency even when only one channel is enabled in a 519 561 * buffered read. If it was not set, the N in ad7124_set_channel_odr() 520 562 * would be 1 and we would get a faster sampling frequency than what 521 - * was requested. 563 + * was requested. It may only be disabled through debugfs for testing 564 + * purposes. 522 565 */ 523 - return ad_sd_write_reg(&st->sd, AD7124_FILTER(cfg->cfg_slot), 3, 566 + return ad_sd_write_reg(&st->sd, AD7124_FILTER(cfg_slot), 3, 524 567 FIELD_PREP(AD7124_FILTER_FILTER, filter) | 525 568 FIELD_PREP(AD7124_FILTER_REJ60, rej60) | 526 569 FIELD_PREP(AD7124_FILTER_POST_FILTER, post) | 527 - AD7124_FILTER_SINGLE_CYCLE | 570 + FIELD_PREP(AD7124_FILTER_SINGLE_CYCLE, 571 + st->enable_single_cycle) | 528 572 FIELD_PREP(AD7124_FILTER_FS, cfg->odr_sel_bits)); 529 573 } 530 574 531 - static struct ad7124_channel_config *ad7124_pop_config(struct ad7124_state *st) 575 + /** 576 + * ad7124_request_config_slot() - Request a config slot for a given config 577 + * @st: Driver instance 578 + * @channel: Channel to request a slot for 579 + * 580 + * Tries to find a matching config already in use, otherwise finds a free 581 + * slot. If this function returns successfully, the use count for the slot is 582 + * increased and the slot number is stored in cfg->cfg_slot. 583 + * 584 + * The slot must be released again with ad7124_release_config_slot() when no 585 + * longer needed. 586 + * 587 + * Returns: 0 if a slot was successfully assigned, -EUSERS if no slot is 588 + * available or other error if SPI communication fails. 589 + */ 590 + static int ad7124_request_config_slot(struct ad7124_state *st, u8 channel) 532 591 { 533 - struct ad7124_channel_config *lru_cfg; 534 - struct ad7124_channel_config *cfg; 535 - int ret; 536 - int i; 592 + unsigned int other, slot; 593 + int last_used_slot = -1; 594 + 595 + /* Find another channel with a matching config, if any. */ 596 + for (other = 0; other < st->num_channels; other++) { 597 + if (other == channel) 598 + continue; 599 + 600 + if (st->channels[other].cfg.cfg_slot == AD7124_CFG_SLOT_UNASSIGNED) 601 + continue; 602 + 603 + last_used_slot = max_t(int, last_used_slot, 604 + st->channels[other].cfg.cfg_slot); 605 + 606 + if (!ad7124_config_equal(&st->channels[other].cfg, 607 + &st->channels[channel].cfg)) 608 + continue; 609 + 610 + /* Found a match, re-use that slot. */ 611 + slot = st->channels[other].cfg.cfg_slot; 612 + st->cfg_slot_use_count[slot]++; 613 + st->channels[channel].cfg.cfg_slot = slot; 614 + 615 + return 0; 616 + } 617 + 618 + /* No match, use next free slot. */ 619 + slot = last_used_slot + 1; 620 + if (slot >= AD7124_MAX_CONFIGS) 621 + return -EUSERS; 622 + 623 + st->cfg_slot_use_count[slot]++; 624 + st->channels[channel].cfg.cfg_slot = slot; 625 + 626 + return ad7124_write_config(st, &st->channels[channel].cfg, slot); 627 + } 628 + 629 + static void ad7124_release_config_slot(struct ad7124_state *st, u8 channel) 630 + { 631 + unsigned int slot; 537 632 538 633 /* 539 - * Pop least recently used config from the fifo 540 - * in order to make room for the new one 634 + * All of these early return conditions can happen at probe when all 635 + * channels are disabled. Otherwise, they should not happen normally. 541 636 */ 542 - ret = kfifo_get(&st->live_cfgs_fifo, &lru_cfg); 543 - if (ret <= 0) 544 - return NULL; 637 + if (channel >= st->num_channels) 638 + return; 545 639 546 - lru_cfg->live = false; 640 + slot = st->channels[channel].cfg.cfg_slot; 547 641 548 - /* mark slot as free */ 549 - assign_bit(lru_cfg->cfg_slot, &st->cfg_slots_status, 0); 642 + if (slot == AD7124_CFG_SLOT_UNASSIGNED || 643 + st->cfg_slot_use_count[slot] == 0) 644 + return; 550 645 551 - /* invalidate all other configs that pointed to this one */ 552 - for (i = 0; i < st->num_channels; i++) { 553 - cfg = &st->channels[i].cfg; 554 - 555 - if (cfg->cfg_slot == lru_cfg->cfg_slot) 556 - cfg->live = false; 557 - } 558 - 559 - return lru_cfg; 560 - } 561 - 562 - static int ad7124_push_config(struct ad7124_state *st, struct ad7124_channel_config *cfg) 563 - { 564 - struct ad7124_channel_config *lru_cfg; 565 - int free_cfg_slot; 566 - 567 - free_cfg_slot = ad7124_find_free_config_slot(st); 568 - if (free_cfg_slot >= 0) { 569 - /* push the new config in configs queue */ 570 - kfifo_put(&st->live_cfgs_fifo, cfg); 571 - } else { 572 - /* pop one config to make room for the new one */ 573 - lru_cfg = ad7124_pop_config(st); 574 - if (!lru_cfg) 575 - return -EINVAL; 576 - 577 - /* push the new config in configs queue */ 578 - free_cfg_slot = lru_cfg->cfg_slot; 579 - kfifo_put(&st->live_cfgs_fifo, cfg); 580 - } 581 - 582 - /* mark slot as used */ 583 - assign_bit(free_cfg_slot, &st->cfg_slots_status, 1); 584 - 585 - return ad7124_write_config(st, cfg, free_cfg_slot); 586 - } 587 - 588 - static int ad7124_enable_channel(struct ad7124_state *st, struct ad7124_channel *ch) 589 - { 590 - ch->cfg.live = true; 591 - return ad_sd_write_reg(&st->sd, AD7124_CHANNEL(ch->nr), 2, ch->ain | 592 - FIELD_PREP(AD7124_CHANNEL_SETUP, ch->cfg.cfg_slot) | 593 - AD7124_CHANNEL_ENABLE); 646 + st->cfg_slot_use_count[slot]--; 647 + st->channels[channel].cfg.cfg_slot = AD7124_CFG_SLOT_UNASSIGNED; 594 648 } 595 649 596 650 static int ad7124_prepare_read(struct ad7124_state *st, int address) 597 651 { 598 652 struct ad7124_channel_config *cfg = &st->channels[address].cfg; 599 - struct ad7124_channel_config *live_cfg; 653 + int ret; 600 654 601 - /* 602 - * Before doing any reads assign the channel a configuration. 603 - * Check if channel's config is on the device 604 - */ 605 - if (!cfg->live) { 606 - /* check if config matches another one */ 607 - live_cfg = ad7124_find_similar_live_cfg(st, cfg); 608 - if (!live_cfg) 609 - ad7124_push_config(st, cfg); 610 - else 611 - cfg->cfg_slot = live_cfg->cfg_slot; 612 - } 655 + ret = ad7124_request_config_slot(st, address); 656 + if (ret) 657 + return ret; 613 658 614 659 /* point channel to the config slot and enable */ 615 - return ad7124_enable_channel(st, &st->channels[address]); 616 - } 617 - 618 - static int __ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int channel) 619 - { 620 - struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); 621 - 622 - return ad7124_prepare_read(st, channel); 660 + return ad_sd_write_reg(&st->sd, AD7124_CHANNEL(address), 2, 661 + st->channels[address].ain | 662 + FIELD_PREP(AD7124_CHANNEL_SETUP, cfg->cfg_slot) | 663 + AD7124_CHANNEL_ENABLE); 623 664 } 624 665 625 666 static int ad7124_set_channel(struct ad_sigma_delta *sd, unsigned int channel) ··· 627 670 int ret; 628 671 629 672 mutex_lock(&st->cfgs_lock); 630 - ret = __ad7124_set_channel(sd, channel); 673 + ret = ad7124_prepare_read(st, channel); 631 674 mutex_unlock(&st->cfgs_lock); 632 675 633 676 return ret; ··· 657 700 { 658 701 struct ad7124_state *st = container_of(sd, struct ad7124_state, sd); 659 702 703 + ad7124_release_config_slot(st, chan); 704 + 660 705 /* The relevant thing here is that AD7124_CHANNEL_ENABLE is cleared. */ 661 706 return ad_sd_write_reg(&st->sd, AD7124_CHANNEL(chan), 2, 0); 662 707 } ··· 668 709 int ret; 669 710 int i; 670 711 671 - for (i = 0; i < 16; i++) { 712 + for (i = 0; i < AD7124_MAX_CHANNELS; i++) { 672 713 ret = ad7124_disable_one(sd, i); 673 714 if (ret < 0) 674 715 return ret; ··· 880 921 gain = DIV_ROUND_CLOSEST(res, val2); 881 922 res = ad7124_find_closest_match(ad7124_gain, ARRAY_SIZE(ad7124_gain), gain); 882 923 883 - if (st->channels[chan->address].cfg.pga_bits != res) 884 - st->channels[chan->address].cfg.live = false; 885 - 886 924 st->channels[chan->address].cfg.pga_bits = res; 887 925 return 0; 888 926 default: ··· 921 965 for (i = 0; i < st->num_channels; i++) { 922 966 bit_set = test_bit(i, scan_mask); 923 967 if (bit_set) 924 - ret = __ad7124_set_channel(&st->sd, i); 968 + ret = ad7124_prepare_read(st, i); 925 969 else 926 970 ret = ad7124_spi_write_mask(st, AD7124_CHANNEL(i), AD7124_CHANNEL_ENABLE, 927 971 0, 2); ··· 1022 1066 if (ret < 0) 1023 1067 return ret; 1024 1068 1025 - ret = ad_sd_read_reg(&st->sd, AD7124_OFFSET(ch->cfg.cfg_slot), 3, 1069 + /* 1070 + * Making the assumption that a single conversion will always 1071 + * use configuration slot 0 for the OFFSET/GAIN registers. 1072 + */ 1073 + ret = ad_sd_read_reg(&st->sd, AD7124_OFFSET(0), 3, 1026 1074 &ch->cfg.calibration_offset); 1027 1075 if (ret < 0) 1028 1076 return ret; ··· 1041 1081 if (ret < 0) 1042 1082 return ret; 1043 1083 1044 - ret = ad_sd_read_reg(&st->sd, AD7124_GAIN(ch->cfg.cfg_slot), 3, 1084 + ret = ad_sd_read_reg(&st->sd, AD7124_GAIN(0), 3, 1045 1085 &ch->cfg.calibration_gain); 1046 1086 if (ret < 0) 1047 1087 return ret; ··· 1132 1172 1133 1173 guard(mutex)(&st->cfgs_lock); 1134 1174 1135 - cfg->live = false; 1136 1175 cfg->filter_type = value; 1137 1176 ad7124_set_channel_odr(st, chan->address); 1138 1177 ··· 1264 1305 return dev_err_probe(dev, -EINVAL, 1265 1306 "diff-channels property of %pfwP contains invalid data\n", child); 1266 1307 1267 - st->channels[channel].nr = channel; 1268 1308 st->channels[channel].ain = FIELD_PREP(AD7124_CHANNEL_AINP, ain[0]) | 1269 1309 FIELD_PREP(AD7124_CHANNEL_AINM, ain[1]); 1270 1310 ··· 1290 1332 1291 1333 if (num_channels < AD7124_MAX_CHANNELS) { 1292 1334 st->channels[num_channels] = (struct ad7124_channel) { 1293 - .nr = num_channels, 1294 1335 .ain = FIELD_PREP(AD7124_CHANNEL_AINP, AD7124_CHANNEL_AINx_TEMPSENSOR) | 1295 1336 FIELD_PREP(AD7124_CHANNEL_AINM, AD7124_CHANNEL_AINx_AVSS), 1296 1337 .cfg = { ··· 1315 1358 }, 1316 1359 .address = num_channels, 1317 1360 .scan_index = num_channels, 1361 + .ext_info = ad7124_calibsys_ext_info, 1318 1362 }; 1319 1363 } 1320 1364 ··· 1447 1489 st->adc_control &= ~AD7124_ADC_CONTROL_MODE; 1448 1490 st->adc_control |= FIELD_PREP(AD7124_ADC_CONTROL_MODE, AD_SD_MODE_IDLE); 1449 1491 1450 - mutex_init(&st->cfgs_lock); 1451 - INIT_KFIFO(st->live_cfgs_fifo); 1492 + ret = devm_mutex_init(dev, &st->cfgs_lock); 1493 + if (ret) 1494 + return ret; 1495 + 1452 1496 for (i = 0; i < st->num_channels; i++) { 1453 1497 struct ad7124_channel_config *cfg = &st->channels[i].cfg; 1454 1498 1455 1499 ret = ad7124_init_config_vref(st, cfg); 1456 1500 if (ret < 0) 1457 1501 return ret; 1502 + 1503 + cfg->cfg_slot = AD7124_CFG_SLOT_UNASSIGNED; 1458 1504 1459 1505 /* Default filter type on the ADC after reset. */ 1460 1506 cfg->filter_type = AD7124_FILTER_TYPE_SINC4; ··· 1517 1555 * after full-scale calibration because the next 1518 1556 * ad_sd_calibrate() call overwrites this via 1519 1557 * ad_sigma_delta_set_channel() -> ad7124_set_channel() 1520 - * ... -> ad7124_enable_channel(). 1558 + * -> ad7124_prepare_read(). 1521 1559 */ 1522 - ret = ad_sd_read_reg(&st->sd, AD7124_GAIN(st->channels[i].cfg.cfg_slot), 3, 1560 + ret = ad_sd_read_reg(&st->sd, AD7124_GAIN(0), 3, 1523 1561 &st->channels[i].cfg.calibration_gain); 1524 1562 if (ret < 0) 1525 1563 return ret; ··· 1529 1567 if (ret < 0) 1530 1568 return ret; 1531 1569 1532 - ret = ad_sd_read_reg(&st->sd, AD7124_OFFSET(st->channels[i].cfg.cfg_slot), 3, 1570 + /* 1571 + * Making the assumption that a single conversion will always 1572 + * use configuration slot 0 for the OFFSET/GAIN registers. 1573 + */ 1574 + ret = ad_sd_read_reg(&st->sd, AD7124_OFFSET(0), 3, 1533 1575 &st->channels[i].cfg.calibration_offset); 1534 1576 if (ret < 0) 1535 1577 return ret; ··· 1575 1609 regulator_disable(r); 1576 1610 } 1577 1611 1612 + static void ad7124_debugfs_init(struct iio_dev *indio_dev) 1613 + { 1614 + struct dentry *dentry = iio_get_debugfs_dentry(indio_dev); 1615 + struct ad7124_state *st = iio_priv(indio_dev); 1616 + 1617 + if (!IS_ENABLED(CONFIG_DEBUG_FS)) 1618 + return; 1619 + 1620 + debugfs_create_bool("enable_single_cycle", 0644, dentry, 1621 + &st->enable_single_cycle); 1622 + } 1623 + 1578 1624 static int ad7124_probe(struct spi_device *spi) 1579 1625 { 1580 1626 const struct ad7124_chip_info *info; ··· 1606 1628 st = iio_priv(indio_dev); 1607 1629 1608 1630 st->chip_info = info; 1631 + 1632 + /* Only disabled for debug/testing purposes. */ 1633 + st->enable_single_cycle = true; 1609 1634 1610 1635 indio_dev->name = st->chip_info->name; 1611 1636 indio_dev->modes = INDIO_DIRECT_MODE; ··· 1666 1685 ret = devm_iio_device_register(&spi->dev, indio_dev); 1667 1686 if (ret < 0) 1668 1687 return dev_err_probe(dev, ret, "Failed to register iio device\n"); 1688 + 1689 + ad7124_debugfs_init(indio_dev); 1669 1690 1670 1691 return 0; 1671 1692 }
+1 -1
drivers/iio/adc/ad7768-1.c
··· 899 899 { 900 900 struct ad7768_state *st = iio_priv(indio_dev); 901 901 902 - return sprintf(label, "%s\n", st->labels[chan->channel]); 902 + return sysfs_emit(label, "%s\n", st->labels[chan->channel]); 903 903 } 904 904 905 905 static int ad7768_get_current_scan_type(const struct iio_dev *indio_dev,
+1 -1
drivers/iio/adc/ade9000.c
··· 1629 1629 .val_bits = 32, 1630 1630 .max_register = 0x6bc, 1631 1631 .zero_flag_mask = true, 1632 - .cache_type = REGCACHE_RBTREE, 1632 + .cache_type = REGCACHE_MAPLE, 1633 1633 .reg_read = ade9000_spi_read_reg, 1634 1634 .reg_write = ade9000_spi_write_reg, 1635 1635 .volatile_reg = ade9000_is_volatile_reg,
+34
drivers/iio/adc/aspeed_adc.c
··· 645 645 .field = GENMASK(7, 4), 646 646 }; 647 647 648 + static const struct aspeed_adc_trim_locate ast2700_adc0_trim = { 649 + .offset = 0x820, 650 + .field = GENMASK(3, 0), 651 + }; 652 + 653 + static const struct aspeed_adc_trim_locate ast2700_adc1_trim = { 654 + .offset = 0x820, 655 + .field = GENMASK(7, 4), 656 + }; 657 + 648 658 static const struct aspeed_adc_model_data ast2400_model_data = { 649 659 .model_name = "ast2400-adc", 650 660 .vref_fixed_mv = 2500, ··· 699 689 .trim_locate = &ast2600_adc1_trim, 700 690 }; 701 691 692 + static const struct aspeed_adc_model_data ast2700_adc0_model_data = { 693 + .model_name = "ast2700-adc0", 694 + .min_sampling_rate = 10000, 695 + .max_sampling_rate = 500000, 696 + .wait_init_sequence = true, 697 + .bat_sense_sup = true, 698 + .scaler_bit_width = 16, 699 + .num_channels = 8, 700 + .trim_locate = &ast2700_adc0_trim, 701 + }; 702 + 703 + static const struct aspeed_adc_model_data ast2700_adc1_model_data = { 704 + .model_name = "ast2700-adc1", 705 + .min_sampling_rate = 10000, 706 + .max_sampling_rate = 500000, 707 + .wait_init_sequence = true, 708 + .bat_sense_sup = true, 709 + .scaler_bit_width = 16, 710 + .num_channels = 8, 711 + .trim_locate = &ast2700_adc1_trim, 712 + }; 713 + 702 714 static const struct of_device_id aspeed_adc_matches[] = { 703 715 { .compatible = "aspeed,ast2400-adc", .data = &ast2400_model_data }, 704 716 { .compatible = "aspeed,ast2500-adc", .data = &ast2500_model_data }, 705 717 { .compatible = "aspeed,ast2600-adc0", .data = &ast2600_adc0_model_data }, 706 718 { .compatible = "aspeed,ast2600-adc1", .data = &ast2600_adc1_model_data }, 719 + { .compatible = "aspeed,ast2700-adc0", .data = &ast2700_adc0_model_data }, 720 + { .compatible = "aspeed,ast2700-adc1", .data = &ast2700_adc1_model_data }, 707 721 { } 708 722 }; 709 723 MODULE_DEVICE_TABLE(of, aspeed_adc_matches);
+391
drivers/iio/adc/max14001.c
··· 1 + // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2 + /* 3 + * Analog Devices MAX14001/MAX14002 ADC driver 4 + * 5 + * Copyright (C) 2023-2025 Analog Devices Inc. 6 + * Copyright (C) 2023 Kim Seer Paller <kimseer.paller@analog.com> 7 + * Copyright (c) 2025 Marilene Andrade Garcia <marilene.agarcia@gmail.com> 8 + * 9 + * Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX14001-MAX14002.pdf 10 + */ 11 + 12 + #include <linux/array_size.h> 13 + #include <linux/bitfield.h> 14 + #include <linux/bitrev.h> 15 + #include <linux/bits.h> 16 + #include <linux/cleanup.h> 17 + #include <linux/device.h> 18 + #include <linux/mod_devicetable.h> 19 + #include <linux/module.h> 20 + #include <linux/regmap.h> 21 + #include <linux/regulator/consumer.h> 22 + #include <linux/spi/spi.h> 23 + #include <linux/types.h> 24 + #include <linux/units.h> 25 + #include <asm/byteorder.h> 26 + 27 + #include <linux/iio/iio.h> 28 + #include <linux/iio/types.h> 29 + 30 + /* MAX14001 Registers Address */ 31 + #define MAX14001_REG_ADC 0x00 32 + #define MAX14001_REG_FADC 0x01 33 + #define MAX14001_REG_FLAGS 0x02 34 + #define MAX14001_REG_FLTEN 0x03 35 + #define MAX14001_REG_THL 0x04 36 + #define MAX14001_REG_THU 0x05 37 + #define MAX14001_REG_INRR 0x06 38 + #define MAX14001_REG_INRT 0x07 39 + #define MAX14001_REG_INRP 0x08 40 + #define MAX14001_REG_CFG 0x09 41 + #define MAX14001_REG_ENBL 0x0A 42 + #define MAX14001_REG_ACT 0x0B 43 + #define MAX14001_REG_WEN 0x0C 44 + 45 + #define MAX14001_REG_VERIFICATION(x) ((x) + 0x10) 46 + 47 + #define MAX14001_REG_CFG_BIT_EXRF BIT(5) 48 + 49 + #define MAX14001_REG_WEN_VALUE_WRITE 0x294 50 + 51 + #define MAX14001_MASK_ADDR GENMASK(15, 11) 52 + #define MAX14001_MASK_WR BIT(10) 53 + #define MAX14001_MASK_DATA GENMASK(9, 0) 54 + 55 + struct max14001_state { 56 + const struct max14001_chip_info *chip_info; 57 + struct spi_device *spi; 58 + struct regmap *regmap; 59 + int vref_mV; 60 + bool spi_hw_has_lsb_first; 61 + 62 + /* 63 + * The following buffers will be bit-reversed during device 64 + * communication, because the device transmits and receives data 65 + * LSB-first. 66 + * DMA (thus cache coherency maintenance) requires the transfer 67 + * buffers to live in their own cache lines. 68 + */ 69 + union { 70 + __be16 be; 71 + __le16 le; 72 + } spi_tx_buffer __aligned(IIO_DMA_MINALIGN); 73 + 74 + union { 75 + __be16 be; 76 + __le16 le; 77 + } spi_rx_buffer; 78 + }; 79 + 80 + struct max14001_chip_info { 81 + const char *name; 82 + }; 83 + 84 + static int max14001_read(void *context, unsigned int reg, unsigned int *val) 85 + { 86 + struct max14001_state *st = context; 87 + struct spi_transfer xfers[] = { 88 + { 89 + .tx_buf = &st->spi_tx_buffer, 90 + .len = sizeof(st->spi_tx_buffer), 91 + .cs_change = 1, 92 + }, { 93 + .rx_buf = &st->spi_rx_buffer, 94 + .len = sizeof(st->spi_rx_buffer), 95 + }, 96 + }; 97 + int ret; 98 + unsigned int addr, data; 99 + 100 + /* 101 + * Prepare SPI transmit buffer 16 bit-value and reverse bit order 102 + * to align with the LSB-first input on SDI port in order to meet 103 + * the device communication requirements. If the controller supports 104 + * SPI_LSB_FIRST, this step will be handled by the SPI controller. 105 + */ 106 + addr = FIELD_PREP(MAX14001_MASK_ADDR, reg); 107 + 108 + if (st->spi_hw_has_lsb_first) 109 + st->spi_tx_buffer.le = cpu_to_le16(addr); 110 + else 111 + st->spi_tx_buffer.be = cpu_to_be16(bitrev16(addr)); 112 + 113 + ret = spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); 114 + if (ret) 115 + return ret; 116 + 117 + /* 118 + * Convert received 16-bit value to cpu-endian format and reverse 119 + * bit order. If the controller supports SPI_LSB_FIRST, this step 120 + * will be handled by the SPI controller. 121 + */ 122 + if (st->spi_hw_has_lsb_first) 123 + data = le16_to_cpu(st->spi_rx_buffer.le); 124 + else 125 + data = bitrev16(be16_to_cpu(st->spi_rx_buffer.be)); 126 + 127 + *val = FIELD_GET(MAX14001_MASK_DATA, data); 128 + 129 + return 0; 130 + } 131 + 132 + static int max14001_write(struct max14001_state *st, unsigned int reg, unsigned int val) 133 + { 134 + unsigned int addr; 135 + 136 + /* 137 + * Prepare SPI transmit buffer 16 bit-value and reverse bit order 138 + * to align with the LSB-first input on SDI port in order to meet 139 + * the device communication requirements. If the controller supports 140 + * SPI_LSB_FIRST, this step will be handled by the SPI controller. 141 + */ 142 + addr = FIELD_PREP(MAX14001_MASK_ADDR, reg) | 143 + FIELD_PREP(MAX14001_MASK_WR, 1) | 144 + FIELD_PREP(MAX14001_MASK_DATA, val); 145 + 146 + if (st->spi_hw_has_lsb_first) 147 + st->spi_tx_buffer.le = cpu_to_le16(addr); 148 + else 149 + st->spi_tx_buffer.be = cpu_to_be16(bitrev16(addr)); 150 + 151 + return spi_write(st->spi, &st->spi_tx_buffer, sizeof(st->spi_tx_buffer)); 152 + } 153 + 154 + static int max14001_write_single_reg(void *context, unsigned int reg, unsigned int val) 155 + { 156 + struct max14001_state *st = context; 157 + int ret; 158 + 159 + /* Enable writing to the SPI register. */ 160 + ret = max14001_write(st, MAX14001_REG_WEN, MAX14001_REG_WEN_VALUE_WRITE); 161 + if (ret) 162 + return ret; 163 + 164 + /* Writing data into SPI register. */ 165 + ret = max14001_write(st, reg, val); 166 + if (ret) 167 + return ret; 168 + 169 + /* Disable writing to the SPI register. */ 170 + return max14001_write(st, MAX14001_REG_WEN, 0); 171 + } 172 + 173 + static int max14001_write_verification_reg(struct max14001_state *st, unsigned int reg) 174 + { 175 + unsigned int val; 176 + int ret; 177 + 178 + ret = regmap_read(st->regmap, reg, &val); 179 + if (ret) 180 + return ret; 181 + 182 + return max14001_write(st, MAX14001_REG_VERIFICATION(reg), val); 183 + } 184 + 185 + static int max14001_disable_mv_fault(struct max14001_state *st) 186 + { 187 + unsigned int reg; 188 + int ret; 189 + 190 + /* Enable writing to the SPI registers. */ 191 + ret = max14001_write(st, MAX14001_REG_WEN, MAX14001_REG_WEN_VALUE_WRITE); 192 + if (ret) 193 + return ret; 194 + 195 + /* 196 + * Reads all registers and writes the values to their appropriate 197 + * verification registers to clear the Memory Validation fault. 198 + */ 199 + for (reg = MAX14001_REG_FLTEN; reg <= MAX14001_REG_ENBL; reg++) { 200 + ret = max14001_write_verification_reg(st, reg); 201 + if (ret) 202 + return ret; 203 + } 204 + 205 + /* Disable writing to the SPI registers. */ 206 + return max14001_write(st, MAX14001_REG_WEN, 0); 207 + } 208 + 209 + static int max14001_debugfs_reg_access(struct iio_dev *indio_dev, 210 + unsigned int reg, unsigned int writeval, 211 + unsigned int *readval) 212 + { 213 + struct max14001_state *st = iio_priv(indio_dev); 214 + 215 + if (readval) 216 + return regmap_read(st->regmap, reg, readval); 217 + 218 + return regmap_write(st->regmap, reg, writeval); 219 + } 220 + 221 + static int max14001_read_raw(struct iio_dev *indio_dev, 222 + struct iio_chan_spec const *chan, 223 + int *val, int *val2, long mask) 224 + { 225 + struct max14001_state *st = iio_priv(indio_dev); 226 + int ret; 227 + 228 + switch (mask) { 229 + case IIO_CHAN_INFO_RAW: 230 + ret = regmap_read(st->regmap, MAX14001_REG_ADC, val); 231 + if (ret) 232 + return ret; 233 + 234 + return IIO_VAL_INT; 235 + case IIO_CHAN_INFO_SCALE: 236 + *val = st->vref_mV; 237 + *val2 = 10; 238 + 239 + return IIO_VAL_FRACTIONAL_LOG2; 240 + default: 241 + return -EINVAL; 242 + } 243 + } 244 + 245 + static const struct regmap_range max14001_regmap_rd_range[] = { 246 + regmap_reg_range(MAX14001_REG_ADC, MAX14001_REG_ENBL), 247 + regmap_reg_range(MAX14001_REG_WEN, MAX14001_REG_WEN), 248 + regmap_reg_range(MAX14001_REG_VERIFICATION(MAX14001_REG_FLTEN), 249 + MAX14001_REG_VERIFICATION(MAX14001_REG_ENBL)), 250 + }; 251 + 252 + static const struct regmap_access_table max14001_regmap_rd_table = { 253 + .yes_ranges = max14001_regmap_rd_range, 254 + .n_yes_ranges = ARRAY_SIZE(max14001_regmap_rd_range), 255 + }; 256 + 257 + static const struct regmap_range max14001_regmap_wr_range[] = { 258 + regmap_reg_range(MAX14001_REG_FLTEN, MAX14001_REG_WEN), 259 + regmap_reg_range(MAX14001_REG_VERIFICATION(MAX14001_REG_FLTEN), 260 + MAX14001_REG_VERIFICATION(MAX14001_REG_ENBL)), 261 + }; 262 + 263 + static const struct regmap_access_table max14001_regmap_wr_table = { 264 + .yes_ranges = max14001_regmap_wr_range, 265 + .n_yes_ranges = ARRAY_SIZE(max14001_regmap_wr_range), 266 + }; 267 + 268 + static const struct regmap_config max14001_regmap_config = { 269 + .reg_read = max14001_read, 270 + .reg_write = max14001_write_single_reg, 271 + .max_register = MAX14001_REG_VERIFICATION(MAX14001_REG_ENBL), 272 + .rd_table = &max14001_regmap_rd_table, 273 + .wr_table = &max14001_regmap_wr_table, 274 + }; 275 + 276 + static const struct iio_info max14001_info = { 277 + .read_raw = max14001_read_raw, 278 + .debugfs_reg_access = max14001_debugfs_reg_access, 279 + }; 280 + 281 + static const struct iio_chan_spec max14001_channel[] = { 282 + { 283 + .type = IIO_VOLTAGE, 284 + .indexed = 1, 285 + .channel = 0, 286 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 287 + BIT(IIO_CHAN_INFO_SCALE), 288 + }, 289 + }; 290 + 291 + static int max14001_probe(struct spi_device *spi) 292 + { 293 + struct device *dev = &spi->dev; 294 + struct iio_dev *indio_dev; 295 + struct max14001_state *st; 296 + int ret; 297 + bool use_ext_vrefin = false; 298 + 299 + indio_dev = devm_iio_device_alloc(dev, sizeof(*st)); 300 + if (!indio_dev) 301 + return -ENOMEM; 302 + 303 + st = iio_priv(indio_dev); 304 + st->spi = spi; 305 + st->spi_hw_has_lsb_first = spi->mode & SPI_LSB_FIRST; 306 + st->chip_info = spi_get_device_match_data(spi); 307 + if (!st->chip_info) 308 + return -EINVAL; 309 + 310 + indio_dev->name = st->chip_info->name; 311 + indio_dev->info = &max14001_info; 312 + indio_dev->channels = max14001_channel; 313 + indio_dev->num_channels = ARRAY_SIZE(max14001_channel); 314 + indio_dev->modes = INDIO_DIRECT_MODE; 315 + 316 + st->regmap = devm_regmap_init(dev, NULL, st, &max14001_regmap_config); 317 + if (IS_ERR(st->regmap)) 318 + return dev_err_probe(dev, PTR_ERR(st->regmap), "Failed to initialize regmap\n"); 319 + 320 + ret = devm_regulator_get_enable(dev, "vdd"); 321 + if (ret) 322 + return dev_err_probe(dev, ret, "Failed to enable Vdd supply\n"); 323 + 324 + ret = devm_regulator_get_enable(dev, "vddl"); 325 + if (ret) 326 + return dev_err_probe(dev, ret, "Failed to enable Vddl supply\n"); 327 + 328 + ret = devm_regulator_get_enable_read_voltage(dev, "refin"); 329 + if (ret < 0 && ret != -ENODEV) 330 + return dev_err_probe(dev, ret, "Failed to get REFIN voltage\n"); 331 + 332 + if (ret == -ENODEV) 333 + ret = 1250000; 334 + else 335 + use_ext_vrefin = true; 336 + st->vref_mV = ret / (MICRO / MILLI); 337 + 338 + if (use_ext_vrefin) { 339 + /* 340 + * Configure the MAX14001/MAX14002 to use an external voltage 341 + * reference source by setting the bit 5 of the configuration register. 342 + */ 343 + ret = regmap_set_bits(st->regmap, MAX14001_REG_CFG, 344 + MAX14001_REG_CFG_BIT_EXRF); 345 + if (ret) 346 + return dev_err_probe(dev, ret, 347 + "Failed to set External REFIN in Configuration Register\n"); 348 + } 349 + 350 + ret = max14001_disable_mv_fault(st); 351 + if (ret) 352 + return dev_err_probe(dev, ret, "Failed to disable MV Fault\n"); 353 + 354 + return devm_iio_device_register(dev, indio_dev); 355 + } 356 + 357 + static struct max14001_chip_info max14001_chip_info = { 358 + .name = "max14001", 359 + }; 360 + 361 + static struct max14001_chip_info max14002_chip_info = { 362 + .name = "max14002", 363 + }; 364 + 365 + static const struct spi_device_id max14001_id_table[] = { 366 + { "max14001", (kernel_ulong_t)&max14001_chip_info }, 367 + { "max14002", (kernel_ulong_t)&max14002_chip_info }, 368 + { } 369 + }; 370 + 371 + static const struct of_device_id max14001_of_match[] = { 372 + { .compatible = "adi,max14001", .data = &max14001_chip_info }, 373 + { .compatible = "adi,max14002", .data = &max14002_chip_info }, 374 + { } 375 + }; 376 + MODULE_DEVICE_TABLE(of, max14001_of_match); 377 + 378 + static struct spi_driver max14001_driver = { 379 + .driver = { 380 + .name = "max14001", 381 + .of_match_table = max14001_of_match, 382 + }, 383 + .probe = max14001_probe, 384 + .id_table = max14001_id_table, 385 + }; 386 + module_spi_driver(max14001_driver); 387 + 388 + MODULE_AUTHOR("Kim Seer Paller <kimseer.paller@analog.com>"); 389 + MODULE_AUTHOR("Marilene Andrade Garcia <marilene.agarcia@gmail.com>"); 390 + MODULE_DESCRIPTION("Analog Devices MAX14001/MAX14002 ADCs driver"); 391 + MODULE_LICENSE("GPL");
+1 -1
drivers/iio/adc/mcp3564.c
··· 987 987 { 988 988 struct mcp3564_state *adc = iio_priv(indio_dev); 989 989 990 - return sprintf(label, "%s\n", adc->labels[chan->scan_index]); 990 + return sysfs_emit(label, "%s\n", adc->labels[chan->scan_index]); 991 991 } 992 992 993 993 static int mcp3564_parse_fw_children(struct iio_dev *indio_dev)
+3 -3
drivers/iio/adc/meson_saradc.c
··· 1181 1181 char *label) 1182 1182 { 1183 1183 if (chan->type == IIO_TEMP) 1184 - return sprintf(label, "temp-sensor\n"); 1184 + return sysfs_emit(label, "temp-sensor\n"); 1185 1185 if (chan->type == IIO_VOLTAGE && chan->channel >= NUM_MUX_0_VSS) 1186 - return sprintf(label, "%s\n", 1186 + return sysfs_emit(label, "%s\n", 1187 1187 chan7_mux_names[chan->channel - NUM_MUX_0_VSS]); 1188 1188 if (chan->type == IIO_VOLTAGE) 1189 - return sprintf(label, "channel-%d\n", chan->channel); 1189 + return sysfs_emit(label, "channel-%d\n", chan->channel); 1190 1190 return 0; 1191 1191 } 1192 1192
+1 -1
drivers/iio/adc/mt6360-adc.c
··· 216 216 static int mt6360_adc_read_label(struct iio_dev *iio_dev, const struct iio_chan_spec *chan, 217 217 char *label) 218 218 { 219 - return snprintf(label, PAGE_SIZE, "%s\n", mt6360_channel_labels[chan->channel]); 219 + return sysfs_emit(label, "%s\n", mt6360_channel_labels[chan->channel]); 220 220 } 221 221 222 222 static const struct iio_info mt6360_adc_iio_info = {
+4 -4
drivers/iio/adc/pac1921.c
··· 672 672 { 673 673 switch (chan->channel) { 674 674 case PAC1921_CHAN_VBUS: 675 - return sprintf(label, "vbus\n"); 675 + return sysfs_emit(label, "vbus\n"); 676 676 case PAC1921_CHAN_VSENSE: 677 - return sprintf(label, "vsense\n"); 677 + return sysfs_emit(label, "vsense\n"); 678 678 case PAC1921_CHAN_CURRENT: 679 - return sprintf(label, "current\n"); 679 + return sysfs_emit(label, "current\n"); 680 680 case PAC1921_CHAN_POWER: 681 - return sprintf(label, "power\n"); 681 + return sysfs_emit(label, "power\n"); 682 682 default: 683 683 return -EINVAL; 684 684 }
+1 -1
drivers/iio/adc/pac1934.c
··· 768 768 * Re-schedule the work for the read registers on timeout 769 769 * (to prevent chip registers saturation) 770 770 */ 771 - mod_delayed_work(system_wq, &info->work_chip_rfsh, 771 + mod_delayed_work(system_percpu_wq, &info->work_chip_rfsh, 772 772 msecs_to_jiffies(PAC1934_MAX_RFSH_LIMIT_MS)); 773 773 } 774 774
+1 -1
drivers/iio/adc/qcom-spmi-rradc.c
··· 769 769 static int rradc_read_label(struct iio_dev *indio_dev, 770 770 struct iio_chan_spec const *chan, char *label) 771 771 { 772 - return snprintf(label, PAGE_SIZE, "%s\n", 772 + return sysfs_emit(label, "%s\n", 773 773 rradc_chans[chan->address].label); 774 774 } 775 775
+4 -9
drivers/iio/adc/rohm-bd79112.c
··· 168 168 #define GET_GPI_VAL_REG(offset) _get_gpio_reg((offset), BD79112_REG_GPI_VALUE_A0_A7) 169 169 170 170 static const struct regmap_range bd71815_volatile_ro_ranges[] = { 171 - { 172 - /* Read ADC data */ 173 - .range_min = BD79112_REG_AGIO0A, 174 - .range_max = BD79112_REG_AGIO15B, 175 - }, { 176 - /* GPI state */ 177 - .range_min = BD79112_REG_GPI_VALUE_B8_15, 178 - .range_max = BD79112_REG_GPI_VALUE_A0_A7, 179 - }, 171 + /* Read ADC data */ 172 + regmap_reg_range(BD79112_REG_AGIO0A, BD79112_REG_AGIO15B), 173 + /* GPI state */ 174 + regmap_reg_range(BD79112_REG_GPI_VALUE_B8_15, BD79112_REG_GPI_VALUE_A0_A7), 180 175 }; 181 176 182 177 static const struct regmap_access_table bd79112_volatile_regs = {
+9 -30
drivers/iio/adc/rohm-bd79124.c
··· 126 126 }; 127 127 128 128 static const struct regmap_range bd79124_ro_ranges[] = { 129 - { 130 - .range_min = BD79124_REG_EVENT_FLAG, 131 - .range_max = BD79124_REG_EVENT_FLAG, 132 - }, { 133 - .range_min = BD79124_REG_RECENT_CH0_LSB, 134 - .range_max = BD79124_REG_RECENT_CH7_MSB, 135 - }, 129 + regmap_reg_range(BD79124_REG_EVENT_FLAG, BD79124_REG_EVENT_FLAG), 130 + regmap_reg_range(BD79124_REG_RECENT_CH0_LSB, BD79124_REG_RECENT_CH7_MSB), 136 131 }; 137 132 138 133 static const struct regmap_access_table bd79124_ro_regs = { ··· 136 141 }; 137 142 138 143 static const struct regmap_range bd79124_volatile_ranges[] = { 139 - { 140 - .range_min = BD79124_REG_RECENT_CH0_LSB, 141 - .range_max = BD79124_REG_RECENT_CH7_MSB, 142 - }, { 143 - .range_min = BD79124_REG_EVENT_FLAG, 144 - .range_max = BD79124_REG_EVENT_FLAG, 145 - }, { 146 - .range_min = BD79124_REG_EVENT_FLAG_HI, 147 - .range_max = BD79124_REG_EVENT_FLAG_HI, 148 - }, { 149 - .range_min = BD79124_REG_EVENT_FLAG_LO, 150 - .range_max = BD79124_REG_EVENT_FLAG_LO, 151 - }, { 152 - .range_min = BD79124_REG_SYSTEM_STATUS, 153 - .range_max = BD79124_REG_SYSTEM_STATUS, 154 - }, 144 + regmap_reg_range(BD79124_REG_RECENT_CH0_LSB, BD79124_REG_RECENT_CH7_MSB), 145 + regmap_reg_range(BD79124_REG_EVENT_FLAG, BD79124_REG_EVENT_FLAG), 146 + regmap_reg_range(BD79124_REG_EVENT_FLAG_HI, BD79124_REG_EVENT_FLAG_HI), 147 + regmap_reg_range(BD79124_REG_EVENT_FLAG_LO, BD79124_REG_EVENT_FLAG_LO), 148 + regmap_reg_range(BD79124_REG_SYSTEM_STATUS, BD79124_REG_SYSTEM_STATUS), 155 149 }; 156 150 157 151 static const struct regmap_access_table bd79124_volatile_regs = { ··· 149 165 }; 150 166 151 167 static const struct regmap_range bd79124_precious_ranges[] = { 152 - { 153 - .range_min = BD79124_REG_EVENT_FLAG_HI, 154 - .range_max = BD79124_REG_EVENT_FLAG_HI, 155 - }, { 156 - .range_min = BD79124_REG_EVENT_FLAG_LO, 157 - .range_max = BD79124_REG_EVENT_FLAG_LO, 158 - }, 168 + regmap_reg_range(BD79124_REG_EVENT_FLAG_HI, BD79124_REG_EVENT_FLAG_HI), 169 + regmap_reg_range(BD79124_REG_EVENT_FLAG_LO, BD79124_REG_EVENT_FLAG_LO), 159 170 }; 160 171 161 172 static const struct regmap_access_table bd79124_precious_regs = {
+490
drivers/iio/adc/rzn1-adc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Renesas RZ/N1 ADC driver 4 + * 5 + * Copyright (C) 2025 Schneider-Electric 6 + * 7 + * Author: Herve Codina <herve.codina@bootlin.com> 8 + * 9 + * The RZ/N1 ADC controller can handle channels from its internal ADC1 and/or 10 + * ADC2 cores. The driver use ADC1 and/or ADC2 cores depending on the presence 11 + * of the related power supplies (AVDD and VREF) description in the device-tree. 12 + */ 13 + 14 + #include <linux/array_size.h> 15 + #include <linux/bitfield.h> 16 + #include <linux/bits.h> 17 + #include <linux/cleanup.h> 18 + #include <linux/clk.h> 19 + #include <linux/dev_printk.h> 20 + #include <linux/err.h> 21 + #include <linux/iio/iio.h> 22 + #include <linux/io.h> 23 + #include <linux/iopoll.h> 24 + #include <linux/mod_devicetable.h> 25 + #include <linux/module.h> 26 + #include <linux/mutex.h> 27 + #include <linux/platform_device.h> 28 + #include <linux/pm_runtime.h> 29 + #include <linux/regulator/consumer.h> 30 + #include <linux/types.h> 31 + 32 + #define RZN1_ADC_CONTROL_REG 0x02c 33 + #define RZN1_ADC_CONTROL_ADC_BUSY BIT(6) 34 + 35 + #define RZN1_ADC_FORCE_REG 0x030 36 + #define RZN1_ADC_SET_FORCE_REG 0x034 37 + #define RZN1_ADC_CLEAR_FORCE_REG 0x038 38 + #define RZN1_ADC_FORCE_VC(_n) BIT(_n) 39 + 40 + #define RZN1_ADC_CONFIG_REG 0x040 41 + #define RZN1_ADC_CONFIG_ADC_POWER_DOWN BIT(3) 42 + 43 + #define RZN1_ADC_VC_REG(_n) (0x0c0 + 4 * (_n)) 44 + #define RZN1_ADC_VC_ADC2_ENABLE BIT(16) 45 + #define RZN1_ADC_VC_ADC1_ENABLE BIT(15) 46 + #define RZN1_ADC_VC_ADC2_CHANNEL_SEL_MASK GENMASK(5, 3) 47 + #define RZN1_ADC_VC_ADC1_CHANNEL_SEL_MASK GENMASK(2, 0) 48 + 49 + #define RZN1_ADC_ADC1_DATA_REG(_n) (0x100 + 4 * (_n)) 50 + #define RZN1_ADC_ADC2_DATA_REG(_n) (0x140 + 4 * (_n)) 51 + #define RZN1_ADC_ADCX_DATA_DATA_MASK GENMASK(11, 0) 52 + 53 + #define RZN1_ADC_NO_CHANNEL -1 54 + 55 + #define RZN1_ADC_CHANNEL_SHARED_SCALE(_ch, _ds_name) { \ 56 + .type = IIO_VOLTAGE, \ 57 + .indexed = 1, \ 58 + .channel = (_ch), \ 59 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 60 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 61 + .datasheet_name = (_ds_name), \ 62 + } 63 + 64 + #define RZN1_ADC_CHANNEL_SEPARATED_SCALE(_ch, _ds_name) { \ 65 + .type = IIO_VOLTAGE, \ 66 + .indexed = 1, \ 67 + .channel = (_ch), \ 68 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 69 + BIT(IIO_CHAN_INFO_SCALE), \ 70 + .datasheet_name = (_ds_name), \ 71 + } 72 + 73 + /* 74 + * 8 ADC1_IN signals existed numbered 0..4, 6..8 75 + * ADCx_IN5 doesn't exist in RZ/N1 datasheet 76 + */ 77 + static struct iio_chan_spec rzn1_adc1_channels[] = { 78 + RZN1_ADC_CHANNEL_SHARED_SCALE(0, "ADC1_IN0"), 79 + RZN1_ADC_CHANNEL_SHARED_SCALE(1, "ADC1_IN1"), 80 + RZN1_ADC_CHANNEL_SHARED_SCALE(2, "ADC1_IN2"), 81 + RZN1_ADC_CHANNEL_SHARED_SCALE(3, "ADC1_IN3"), 82 + RZN1_ADC_CHANNEL_SHARED_SCALE(4, "ADC1_IN4"), 83 + RZN1_ADC_CHANNEL_SHARED_SCALE(5, "ADC1_IN6"), 84 + RZN1_ADC_CHANNEL_SHARED_SCALE(6, "ADC1_IN7"), 85 + RZN1_ADC_CHANNEL_SHARED_SCALE(7, "ADC1_IN8"), 86 + }; 87 + 88 + static struct iio_chan_spec rzn1_adc2_channels[] = { 89 + RZN1_ADC_CHANNEL_SHARED_SCALE(8, "ADC2_IN0"), 90 + RZN1_ADC_CHANNEL_SHARED_SCALE(9, "ADC2_IN1"), 91 + RZN1_ADC_CHANNEL_SHARED_SCALE(10, "ADC2_IN2"), 92 + RZN1_ADC_CHANNEL_SHARED_SCALE(11, "ADC2_IN3"), 93 + RZN1_ADC_CHANNEL_SHARED_SCALE(12, "ADC2_IN4"), 94 + RZN1_ADC_CHANNEL_SHARED_SCALE(13, "ADC2_IN6"), 95 + RZN1_ADC_CHANNEL_SHARED_SCALE(14, "ADC2_IN7"), 96 + RZN1_ADC_CHANNEL_SHARED_SCALE(15, "ADC2_IN8"), 97 + }; 98 + 99 + /* 100 + * If both ADCs core are used, scale cannot be common. Indeed, scale is 101 + * based on Vref connected on each ADC core. 102 + */ 103 + static struct iio_chan_spec rzn1_adc1_adc2_channels[] = { 104 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(0, "ADC1_IN0"), 105 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(1, "ADC1_IN1"), 106 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(2, "ADC1_IN2"), 107 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(3, "ADC1_IN3"), 108 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(4, "ADC1_IN4"), 109 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(5, "ADC1_IN6"), 110 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(6, "ADC1_IN7"), 111 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(7, "ADC1_IN8"), 112 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(8, "ADC2_IN0"), 113 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(9, "ADC2_IN1"), 114 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(10, "ADC2_IN2"), 115 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(11, "ADC2_IN3"), 116 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(12, "ADC2_IN4"), 117 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(13, "ADC2_IN6"), 118 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(14, "ADC2_IN7"), 119 + RZN1_ADC_CHANNEL_SEPARATED_SCALE(15, "ADC2_IN8"), 120 + }; 121 + 122 + struct rzn1_adc { 123 + struct device *dev; 124 + void __iomem *regs; 125 + struct mutex lock; /* ADC lock */ 126 + int adc1_vref_mV; /* ADC1 Vref in mV. Negative if ADC1 is not used */ 127 + int adc2_vref_mV; /* ADC2 Vref in mV. Negative if ADC2 is not used */ 128 + }; 129 + 130 + static int rzn1_adc_power(struct rzn1_adc *rzn1_adc, bool power) 131 + { 132 + u32 v; 133 + 134 + writel(power ? 0 : RZN1_ADC_CONFIG_ADC_POWER_DOWN, 135 + rzn1_adc->regs + RZN1_ADC_CONFIG_REG); 136 + 137 + /* Wait for the ADC_BUSY to clear */ 138 + return readl_poll_timeout_atomic(rzn1_adc->regs + RZN1_ADC_CONTROL_REG, 139 + v, !(v & RZN1_ADC_CONTROL_ADC_BUSY), 140 + 0, 500); 141 + } 142 + 143 + static void rzn1_adc_vc_setup_conversion(struct rzn1_adc *rzn1_adc, u32 ch, 144 + int adc1_ch, int adc2_ch) 145 + { 146 + u32 vc = 0; 147 + 148 + if (adc1_ch != RZN1_ADC_NO_CHANNEL) 149 + vc |= RZN1_ADC_VC_ADC1_ENABLE | 150 + FIELD_PREP(RZN1_ADC_VC_ADC1_CHANNEL_SEL_MASK, adc1_ch); 151 + 152 + if (adc2_ch != RZN1_ADC_NO_CHANNEL) 153 + vc |= RZN1_ADC_VC_ADC2_ENABLE | 154 + FIELD_PREP(RZN1_ADC_VC_ADC2_CHANNEL_SEL_MASK, adc2_ch); 155 + 156 + writel(vc, rzn1_adc->regs + RZN1_ADC_VC_REG(ch)); 157 + } 158 + 159 + static int rzn1_adc_vc_start_conversion(struct rzn1_adc *rzn1_adc, u32 ch) 160 + { 161 + u32 val; 162 + 163 + val = readl(rzn1_adc->regs + RZN1_ADC_FORCE_REG); 164 + if (val & RZN1_ADC_FORCE_VC(ch)) 165 + return -EBUSY; 166 + 167 + writel(RZN1_ADC_FORCE_VC(ch), rzn1_adc->regs + RZN1_ADC_SET_FORCE_REG); 168 + 169 + return 0; 170 + } 171 + 172 + static void rzn1_adc_vc_stop_conversion(struct rzn1_adc *rzn1_adc, u32 ch) 173 + { 174 + writel(RZN1_ADC_FORCE_VC(ch), rzn1_adc->regs + RZN1_ADC_CLEAR_FORCE_REG); 175 + } 176 + 177 + static int rzn1_adc_vc_wait_conversion(struct rzn1_adc *rzn1_adc, u32 ch, 178 + u32 *adc1_data, u32 *adc2_data) 179 + { 180 + u32 data_reg; 181 + int ret; 182 + u32 v; 183 + 184 + /* 185 + * When a VC is selected, it needs 20 ADC clocks to perform the 186 + * conversion. 187 + * 188 + * The worst case is when the 16 VCs need to perform a conversion and 189 + * our VC is the lowest in term of priority. 190 + * 191 + * In that case, the conversion is performed in 16 * 20 ADC clocks. 192 + * 193 + * The ADC clock can be set from 4MHz to 20MHz. This leads to a worst 194 + * case of 16 * 20 * 1/4Mhz = 80us. 195 + * 196 + * Round it up to 100us. 197 + */ 198 + 199 + /* Wait for the ADC_FORCE_VC(n) to clear */ 200 + ret = readl_poll_timeout_atomic(rzn1_adc->regs + RZN1_ADC_FORCE_REG, 201 + v, !(v & RZN1_ADC_FORCE_VC(ch)), 202 + 0, 100); 203 + if (ret) 204 + return ret; 205 + 206 + if (adc1_data) { 207 + data_reg = readl(rzn1_adc->regs + RZN1_ADC_ADC1_DATA_REG(ch)); 208 + *adc1_data = FIELD_GET(RZN1_ADC_ADCX_DATA_DATA_MASK, data_reg); 209 + } 210 + 211 + if (adc2_data) { 212 + data_reg = readl(rzn1_adc->regs + RZN1_ADC_ADC2_DATA_REG(ch)); 213 + *adc2_data = FIELD_GET(RZN1_ADC_ADCX_DATA_DATA_MASK, data_reg); 214 + } 215 + 216 + return 0; 217 + } 218 + 219 + static int rzn1_adc_read_raw_ch(struct rzn1_adc *rzn1_adc, unsigned int chan, int *val) 220 + { 221 + u32 *adc1_data, *adc2_data; 222 + int adc1_ch, adc2_ch; 223 + u32 adc_data; 224 + int ret; 225 + 226 + /* 227 + * IIO chan are decoupled from chans used in rzn1_adc_vc_*() functions. 228 + * The RZ/N1 ADC VC controller can handle on a single VC chan one 229 + * channel from the ADC1 core and one channel from the ADC2 core. 230 + * 231 + * Even if IIO chans are mapped 1:1 to ADC core chans and so uses only 232 + * a chan from ADC1 or a chan from ADC2, future improvements can define 233 + * an IIO chan that uses one chan from ADC1 and one chan from ADC2. 234 + */ 235 + 236 + if (chan < 8) { 237 + /* chan 0..7 used to get ADC1 ch 0..7 */ 238 + adc1_ch = chan; 239 + adc1_data = &adc_data; 240 + adc2_ch = RZN1_ADC_NO_CHANNEL; 241 + adc2_data = NULL; 242 + } else if (chan < 16) { 243 + /* chan 8..15 used to get ADC2 ch 0..7 */ 244 + adc1_ch = RZN1_ADC_NO_CHANNEL; 245 + adc1_data = NULL; 246 + adc2_ch = chan - 8; 247 + adc2_data = &adc_data; 248 + } else { 249 + return -EINVAL; 250 + } 251 + 252 + ACQUIRE(pm_runtime_active_auto_try_enabled, pm)(rzn1_adc->dev); 253 + ret = ACQUIRE_ERR(pm_runtime_active_auto_try_enabled, &pm); 254 + if (ret < 0) 255 + return ret; 256 + 257 + scoped_guard(mutex, &rzn1_adc->lock) { 258 + rzn1_adc_vc_setup_conversion(rzn1_adc, chan, adc1_ch, adc2_ch); 259 + 260 + ret = rzn1_adc_vc_start_conversion(rzn1_adc, chan); 261 + if (ret) 262 + return ret; 263 + 264 + ret = rzn1_adc_vc_wait_conversion(rzn1_adc, chan, adc1_data, adc2_data); 265 + if (ret) { 266 + rzn1_adc_vc_stop_conversion(rzn1_adc, chan); 267 + return ret; 268 + } 269 + } 270 + 271 + *val = adc_data; 272 + ret = IIO_VAL_INT; 273 + 274 + return 0; 275 + } 276 + 277 + static int rzn1_adc_get_vref_mV(struct rzn1_adc *rzn1_adc, unsigned int chan) 278 + { 279 + /* chan 0..7 use ADC1 ch 0..7. Vref related to ADC1 core */ 280 + if (chan < 8) 281 + return rzn1_adc->adc1_vref_mV; 282 + 283 + /* chan 8..15 use ADC2 ch 0..7. Vref related to ADC2 core */ 284 + if (chan < 16) 285 + return rzn1_adc->adc2_vref_mV; 286 + 287 + return -EINVAL; 288 + } 289 + 290 + static int rzn1_adc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, 291 + int *val, int *val2, long mask) 292 + { 293 + struct rzn1_adc *rzn1_adc = iio_priv(indio_dev); 294 + int ret; 295 + 296 + switch (mask) { 297 + case IIO_CHAN_INFO_RAW: 298 + ret = rzn1_adc_read_raw_ch(rzn1_adc, chan->channel, val); 299 + if (ret) 300 + return ret; 301 + return IIO_VAL_INT; 302 + 303 + case IIO_CHAN_INFO_SCALE: 304 + ret = rzn1_adc_get_vref_mV(rzn1_adc, chan->channel); 305 + if (ret < 0) 306 + return ret; 307 + *val = ret; 308 + *val2 = 12; 309 + return IIO_VAL_FRACTIONAL_LOG2; 310 + 311 + default: 312 + return -EINVAL; 313 + } 314 + } 315 + 316 + static const struct iio_info rzn1_adc_info = { 317 + .read_raw = &rzn1_adc_read_raw, 318 + }; 319 + 320 + static int rzn1_adc_set_iio_dev_channels(struct rzn1_adc *rzn1_adc, 321 + struct iio_dev *indio_dev) 322 + { 323 + /* 324 + * When an ADC core is not used, its related vref_mV is set to a 325 + * negative error code. Use the correct IIO channels table based on 326 + * those vref_mV values. 327 + */ 328 + if (rzn1_adc->adc1_vref_mV >= 0) { 329 + if (rzn1_adc->adc2_vref_mV >= 0) { 330 + indio_dev->channels = rzn1_adc1_adc2_channels; 331 + indio_dev->num_channels = ARRAY_SIZE(rzn1_adc1_adc2_channels); 332 + } else { 333 + indio_dev->channels = rzn1_adc1_channels; 334 + indio_dev->num_channels = ARRAY_SIZE(rzn1_adc1_channels); 335 + } 336 + return 0; 337 + } 338 + 339 + if (rzn1_adc->adc2_vref_mV >= 0) { 340 + indio_dev->channels = rzn1_adc2_channels; 341 + indio_dev->num_channels = ARRAY_SIZE(rzn1_adc2_channels); 342 + return 0; 343 + } 344 + 345 + return dev_err_probe(rzn1_adc->dev, -ENODEV, 346 + "Failed to set IIO channels, no ADC core used\n"); 347 + } 348 + 349 + static int rzn1_adc_core_get_regulators(struct rzn1_adc *rzn1_adc, 350 + int *adc_vref_mV, 351 + const char *avdd_name, const char *vref_name) 352 + { 353 + struct device *dev = rzn1_adc->dev; 354 + int ret; 355 + 356 + /* 357 + * For a given ADC core (ADC1 or ADC2), both regulators (AVDD and VREF) 358 + * must be available in order to have the ADC core used. 359 + * 360 + * We use the regulators presence to check the usage of the related 361 + * ADC core. If both regulators are available, the ADC core is used. 362 + * Otherwise, the ADC core is not used. 363 + * 364 + * The adc_vref_mV value is set to a negative error code (-ENODEV) when 365 + * the ADC core is not used. Otherwise it is set to the VRef mV value. 366 + */ 367 + 368 + *adc_vref_mV = -ENODEV; 369 + 370 + ret = devm_regulator_get_enable_optional(dev, avdd_name); 371 + if (ret == -ENODEV) 372 + return 0; 373 + if (ret < 0) 374 + return dev_err_probe(dev, ret, "Failed to get '%s' regulator\n", 375 + avdd_name); 376 + 377 + ret = devm_regulator_get_enable_read_voltage(dev, vref_name); 378 + if (ret == -ENODEV) 379 + return 0; 380 + if (ret < 0) 381 + return dev_err_probe(dev, ret, "Failed to get '%s' regulator\n", 382 + vref_name); 383 + 384 + /* 385 + * Both regulators are available. 386 + * Set adc_vref_mV to the Vref value in mV. This, as the value set is 387 + * positive, also signals that the ADC is used. 388 + */ 389 + *adc_vref_mV = ret / 1000; 390 + 391 + return 0; 392 + } 393 + 394 + static int rzn1_adc_probe(struct platform_device *pdev) 395 + { 396 + struct device *dev = &pdev->dev; 397 + struct iio_dev *indio_dev; 398 + struct rzn1_adc *rzn1_adc; 399 + struct clk *clk; 400 + int ret; 401 + 402 + indio_dev = devm_iio_device_alloc(dev, sizeof(*rzn1_adc)); 403 + if (!indio_dev) 404 + return -ENOMEM; 405 + 406 + rzn1_adc = iio_priv(indio_dev); 407 + rzn1_adc->dev = dev; 408 + 409 + ret = devm_mutex_init(dev, &rzn1_adc->lock); 410 + if (ret) 411 + return ret; 412 + 413 + rzn1_adc->regs = devm_platform_ioremap_resource(pdev, 0); 414 + if (IS_ERR(rzn1_adc->regs)) 415 + return PTR_ERR(rzn1_adc->regs); 416 + 417 + clk = devm_clk_get_enabled(dev, "pclk"); 418 + if (IS_ERR(clk)) 419 + return dev_err_probe(dev, PTR_ERR(clk), "Failed to get pclk\n"); 420 + 421 + clk = devm_clk_get_enabled(dev, "adc"); 422 + if (IS_ERR(clk)) 423 + return dev_err_probe(dev, PTR_ERR(clk), "Failed to get adc clk\n"); 424 + 425 + ret = rzn1_adc_core_get_regulators(rzn1_adc, &rzn1_adc->adc1_vref_mV, 426 + "adc1-avdd", "adc1-vref"); 427 + if (ret) 428 + return ret; 429 + 430 + ret = rzn1_adc_core_get_regulators(rzn1_adc, &rzn1_adc->adc2_vref_mV, 431 + "adc2-avdd", "adc2-vref"); 432 + if (ret) 433 + return ret; 434 + 435 + platform_set_drvdata(pdev, rzn1_adc); 436 + 437 + indio_dev->name = "rzn1-adc"; 438 + indio_dev->info = &rzn1_adc_info; 439 + indio_dev->modes = INDIO_DIRECT_MODE; 440 + ret = rzn1_adc_set_iio_dev_channels(rzn1_adc, indio_dev); 441 + if (ret) 442 + return ret; 443 + 444 + pm_runtime_set_autosuspend_delay(dev, 500); 445 + pm_runtime_use_autosuspend(dev); 446 + ret = devm_pm_runtime_enable(dev); 447 + if (ret) 448 + return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); 449 + 450 + return devm_iio_device_register(dev, indio_dev); 451 + } 452 + 453 + static int rzn1_adc_pm_runtime_suspend(struct device *dev) 454 + { 455 + struct rzn1_adc *rzn1_adc = dev_get_drvdata(dev); 456 + 457 + return rzn1_adc_power(rzn1_adc, false); 458 + } 459 + 460 + static int rzn1_adc_pm_runtime_resume(struct device *dev) 461 + { 462 + struct rzn1_adc *rzn1_adc = dev_get_drvdata(dev); 463 + 464 + return rzn1_adc_power(rzn1_adc, true); 465 + } 466 + 467 + static DEFINE_RUNTIME_DEV_PM_OPS(rzn1_adc_pm_ops, 468 + rzn1_adc_pm_runtime_suspend, 469 + rzn1_adc_pm_runtime_resume, 470 + NULL); 471 + 472 + static const struct of_device_id rzn1_adc_of_match[] = { 473 + { .compatible = "renesas,rzn1-adc" }, 474 + { } 475 + }; 476 + MODULE_DEVICE_TABLE(of, rzn1_adc_of_match); 477 + 478 + static struct platform_driver rzn1_adc_driver = { 479 + .probe = rzn1_adc_probe, 480 + .driver = { 481 + .name = "rzn1-adc", 482 + .of_match_table = rzn1_adc_of_match, 483 + .pm = pm_ptr(&rzn1_adc_pm_ops), 484 + }, 485 + }; 486 + module_platform_driver(rzn1_adc_driver); 487 + 488 + MODULE_AUTHOR("Herve Codina <herve.codina@bootlin.com>"); 489 + MODULE_DESCRIPTION("Renesas RZ/N1 ADC Driver"); 490 + MODULE_LICENSE("GPL");
+304
drivers/iio/adc/rzt2h_adc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + 3 + #include <linux/bitfield.h> 4 + #include <linux/cleanup.h> 5 + #include <linux/completion.h> 6 + #include <linux/delay.h> 7 + #include <linux/iio/adc-helpers.h> 8 + #include <linux/iio/iio.h> 9 + #include <linux/interrupt.h> 10 + #include <linux/io.h> 11 + #include <linux/iopoll.h> 12 + #include <linux/mod_devicetable.h> 13 + #include <linux/module.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/pm_runtime.h> 16 + #include <linux/property.h> 17 + 18 + #define RZT2H_ADCSR_REG 0x00 19 + #define RZT2H_ADCSR_ADIE_MASK BIT(12) 20 + #define RZT2H_ADCSR_ADCS_MASK GENMASK(14, 13) 21 + #define RZT2H_ADCSR_ADCS_SINGLE 0b00 22 + #define RZT2H_ADCSR_ADST_MASK BIT(15) 23 + 24 + #define RZT2H_ADANSA0_REG 0x04 25 + #define RZT2H_ADANSA0_CH_MASK(x) BIT(x) 26 + 27 + #define RZT2H_ADDR_REG(x) (0x20 + 0x2 * (x)) 28 + 29 + #define RZT2H_ADCALCTL_REG 0x1f0 30 + #define RZT2H_ADCALCTL_CAL_MASK BIT(0) 31 + #define RZT2H_ADCALCTL_CAL_RDY_MASK BIT(1) 32 + #define RZT2H_ADCALCTL_CAL_ERR_MASK BIT(2) 33 + 34 + #define RZT2H_ADC_MAX_CHANNELS 16 35 + 36 + struct rzt2h_adc { 37 + void __iomem *base; 38 + struct device *dev; 39 + 40 + struct completion completion; 41 + /* lock to protect against multiple access to the device */ 42 + struct mutex lock; 43 + 44 + const struct iio_chan_spec *channels; 45 + unsigned int num_channels; 46 + unsigned int max_channels; 47 + }; 48 + 49 + static void rzt2h_adc_start(struct rzt2h_adc *adc, unsigned int conversion_type) 50 + { 51 + u16 reg; 52 + 53 + reg = readw(adc->base + RZT2H_ADCSR_REG); 54 + 55 + /* Set conversion type */ 56 + FIELD_MODIFY(RZT2H_ADCSR_ADCS_MASK, &reg, conversion_type); 57 + 58 + /* Set end of conversion interrupt and start bit. */ 59 + reg |= RZT2H_ADCSR_ADIE_MASK | RZT2H_ADCSR_ADST_MASK; 60 + 61 + writew(reg, adc->base + RZT2H_ADCSR_REG); 62 + } 63 + 64 + static void rzt2h_adc_stop(struct rzt2h_adc *adc) 65 + { 66 + u16 reg; 67 + 68 + reg = readw(adc->base + RZT2H_ADCSR_REG); 69 + 70 + /* Clear end of conversion interrupt and start bit. */ 71 + reg &= ~(RZT2H_ADCSR_ADIE_MASK | RZT2H_ADCSR_ADST_MASK); 72 + 73 + writew(reg, adc->base + RZT2H_ADCSR_REG); 74 + } 75 + 76 + static int rzt2h_adc_read_single(struct rzt2h_adc *adc, unsigned int ch, int *val) 77 + { 78 + int ret; 79 + 80 + ret = pm_runtime_resume_and_get(adc->dev); 81 + if (ret) 82 + return ret; 83 + 84 + mutex_lock(&adc->lock); 85 + 86 + reinit_completion(&adc->completion); 87 + 88 + /* Enable a single channel */ 89 + writew(RZT2H_ADANSA0_CH_MASK(ch), adc->base + RZT2H_ADANSA0_REG); 90 + 91 + rzt2h_adc_start(adc, RZT2H_ADCSR_ADCS_SINGLE); 92 + 93 + /* 94 + * Datasheet Page 2770, Table 41.1: 95 + * 0.32us per channel when sample-and-hold circuits are not in use. 96 + */ 97 + ret = wait_for_completion_timeout(&adc->completion, usecs_to_jiffies(1)); 98 + if (!ret) { 99 + ret = -ETIMEDOUT; 100 + goto disable; 101 + } 102 + 103 + *val = readw(adc->base + RZT2H_ADDR_REG(ch)); 104 + ret = IIO_VAL_INT; 105 + 106 + disable: 107 + rzt2h_adc_stop(adc); 108 + 109 + mutex_unlock(&adc->lock); 110 + 111 + pm_runtime_put_autosuspend(adc->dev); 112 + 113 + return ret; 114 + } 115 + 116 + static void rzt2h_adc_set_cal(struct rzt2h_adc *adc, bool cal) 117 + { 118 + u16 val; 119 + 120 + val = readw(adc->base + RZT2H_ADCALCTL_REG); 121 + if (cal) 122 + val |= RZT2H_ADCALCTL_CAL_MASK; 123 + else 124 + val &= ~RZT2H_ADCALCTL_CAL_MASK; 125 + 126 + writew(val, adc->base + RZT2H_ADCALCTL_REG); 127 + } 128 + 129 + static int rzt2h_adc_calibrate(struct rzt2h_adc *adc) 130 + { 131 + u16 val; 132 + int ret; 133 + 134 + rzt2h_adc_set_cal(adc, true); 135 + 136 + ret = read_poll_timeout(readw, val, val & RZT2H_ADCALCTL_CAL_RDY_MASK, 137 + 200, 1000, true, adc->base + RZT2H_ADCALCTL_REG); 138 + if (ret) { 139 + dev_err(adc->dev, "Calibration timed out: %d\n", ret); 140 + return ret; 141 + } 142 + 143 + rzt2h_adc_set_cal(adc, false); 144 + 145 + if (val & RZT2H_ADCALCTL_CAL_ERR_MASK) { 146 + dev_err(adc->dev, "Calibration failed\n"); 147 + return -EINVAL; 148 + } 149 + 150 + return 0; 151 + } 152 + 153 + static int rzt2h_adc_read_raw(struct iio_dev *indio_dev, 154 + struct iio_chan_spec const *chan, 155 + int *val, int *val2, long mask) 156 + { 157 + struct rzt2h_adc *adc = iio_priv(indio_dev); 158 + 159 + switch (mask) { 160 + case IIO_CHAN_INFO_RAW: 161 + return rzt2h_adc_read_single(adc, chan->channel, val); 162 + case IIO_CHAN_INFO_SCALE: 163 + *val = 1800; 164 + *val2 = 12; 165 + return IIO_VAL_FRACTIONAL_LOG2; 166 + default: 167 + return -EINVAL; 168 + } 169 + } 170 + 171 + static const struct iio_info rzt2h_adc_iio_info = { 172 + .read_raw = rzt2h_adc_read_raw, 173 + }; 174 + 175 + static irqreturn_t rzt2h_adc_isr(int irq, void *private) 176 + { 177 + struct rzt2h_adc *adc = private; 178 + 179 + complete(&adc->completion); 180 + 181 + return IRQ_HANDLED; 182 + } 183 + 184 + static const struct iio_chan_spec rzt2h_adc_chan_template = { 185 + .indexed = 1, 186 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 187 + BIT(IIO_CHAN_INFO_SCALE), 188 + .type = IIO_VOLTAGE, 189 + }; 190 + 191 + static int rzt2h_adc_parse_properties(struct rzt2h_adc *adc) 192 + { 193 + struct iio_chan_spec *chan_array; 194 + unsigned int i; 195 + int ret; 196 + 197 + ret = devm_iio_adc_device_alloc_chaninfo_se(adc->dev, 198 + &rzt2h_adc_chan_template, 199 + RZT2H_ADC_MAX_CHANNELS - 1, 200 + &chan_array); 201 + if (ret < 0) 202 + return dev_err_probe(adc->dev, ret, "Failed to read channel info"); 203 + 204 + adc->num_channels = ret; 205 + adc->channels = chan_array; 206 + 207 + for (i = 0; i < adc->num_channels; i++) 208 + if (chan_array[i].channel + 1 > adc->max_channels) 209 + adc->max_channels = chan_array[i].channel + 1; 210 + 211 + return 0; 212 + } 213 + 214 + static int rzt2h_adc_probe(struct platform_device *pdev) 215 + { 216 + struct device *dev = &pdev->dev; 217 + struct iio_dev *indio_dev; 218 + struct rzt2h_adc *adc; 219 + int ret, irq; 220 + 221 + indio_dev = devm_iio_device_alloc(dev, sizeof(*adc)); 222 + if (!indio_dev) 223 + return -ENOMEM; 224 + 225 + adc = iio_priv(indio_dev); 226 + adc->dev = dev; 227 + init_completion(&adc->completion); 228 + 229 + ret = devm_mutex_init(dev, &adc->lock); 230 + if (ret) 231 + return ret; 232 + 233 + platform_set_drvdata(pdev, adc); 234 + 235 + ret = rzt2h_adc_parse_properties(adc); 236 + if (ret) 237 + return ret; 238 + 239 + adc->base = devm_platform_ioremap_resource(pdev, 0); 240 + if (IS_ERR(adc->base)) 241 + return PTR_ERR(adc->base); 242 + 243 + pm_runtime_set_autosuspend_delay(dev, 300); 244 + pm_runtime_use_autosuspend(dev); 245 + ret = devm_pm_runtime_enable(dev); 246 + if (ret) 247 + return ret; 248 + 249 + irq = platform_get_irq_byname(pdev, "adi"); 250 + if (irq < 0) 251 + return irq; 252 + 253 + ret = devm_request_irq(dev, irq, rzt2h_adc_isr, 0, dev_name(dev), adc); 254 + if (ret) 255 + return ret; 256 + 257 + indio_dev->name = "rzt2h-adc"; 258 + indio_dev->info = &rzt2h_adc_iio_info; 259 + indio_dev->modes = INDIO_DIRECT_MODE; 260 + indio_dev->channels = adc->channels; 261 + indio_dev->num_channels = adc->num_channels; 262 + 263 + return devm_iio_device_register(dev, indio_dev); 264 + } 265 + 266 + static const struct of_device_id rzt2h_adc_match[] = { 267 + { .compatible = "renesas,r9a09g077-adc" }, 268 + { } 269 + }; 270 + MODULE_DEVICE_TABLE(of, rzt2h_adc_match); 271 + 272 + static int rzt2h_adc_pm_runtime_resume(struct device *dev) 273 + { 274 + struct rzt2h_adc *adc = dev_get_drvdata(dev); 275 + 276 + /* 277 + * Datasheet Page 2810, Section 41.5.6: 278 + * After release from the module-stop state, wait for at least 279 + * 0.5 µs before starting A/D conversion. 280 + */ 281 + fsleep(1); 282 + 283 + return rzt2h_adc_calibrate(adc); 284 + } 285 + 286 + static const struct dev_pm_ops rzt2h_adc_pm_ops = { 287 + RUNTIME_PM_OPS(NULL, rzt2h_adc_pm_runtime_resume, NULL) 288 + }; 289 + 290 + static struct platform_driver rzt2h_adc_driver = { 291 + .probe = rzt2h_adc_probe, 292 + .driver = { 293 + .name = "rzt2h-adc", 294 + .of_match_table = rzt2h_adc_match, 295 + .pm = pm_ptr(&rzt2h_adc_pm_ops), 296 + }, 297 + }; 298 + 299 + module_platform_driver(rzt2h_adc_driver); 300 + 301 + MODULE_AUTHOR("Cosmin Tanislav <cosmin-gabriel.tanislav.xa@renesas.com>"); 302 + MODULE_DESCRIPTION("Renesas RZ/T2H / RZ/N2H ADC driver"); 303 + MODULE_LICENSE("GPL"); 304 + MODULE_IMPORT_NS("IIO_DRIVER");
+1 -1
drivers/iio/adc/ti-ads131e08.c
··· 848 848 ret = devm_iio_trigger_register(&spi->dev, st->trig); 849 849 if (ret) { 850 850 dev_err(&spi->dev, "failed to register IIO trigger\n"); 851 - return -ENOMEM; 851 + return ret; 852 852 } 853 853 854 854 indio_dev->trig = iio_trigger_get(st->trig);
+1 -1
drivers/iio/adc/ti_am335x_adc.c
··· 123 123 124 124 chan = adc_dev->channel_line[i]; 125 125 126 - if (adc_dev->step_avg[i]) 126 + if (adc_dev->step_avg[i] && adc_dev->step_avg[i] <= STEPCONFIG_AVG_16) 127 127 stepconfig = STEPCONFIG_AVG(ffs(adc_dev->step_avg[i]) - 1) | 128 128 STEPCONFIG_FIFO1; 129 129 else
+1
drivers/iio/buffer/industrialio-buffer-cb.c
··· 13 13 14 14 struct iio_cb_buffer { 15 15 struct iio_buffer buffer; 16 + /* Must be safe to call from any context (e.g. must not sleep). */ 16 17 int (*cb)(const void *data, void *private); 17 18 void *private; 18 19 struct iio_channel *channels;
+2 -3
drivers/iio/common/scmi_sensors/scmi_iio.c
··· 66 66 /* 67 67 * Timestamp returned by SCMI is in seconds and is equal to 68 68 * time * power-of-10 multiplier(tstamp_scale) seconds. 69 - * Converting the timestamp to nanoseconds below. 69 + * Converting the timestamp to nanoseconds (10⁹) below. 70 70 */ 71 - tstamp_scale = sensor->sensor_info->tstamp_scale + 72 - const_ilog2(NSEC_PER_SEC) / const_ilog2(10); 71 + tstamp_scale = sensor->sensor_info->tstamp_scale + 9; 73 72 if (tstamp_scale < 0) { 74 73 do_div(time, int_pow(10, abs(tstamp_scale))); 75 74 time_ns = time;
+23 -8
drivers/iio/dac/Kconfig
··· 97 97 ad5421. 98 98 99 99 config AD5446 100 - tristate "Analog Devices AD5446 and similar single channel DACs driver" 101 - depends on (SPI_MASTER && I2C!=m) || I2C 100 + tristate 101 + 102 + config AD5446_SPI 103 + tristate "Analog Devices AD5446 and similar single channel DACs driver (SPI)" 104 + depends on SPI 105 + select AD5446 102 106 help 103 - Say yes here to build support for Analog Devices AD5300, AD5301, AD5310, 104 - AD5311, AD5320, AD5321, AD5444, AD5446, AD5450, AD5451, AD5452, AD5453, 105 - AD5512A, AD5541A, AD5542A, AD5543, AD5553, AD5600, AD5601, AD5602, AD5611, 106 - AD5612, AD5620, AD5621, AD5622, AD5640, AD5641, AD5660, AD5662 DACs 107 - as well as Texas Instruments DAC081S101, DAC101S101, DAC121S101. 107 + Say yes here to build support for Analog Devices AD5300, AD5310, 108 + AD5320, AD5444, AD5446, AD5450, AD5451, AD5452, AD5453, AD5512A, 109 + AD5541A, AD5542A, AD5543, AD5553, AD5600, AD5601, AD5611, AD5620, 110 + AD5621, AD5640, AD5641, AD5660, AD5662 DACs as well as 111 + Texas Instruments DAC081S101, DAC101S101, DAC121S101. 108 112 109 113 To compile this driver as a module, choose M here: the 110 - module will be called ad5446. 114 + module will be called ad5446-spi. 115 + 116 + config AD5446_I2C 117 + tristate "Analog Devices AD5446 and similar single channel DACs driver (I2C)" 118 + depends on I2C 119 + select AD5446 120 + help 121 + Say yes here to build support for Analog Devices AD5301, AD5311, AD5321, 122 + AD5602, AD5612, AD5622 DACs. 123 + 124 + To compile this driver as a module, choose M here: the 125 + module will be called ad5446-i2c. 111 126 112 127 config AD5449 113 128 tristate "Analog Devices AD5449 and similar DACs driver"
+2
drivers/iio/dac/Makefile
··· 15 15 obj-$(CONFIG_AD5064) += ad5064.o 16 16 obj-$(CONFIG_AD5504) += ad5504.o 17 17 obj-$(CONFIG_AD5446) += ad5446.o 18 + obj-$(CONFIG_AD5446_SPI) += ad5446-spi.o 19 + obj-$(CONFIG_AD5446_I2C) += ad5446-i2c.o 18 20 obj-$(CONFIG_AD5449) += ad5449.o 19 21 obj-$(CONFIG_AD5592R_BASE) += ad5592r-base.o 20 22 obj-$(CONFIG_AD5592R) += ad5592r.o
+102
drivers/iio/dac/ad5446-i2c.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * AD5446 SPI I2C driver 4 + * 5 + * Copyright 2025 Analog Devices Inc. 6 + */ 7 + #include <linux/err.h> 8 + #include <linux/module.h> 9 + #include <linux/mod_devicetable.h> 10 + #include <linux/i2c.h> 11 + 12 + #include <asm/byteorder.h> 13 + 14 + #include "ad5446.h" 15 + 16 + static int ad5622_write(struct ad5446_state *st, unsigned int val) 17 + { 18 + struct i2c_client *client = to_i2c_client(st->dev); 19 + int ret; 20 + 21 + st->d16 = cpu_to_be16(val); 22 + 23 + ret = i2c_master_send_dmasafe(client, (char *)&st->d16, sizeof(st->d16)); 24 + if (ret < 0) 25 + return ret; 26 + if (ret != sizeof(st->d16)) 27 + return -EIO; 28 + 29 + return 0; 30 + } 31 + 32 + static int ad5446_i2c_probe(struct i2c_client *i2c) 33 + { 34 + const struct i2c_device_id *id = i2c_client_get_device_id(i2c); 35 + const struct ad5446_chip_info *chip_info; 36 + 37 + chip_info = i2c_get_match_data(i2c); 38 + if (!chip_info) 39 + return -ENODEV; 40 + 41 + return ad5446_probe(&i2c->dev, id->name, chip_info); 42 + } 43 + 44 + /* 45 + * ad5446_supported_i2c_device_ids: 46 + * The AD5620/40/60 parts are available in different fixed internal reference 47 + * voltage options. The actual part numbers may look differently 48 + * (and a bit cryptic), however this style is used to make clear which 49 + * parts are supported here. 50 + */ 51 + 52 + static const struct ad5446_chip_info ad5602_chip_info = { 53 + .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 4), 54 + .write = ad5622_write, 55 + }; 56 + 57 + static const struct ad5446_chip_info ad5612_chip_info = { 58 + .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 2), 59 + .write = ad5622_write, 60 + }; 61 + 62 + static const struct ad5446_chip_info ad5622_chip_info = { 63 + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 0), 64 + .write = ad5622_write, 65 + }; 66 + 67 + static const struct i2c_device_id ad5446_i2c_ids[] = { 68 + {"ad5301", (kernel_ulong_t)&ad5602_chip_info}, 69 + {"ad5311", (kernel_ulong_t)&ad5612_chip_info}, 70 + {"ad5321", (kernel_ulong_t)&ad5622_chip_info}, 71 + {"ad5602", (kernel_ulong_t)&ad5602_chip_info}, 72 + {"ad5612", (kernel_ulong_t)&ad5612_chip_info}, 73 + {"ad5622", (kernel_ulong_t)&ad5622_chip_info}, 74 + { } 75 + }; 76 + MODULE_DEVICE_TABLE(i2c, ad5446_i2c_ids); 77 + 78 + static const struct of_device_id ad5446_i2c_of_ids[] = { 79 + { .compatible = "adi,ad5301", .data = &ad5602_chip_info }, 80 + { .compatible = "adi,ad5311", .data = &ad5612_chip_info }, 81 + { .compatible = "adi,ad5321", .data = &ad5622_chip_info }, 82 + { .compatible = "adi,ad5602", .data = &ad5602_chip_info }, 83 + { .compatible = "adi,ad5612", .data = &ad5612_chip_info }, 84 + { .compatible = "adi,ad5622", .data = &ad5622_chip_info }, 85 + { } 86 + }; 87 + MODULE_DEVICE_TABLE(OF, ad5446_i2c_of_ids); 88 + 89 + static struct i2c_driver ad5446_i2c_driver = { 90 + .driver = { 91 + .name = "ad5446", 92 + .of_match_table = ad5446_i2c_of_ids, 93 + }, 94 + .probe = ad5446_i2c_probe, 95 + .id_table = ad5446_i2c_ids, 96 + }; 97 + module_i2c_driver(ad5446_i2c_driver); 98 + 99 + MODULE_AUTHOR("Nuno Sá <nuno.sa@analog.com>"); 100 + MODULE_DESCRIPTION("Analog Devices AD5622 and similar I2C DACs"); 101 + MODULE_LICENSE("GPL"); 102 + MODULE_IMPORT_NS("IIO_AD5446");
+252
drivers/iio/dac/ad5446-spi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * AD5446 SPI DAC driver 4 + * 5 + * Copyright 2025 Analog Devices Inc. 6 + */ 7 + #include <linux/err.h> 8 + #include <linux/module.h> 9 + #include <linux/mod_devicetable.h> 10 + #include <linux/spi/spi.h> 11 + #include <linux/unaligned.h> 12 + 13 + #include <asm/byteorder.h> 14 + 15 + #include "ad5446.h" 16 + 17 + static int ad5446_write(struct ad5446_state *st, unsigned int val) 18 + { 19 + struct spi_device *spi = to_spi_device(st->dev); 20 + 21 + st->d16 = cpu_to_be16(val); 22 + 23 + return spi_write(spi, &st->d16, sizeof(st->d16)); 24 + } 25 + 26 + static int ad5660_write(struct ad5446_state *st, unsigned int val) 27 + { 28 + struct spi_device *spi = to_spi_device(st->dev); 29 + 30 + put_unaligned_be24(val, st->d24); 31 + 32 + return spi_write(spi, st->d24, sizeof(st->d24)); 33 + } 34 + 35 + static int ad5446_spi_probe(struct spi_device *spi) 36 + { 37 + const struct spi_device_id *id = spi_get_device_id(spi); 38 + const struct ad5446_chip_info *chip_info; 39 + 40 + chip_info = spi_get_device_match_data(spi); 41 + if (!chip_info) 42 + return -ENODEV; 43 + 44 + return ad5446_probe(&spi->dev, id->name, chip_info); 45 + } 46 + 47 + /* 48 + * ad5446_supported_spi_device_ids: 49 + * The AD5620/40/60 parts are available in different fixed internal reference 50 + * voltage options. The actual part numbers may look differently 51 + * (and a bit cryptic), however this style is used to make clear which 52 + * parts are supported here. 53 + */ 54 + 55 + static const struct ad5446_chip_info ad5300_chip_info = { 56 + .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 4), 57 + .write = ad5446_write, 58 + }; 59 + 60 + static const struct ad5446_chip_info ad5310_chip_info = { 61 + .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 2), 62 + .write = ad5446_write, 63 + }; 64 + 65 + static const struct ad5446_chip_info ad5320_chip_info = { 66 + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 0), 67 + .write = ad5446_write, 68 + }; 69 + 70 + static const struct ad5446_chip_info ad5444_chip_info = { 71 + .channel = AD5446_CHANNEL(12, 16, 2), 72 + .write = ad5446_write, 73 + }; 74 + 75 + static const struct ad5446_chip_info ad5446_chip_info = { 76 + .channel = AD5446_CHANNEL(14, 16, 0), 77 + .write = ad5446_write, 78 + }; 79 + 80 + static const struct ad5446_chip_info ad5450_chip_info = { 81 + .channel = AD5446_CHANNEL(8, 16, 6), 82 + .write = ad5446_write, 83 + }; 84 + 85 + static const struct ad5446_chip_info ad5451_chip_info = { 86 + .channel = AD5446_CHANNEL(10, 16, 4), 87 + .write = ad5446_write, 88 + }; 89 + 90 + static const struct ad5446_chip_info ad5541a_chip_info = { 91 + .channel = AD5446_CHANNEL(16, 16, 0), 92 + .write = ad5446_write, 93 + }; 94 + 95 + static const struct ad5446_chip_info ad5512a_chip_info = { 96 + .channel = AD5446_CHANNEL(12, 16, 4), 97 + .write = ad5446_write, 98 + }; 99 + 100 + static const struct ad5446_chip_info ad5553_chip_info = { 101 + .channel = AD5446_CHANNEL(14, 16, 0), 102 + .write = ad5446_write, 103 + }; 104 + 105 + static const struct ad5446_chip_info ad5601_chip_info = { 106 + .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6), 107 + .write = ad5446_write, 108 + }; 109 + 110 + static const struct ad5446_chip_info ad5611_chip_info = { 111 + .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4), 112 + .write = ad5446_write, 113 + }; 114 + 115 + static const struct ad5446_chip_info ad5621_chip_info = { 116 + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), 117 + .write = ad5446_write, 118 + }; 119 + 120 + static const struct ad5446_chip_info ad5641_chip_info = { 121 + .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), 122 + .write = ad5446_write, 123 + }; 124 + 125 + static const struct ad5446_chip_info ad5620_2500_chip_info = { 126 + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), 127 + .int_vref_mv = 2500, 128 + .write = ad5446_write, 129 + }; 130 + 131 + static const struct ad5446_chip_info ad5620_1250_chip_info = { 132 + .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), 133 + .int_vref_mv = 1250, 134 + .write = ad5446_write, 135 + }; 136 + 137 + static const struct ad5446_chip_info ad5640_2500_chip_info = { 138 + .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), 139 + .int_vref_mv = 2500, 140 + .write = ad5446_write, 141 + }; 142 + 143 + static const struct ad5446_chip_info ad5640_1250_chip_info = { 144 + .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), 145 + .int_vref_mv = 1250, 146 + .write = ad5446_write, 147 + }; 148 + 149 + static const struct ad5446_chip_info ad5660_2500_chip_info = { 150 + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), 151 + .int_vref_mv = 2500, 152 + .write = ad5660_write, 153 + }; 154 + 155 + static const struct ad5446_chip_info ad5660_1250_chip_info = { 156 + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), 157 + .int_vref_mv = 1250, 158 + .write = ad5660_write, 159 + }; 160 + 161 + static const struct ad5446_chip_info ad5662_chip_info = { 162 + .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), 163 + .write = ad5660_write, 164 + }; 165 + 166 + static const struct spi_device_id ad5446_spi_ids[] = { 167 + {"ad5300", (kernel_ulong_t)&ad5300_chip_info}, 168 + {"ad5310", (kernel_ulong_t)&ad5310_chip_info}, 169 + {"ad5320", (kernel_ulong_t)&ad5320_chip_info}, 170 + {"ad5444", (kernel_ulong_t)&ad5444_chip_info}, 171 + {"ad5446", (kernel_ulong_t)&ad5446_chip_info}, 172 + {"ad5450", (kernel_ulong_t)&ad5450_chip_info}, 173 + {"ad5451", (kernel_ulong_t)&ad5451_chip_info}, 174 + {"ad5452", (kernel_ulong_t)&ad5444_chip_info}, /* ad5452 is compatible to the ad5444 */ 175 + {"ad5453", (kernel_ulong_t)&ad5446_chip_info}, /* ad5453 is compatible to the ad5446 */ 176 + {"ad5512a", (kernel_ulong_t)&ad5512a_chip_info}, 177 + {"ad5541a", (kernel_ulong_t)&ad5541a_chip_info}, 178 + {"ad5542", (kernel_ulong_t)&ad5541a_chip_info}, /* ad5541a and ad5542 are compatible */ 179 + {"ad5542a", (kernel_ulong_t)&ad5541a_chip_info}, /* ad5541a and ad5542a are compatible */ 180 + {"ad5543", (kernel_ulong_t)&ad5541a_chip_info}, /* ad5541a and ad5543 are compatible */ 181 + {"ad5553", (kernel_ulong_t)&ad5553_chip_info}, 182 + {"ad5600", (kernel_ulong_t)&ad5541a_chip_info}, /* ad5541a and ad5600 are compatible */ 183 + {"ad5601", (kernel_ulong_t)&ad5601_chip_info}, 184 + {"ad5611", (kernel_ulong_t)&ad5611_chip_info}, 185 + {"ad5621", (kernel_ulong_t)&ad5621_chip_info}, 186 + {"ad5641", (kernel_ulong_t)&ad5641_chip_info}, 187 + {"ad5620-2500", (kernel_ulong_t)&ad5620_2500_chip_info}, /* AD5620/40/60: */ 188 + /* part numbers may look differently */ 189 + {"ad5620-1250", (kernel_ulong_t)&ad5620_1250_chip_info}, 190 + {"ad5640-2500", (kernel_ulong_t)&ad5640_2500_chip_info}, 191 + {"ad5640-1250", (kernel_ulong_t)&ad5640_1250_chip_info}, 192 + {"ad5660-2500", (kernel_ulong_t)&ad5660_2500_chip_info}, 193 + {"ad5660-1250", (kernel_ulong_t)&ad5660_1250_chip_info}, 194 + {"ad5662", (kernel_ulong_t)&ad5662_chip_info}, 195 + {"dac081s101", (kernel_ulong_t)&ad5300_chip_info}, /* compatible Texas Instruments chips */ 196 + {"dac101s101", (kernel_ulong_t)&ad5310_chip_info}, 197 + {"dac121s101", (kernel_ulong_t)&ad5320_chip_info}, 198 + {"dac7512", (kernel_ulong_t)&ad5320_chip_info}, 199 + { } 200 + }; 201 + MODULE_DEVICE_TABLE(spi, ad5446_spi_ids); 202 + 203 + static const struct of_device_id ad5446_of_ids[] = { 204 + { .compatible = "adi,ad5300", .data = &ad5300_chip_info }, 205 + { .compatible = "adi,ad5310", .data = &ad5310_chip_info }, 206 + { .compatible = "adi,ad5320", .data = &ad5320_chip_info }, 207 + { .compatible = "adi,ad5444", .data = &ad5444_chip_info }, 208 + { .compatible = "adi,ad5446", .data = &ad5446_chip_info }, 209 + { .compatible = "adi,ad5450", .data = &ad5450_chip_info }, 210 + { .compatible = "adi,ad5451", .data = &ad5451_chip_info }, 211 + { .compatible = "adi,ad5452", .data = &ad5444_chip_info }, 212 + { .compatible = "adi,ad5453", .data = &ad5446_chip_info }, 213 + { .compatible = "adi,ad5512a", .data = &ad5512a_chip_info }, 214 + { .compatible = "adi,ad5541a", .data = &ad5541a_chip_info }, 215 + { .compatible = "adi,ad5542", .data = &ad5541a_chip_info }, 216 + { .compatible = "adi,ad5542a", .data = &ad5541a_chip_info }, 217 + { .compatible = "adi,ad5543", .data = &ad5541a_chip_info }, 218 + { .compatible = "adi,ad5553", .data = &ad5553_chip_info }, 219 + { .compatible = "adi,ad5600", .data = &ad5541a_chip_info }, 220 + { .compatible = "adi,ad5601", .data = &ad5601_chip_info }, 221 + { .compatible = "adi,ad5611", .data = &ad5611_chip_info }, 222 + { .compatible = "adi,ad5621", .data = &ad5621_chip_info }, 223 + { .compatible = "adi,ad5641", .data = &ad5641_chip_info }, 224 + { .compatible = "adi,ad5620-2500", .data = &ad5620_2500_chip_info }, 225 + { .compatible = "adi,ad5620-1250", .data = &ad5620_1250_chip_info }, 226 + { .compatible = "adi,ad5640-2500", .data = &ad5640_2500_chip_info }, 227 + { .compatible = "adi,ad5640-1250", .data = &ad5640_1250_chip_info }, 228 + { .compatible = "adi,ad5660-2500", .data = &ad5660_2500_chip_info }, 229 + { .compatible = "adi,ad5660-1250", .data = &ad5660_1250_chip_info }, 230 + { .compatible = "adi,ad5662", .data = &ad5662_chip_info }, 231 + { .compatible = "ti,dac081s101", .data = &ad5300_chip_info }, 232 + { .compatible = "ti,dac101s101", .data = &ad5310_chip_info }, 233 + { .compatible = "ti,dac121s101", .data = &ad5320_chip_info }, 234 + { .compatible = "ti,dac7512", .data = &ad5320_chip_info }, 235 + { } 236 + }; 237 + MODULE_DEVICE_TABLE(of, ad5446_of_ids); 238 + 239 + static struct spi_driver ad5446_spi_driver = { 240 + .driver = { 241 + .name = "ad5446", 242 + .of_match_table = ad5446_of_ids, 243 + }, 244 + .probe = ad5446_spi_probe, 245 + .id_table = ad5446_spi_ids, 246 + }; 247 + module_spi_driver(ad5446_spi_driver); 248 + 249 + MODULE_AUTHOR("Nuno Sá <nuno.sa@analog.com>"); 250 + MODULE_DESCRIPTION("Analog Devices AD5446 and similar SPI DACs"); 251 + MODULE_LICENSE("GPL"); 252 + MODULE_IMPORT_NS("IIO_AD5446");
+59 -447
drivers/iio/dac/ad5446.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-or-later 2 2 /* 3 - * AD5446 SPI DAC driver 3 + * AD5446 CORE DAC driver 4 4 * 5 5 * Copyright 2010 Analog Devices Inc. 6 6 */ 7 7 8 - #include <linux/interrupt.h> 9 - #include <linux/workqueue.h> 8 + #include <linux/array_size.h> 9 + #include <linux/cleanup.h> 10 10 #include <linux/device.h> 11 - #include <linux/kernel.h> 12 - #include <linux/slab.h> 13 - #include <linux/sysfs.h> 14 - #include <linux/list.h> 15 - #include <linux/spi/spi.h> 16 - #include <linux/i2c.h> 17 - #include <linux/regulator/consumer.h> 18 11 #include <linux/err.h> 19 - #include <linux/module.h> 20 - #include <linux/mod_devicetable.h> 21 - 12 + #include <linux/export.h> 22 13 #include <linux/iio/iio.h> 23 - #include <linux/iio/sysfs.h> 14 + #include <linux/kstrtox.h> 15 + #include <linux/module.h> 16 + #include <linux/mutex.h> 17 + #include <linux/regulator/consumer.h> 18 + #include <linux/sysfs.h> 24 19 25 - #include <linux/unaligned.h> 20 + #include "ad5446.h" 26 21 27 22 #define MODE_PWRDWN_1k 0x1 28 23 #define MODE_PWRDWN_100k 0x2 29 24 #define MODE_PWRDWN_TRISTATE 0x3 30 - 31 - /** 32 - * struct ad5446_state - driver instance specific data 33 - * @dev: this device 34 - * @chip_info: chip model specific constants, available modes etc 35 - * @vref_mv: actual reference voltage used 36 - * @cached_val: store/retrieve values during power down 37 - * @pwr_down_mode: power down mode (1k, 100k or tristate) 38 - * @pwr_down: true if the device is in power down 39 - * @lock: lock to protect the data buffer during write ops 40 - */ 41 - 42 - struct ad5446_state { 43 - struct device *dev; 44 - const struct ad5446_chip_info *chip_info; 45 - unsigned short vref_mv; 46 - unsigned cached_val; 47 - unsigned pwr_down_mode; 48 - unsigned pwr_down; 49 - struct mutex lock; 50 - }; 51 - 52 - /** 53 - * struct ad5446_chip_info - chip specific information 54 - * @channel: channel spec for the DAC 55 - * @int_vref_mv: AD5620/40/60: the internal reference voltage 56 - * @write: chip specific helper function to write to the register 57 - */ 58 - 59 - struct ad5446_chip_info { 60 - struct iio_chan_spec channel; 61 - u16 int_vref_mv; 62 - int (*write)(struct ad5446_state *st, unsigned val); 63 - }; 64 25 65 26 static const char * const ad5446_powerdown_modes[] = { 66 27 "1kohm_to_gnd", "100kohm_to_gnd", "three_state" 67 28 }; 68 29 69 30 static int ad5446_set_powerdown_mode(struct iio_dev *indio_dev, 70 - const struct iio_chan_spec *chan, unsigned int mode) 31 + const struct iio_chan_spec *chan, 32 + unsigned int mode) 71 33 { 72 34 struct ad5446_state *st = iio_priv(indio_dev); 73 35 ··· 39 77 } 40 78 41 79 static int ad5446_get_powerdown_mode(struct iio_dev *indio_dev, 42 - const struct iio_chan_spec *chan) 80 + const struct iio_chan_spec *chan) 43 81 { 44 82 struct ad5446_state *st = iio_priv(indio_dev); 45 83 ··· 54 92 }; 55 93 56 94 static ssize_t ad5446_read_dac_powerdown(struct iio_dev *indio_dev, 57 - uintptr_t private, 58 - const struct iio_chan_spec *chan, 59 - char *buf) 95 + uintptr_t private, 96 + const struct iio_chan_spec *chan, 97 + char *buf) 60 98 { 61 99 struct ad5446_state *st = iio_priv(indio_dev); 62 100 ··· 64 102 } 65 103 66 104 static ssize_t ad5446_write_dac_powerdown(struct iio_dev *indio_dev, 67 - uintptr_t private, 68 - const struct iio_chan_spec *chan, 69 - const char *buf, size_t len) 105 + uintptr_t private, 106 + const struct iio_chan_spec *chan, 107 + const char *buf, size_t len) 70 108 { 71 109 struct ad5446_state *st = iio_priv(indio_dev); 72 110 unsigned int shift; ··· 78 116 if (ret) 79 117 return ret; 80 118 81 - mutex_lock(&st->lock); 119 + guard(mutex)(&st->lock); 82 120 st->pwr_down = powerdown; 83 121 84 122 if (st->pwr_down) { ··· 89 127 } 90 128 91 129 ret = st->chip_info->write(st, val); 92 - mutex_unlock(&st->lock); 130 + if (ret) 131 + return ret; 93 132 94 - return ret ? ret : len; 133 + return len; 95 134 } 96 135 97 - static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = { 136 + const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = { 98 137 { 99 138 .name = "powerdown", 100 139 .read = ad5446_read_dac_powerdown, ··· 106 143 IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, &ad5446_powerdown_mode_enum), 107 144 { } 108 145 }; 109 - 110 - #define _AD5446_CHANNEL(bits, storage, _shift, ext) { \ 111 - .type = IIO_VOLTAGE, \ 112 - .indexed = 1, \ 113 - .output = 1, \ 114 - .channel = 0, \ 115 - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 116 - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 117 - .scan_type = { \ 118 - .sign = 'u', \ 119 - .realbits = (bits), \ 120 - .storagebits = (storage), \ 121 - .shift = (_shift), \ 122 - }, \ 123 - .ext_info = (ext), \ 124 - } 125 - 126 - #define AD5446_CHANNEL(bits, storage, shift) \ 127 - _AD5446_CHANNEL(bits, storage, shift, NULL) 128 - 129 - #define AD5446_CHANNEL_POWERDOWN(bits, storage, shift) \ 130 - _AD5446_CHANNEL(bits, storage, shift, ad5446_ext_info_powerdown) 146 + EXPORT_SYMBOL_NS_GPL(ad5446_ext_info_powerdown, "IIO_AD5446"); 131 147 132 148 static int ad5446_read_raw(struct iio_dev *indio_dev, 133 149 struct iio_chan_spec const *chan, ··· 128 186 return -EINVAL; 129 187 } 130 188 131 - static int ad5446_write_raw(struct iio_dev *indio_dev, 132 - struct iio_chan_spec const *chan, 133 - int val, 134 - int val2, 135 - long mask) 189 + static int ad5446_write_dac_raw(struct iio_dev *indio_dev, 190 + const struct iio_chan_spec *chan, 191 + int val) 136 192 { 137 193 struct ad5446_state *st = iio_priv(indio_dev); 138 - int ret = 0; 139 194 195 + if (val >= (1 << chan->scan_type.realbits) || val < 0) 196 + return -EINVAL; 197 + 198 + val <<= chan->scan_type.shift; 199 + guard(mutex)(&st->lock); 200 + 201 + st->cached_val = val; 202 + if (st->pwr_down) 203 + return 0; 204 + 205 + return st->chip_info->write(st, val); 206 + } 207 + 208 + static int ad5446_write_raw(struct iio_dev *indio_dev, 209 + struct iio_chan_spec const *chan, int val, 210 + int val2, long mask) 211 + { 140 212 switch (mask) { 141 213 case IIO_CHAN_INFO_RAW: 142 - if (val >= (1 << chan->scan_type.realbits) || val < 0) 143 - return -EINVAL; 144 - 145 - val <<= chan->scan_type.shift; 146 - mutex_lock(&st->lock); 147 - st->cached_val = val; 148 - if (!st->pwr_down) 149 - ret = st->chip_info->write(st, val); 150 - mutex_unlock(&st->lock); 151 - break; 214 + return ad5446_write_dac_raw(indio_dev, chan, val); 152 215 default: 153 - ret = -EINVAL; 216 + return -EINVAL; 154 217 } 155 - 156 - return ret; 157 218 } 158 219 159 220 static const struct iio_info ad5446_info = { ··· 164 219 .write_raw = ad5446_write_raw, 165 220 }; 166 221 167 - static int ad5446_probe(struct device *dev, const char *name, 168 - const struct ad5446_chip_info *chip_info) 222 + int ad5446_probe(struct device *dev, const char *name, 223 + const struct ad5446_chip_info *chip_info) 169 224 { 170 225 struct ad5446_state *st; 171 226 struct iio_dev *indio_dev; ··· 186 241 indio_dev->channels = &st->chip_info->channel; 187 242 indio_dev->num_channels = 1; 188 243 189 - mutex_init(&st->lock); 244 + ret = devm_mutex_init(dev, &st->lock); 245 + if (ret) 246 + return ret; 190 247 191 248 st->pwr_down_mode = MODE_PWRDWN_1k; 192 249 ··· 196 249 if (ret < 0 && ret != -ENODEV) 197 250 return ret; 198 251 if (ret == -ENODEV) { 199 - if (chip_info->int_vref_mv) 200 - st->vref_mv = chip_info->int_vref_mv; 201 - else 202 - dev_warn(dev, "reference voltage unspecified\n"); 252 + if (!chip_info->int_vref_mv) 253 + return dev_err_probe(dev, ret, 254 + "reference voltage unspecified\n"); 255 + 256 + st->vref_mv = chip_info->int_vref_mv; 203 257 } else { 204 258 st->vref_mv = ret / 1000; 205 259 } 206 260 207 261 return devm_iio_device_register(dev, indio_dev); 208 262 } 209 - 210 - #if IS_ENABLED(CONFIG_SPI_MASTER) 211 - 212 - static int ad5446_write(struct ad5446_state *st, unsigned val) 213 - { 214 - struct spi_device *spi = to_spi_device(st->dev); 215 - __be16 data = cpu_to_be16(val); 216 - 217 - return spi_write(spi, &data, sizeof(data)); 218 - } 219 - 220 - static int ad5660_write(struct ad5446_state *st, unsigned val) 221 - { 222 - struct spi_device *spi = to_spi_device(st->dev); 223 - uint8_t data[3]; 224 - 225 - put_unaligned_be24(val, &data[0]); 226 - 227 - return spi_write(spi, data, sizeof(data)); 228 - } 229 - 230 - /* 231 - * ad5446_supported_spi_device_ids: 232 - * The AD5620/40/60 parts are available in different fixed internal reference 233 - * voltage options. The actual part numbers may look differently 234 - * (and a bit cryptic), however this style is used to make clear which 235 - * parts are supported here. 236 - */ 237 - enum ad5446_supported_spi_device_ids { 238 - ID_AD5300, 239 - ID_AD5310, 240 - ID_AD5320, 241 - ID_AD5444, 242 - ID_AD5446, 243 - ID_AD5450, 244 - ID_AD5451, 245 - ID_AD5541A, 246 - ID_AD5512A, 247 - ID_AD5553, 248 - ID_AD5600, 249 - ID_AD5601, 250 - ID_AD5611, 251 - ID_AD5621, 252 - ID_AD5641, 253 - ID_AD5620_2500, 254 - ID_AD5620_1250, 255 - ID_AD5640_2500, 256 - ID_AD5640_1250, 257 - ID_AD5660_2500, 258 - ID_AD5660_1250, 259 - ID_AD5662, 260 - }; 261 - 262 - static const struct ad5446_chip_info ad5446_spi_chip_info[] = { 263 - [ID_AD5300] = { 264 - .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 4), 265 - .write = ad5446_write, 266 - }, 267 - [ID_AD5310] = { 268 - .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 2), 269 - .write = ad5446_write, 270 - }, 271 - [ID_AD5320] = { 272 - .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 0), 273 - .write = ad5446_write, 274 - }, 275 - [ID_AD5444] = { 276 - .channel = AD5446_CHANNEL(12, 16, 2), 277 - .write = ad5446_write, 278 - }, 279 - [ID_AD5446] = { 280 - .channel = AD5446_CHANNEL(14, 16, 0), 281 - .write = ad5446_write, 282 - }, 283 - [ID_AD5450] = { 284 - .channel = AD5446_CHANNEL(8, 16, 6), 285 - .write = ad5446_write, 286 - }, 287 - [ID_AD5451] = { 288 - .channel = AD5446_CHANNEL(10, 16, 4), 289 - .write = ad5446_write, 290 - }, 291 - [ID_AD5541A] = { 292 - .channel = AD5446_CHANNEL(16, 16, 0), 293 - .write = ad5446_write, 294 - }, 295 - [ID_AD5512A] = { 296 - .channel = AD5446_CHANNEL(12, 16, 4), 297 - .write = ad5446_write, 298 - }, 299 - [ID_AD5553] = { 300 - .channel = AD5446_CHANNEL(14, 16, 0), 301 - .write = ad5446_write, 302 - }, 303 - [ID_AD5600] = { 304 - .channel = AD5446_CHANNEL(16, 16, 0), 305 - .write = ad5446_write, 306 - }, 307 - [ID_AD5601] = { 308 - .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 6), 309 - .write = ad5446_write, 310 - }, 311 - [ID_AD5611] = { 312 - .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 4), 313 - .write = ad5446_write, 314 - }, 315 - [ID_AD5621] = { 316 - .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), 317 - .write = ad5446_write, 318 - }, 319 - [ID_AD5641] = { 320 - .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), 321 - .write = ad5446_write, 322 - }, 323 - [ID_AD5620_2500] = { 324 - .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), 325 - .int_vref_mv = 2500, 326 - .write = ad5446_write, 327 - }, 328 - [ID_AD5620_1250] = { 329 - .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 2), 330 - .int_vref_mv = 1250, 331 - .write = ad5446_write, 332 - }, 333 - [ID_AD5640_2500] = { 334 - .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), 335 - .int_vref_mv = 2500, 336 - .write = ad5446_write, 337 - }, 338 - [ID_AD5640_1250] = { 339 - .channel = AD5446_CHANNEL_POWERDOWN(14, 16, 0), 340 - .int_vref_mv = 1250, 341 - .write = ad5446_write, 342 - }, 343 - [ID_AD5660_2500] = { 344 - .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), 345 - .int_vref_mv = 2500, 346 - .write = ad5660_write, 347 - }, 348 - [ID_AD5660_1250] = { 349 - .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), 350 - .int_vref_mv = 1250, 351 - .write = ad5660_write, 352 - }, 353 - [ID_AD5662] = { 354 - .channel = AD5446_CHANNEL_POWERDOWN(16, 16, 0), 355 - .write = ad5660_write, 356 - }, 357 - }; 358 - 359 - static const struct spi_device_id ad5446_spi_ids[] = { 360 - {"ad5300", ID_AD5300}, 361 - {"ad5310", ID_AD5310}, 362 - {"ad5320", ID_AD5320}, 363 - {"ad5444", ID_AD5444}, 364 - {"ad5446", ID_AD5446}, 365 - {"ad5450", ID_AD5450}, 366 - {"ad5451", ID_AD5451}, 367 - {"ad5452", ID_AD5444}, /* ad5452 is compatible to the ad5444 */ 368 - {"ad5453", ID_AD5446}, /* ad5453 is compatible to the ad5446 */ 369 - {"ad5512a", ID_AD5512A}, 370 - {"ad5541a", ID_AD5541A}, 371 - {"ad5542a", ID_AD5541A}, /* ad5541a and ad5542a are compatible */ 372 - {"ad5543", ID_AD5541A}, /* ad5541a and ad5543 are compatible */ 373 - {"ad5553", ID_AD5553}, 374 - {"ad5600", ID_AD5600}, 375 - {"ad5601", ID_AD5601}, 376 - {"ad5611", ID_AD5611}, 377 - {"ad5621", ID_AD5621}, 378 - {"ad5641", ID_AD5641}, 379 - {"ad5620-2500", ID_AD5620_2500}, /* AD5620/40/60: */ 380 - {"ad5620-1250", ID_AD5620_1250}, /* part numbers may look differently */ 381 - {"ad5640-2500", ID_AD5640_2500}, 382 - {"ad5640-1250", ID_AD5640_1250}, 383 - {"ad5660-2500", ID_AD5660_2500}, 384 - {"ad5660-1250", ID_AD5660_1250}, 385 - {"ad5662", ID_AD5662}, 386 - {"dac081s101", ID_AD5300}, /* compatible Texas Instruments chips */ 387 - {"dac101s101", ID_AD5310}, 388 - {"dac121s101", ID_AD5320}, 389 - {"dac7512", ID_AD5320}, 390 - { } 391 - }; 392 - MODULE_DEVICE_TABLE(spi, ad5446_spi_ids); 393 - 394 - static const struct of_device_id ad5446_of_ids[] = { 395 - { .compatible = "ti,dac7512" }, 396 - { } 397 - }; 398 - MODULE_DEVICE_TABLE(of, ad5446_of_ids); 399 - 400 - static int ad5446_spi_probe(struct spi_device *spi) 401 - { 402 - const struct spi_device_id *id = spi_get_device_id(spi); 403 - 404 - return ad5446_probe(&spi->dev, id->name, 405 - &ad5446_spi_chip_info[id->driver_data]); 406 - } 407 - 408 - static struct spi_driver ad5446_spi_driver = { 409 - .driver = { 410 - .name = "ad5446", 411 - .of_match_table = ad5446_of_ids, 412 - }, 413 - .probe = ad5446_spi_probe, 414 - .id_table = ad5446_spi_ids, 415 - }; 416 - 417 - static int __init ad5446_spi_register_driver(void) 418 - { 419 - return spi_register_driver(&ad5446_spi_driver); 420 - } 421 - 422 - static void ad5446_spi_unregister_driver(void) 423 - { 424 - spi_unregister_driver(&ad5446_spi_driver); 425 - } 426 - 427 - #else 428 - 429 - static inline int ad5446_spi_register_driver(void) { return 0; } 430 - static inline void ad5446_spi_unregister_driver(void) { } 431 - 432 - #endif 433 - 434 - #if IS_ENABLED(CONFIG_I2C) 435 - 436 - static int ad5622_write(struct ad5446_state *st, unsigned val) 437 - { 438 - struct i2c_client *client = to_i2c_client(st->dev); 439 - __be16 data = cpu_to_be16(val); 440 - int ret; 441 - 442 - ret = i2c_master_send(client, (char *)&data, sizeof(data)); 443 - if (ret < 0) 444 - return ret; 445 - if (ret != sizeof(data)) 446 - return -EIO; 447 - 448 - return 0; 449 - } 450 - 451 - /* 452 - * ad5446_supported_i2c_device_ids: 453 - * The AD5620/40/60 parts are available in different fixed internal reference 454 - * voltage options. The actual part numbers may look differently 455 - * (and a bit cryptic), however this style is used to make clear which 456 - * parts are supported here. 457 - */ 458 - enum ad5446_supported_i2c_device_ids { 459 - ID_AD5602, 460 - ID_AD5612, 461 - ID_AD5622, 462 - }; 463 - 464 - static const struct ad5446_chip_info ad5446_i2c_chip_info[] = { 465 - [ID_AD5602] = { 466 - .channel = AD5446_CHANNEL_POWERDOWN(8, 16, 4), 467 - .write = ad5622_write, 468 - }, 469 - [ID_AD5612] = { 470 - .channel = AD5446_CHANNEL_POWERDOWN(10, 16, 2), 471 - .write = ad5622_write, 472 - }, 473 - [ID_AD5622] = { 474 - .channel = AD5446_CHANNEL_POWERDOWN(12, 16, 0), 475 - .write = ad5622_write, 476 - }, 477 - }; 478 - 479 - static int ad5446_i2c_probe(struct i2c_client *i2c) 480 - { 481 - const struct i2c_device_id *id = i2c_client_get_device_id(i2c); 482 - return ad5446_probe(&i2c->dev, id->name, 483 - &ad5446_i2c_chip_info[id->driver_data]); 484 - } 485 - 486 - static const struct i2c_device_id ad5446_i2c_ids[] = { 487 - {"ad5301", ID_AD5602}, 488 - {"ad5311", ID_AD5612}, 489 - {"ad5321", ID_AD5622}, 490 - {"ad5602", ID_AD5602}, 491 - {"ad5612", ID_AD5612}, 492 - {"ad5622", ID_AD5622}, 493 - { } 494 - }; 495 - MODULE_DEVICE_TABLE(i2c, ad5446_i2c_ids); 496 - 497 - static struct i2c_driver ad5446_i2c_driver = { 498 - .driver = { 499 - .name = "ad5446", 500 - }, 501 - .probe = ad5446_i2c_probe, 502 - .id_table = ad5446_i2c_ids, 503 - }; 504 - 505 - static int __init ad5446_i2c_register_driver(void) 506 - { 507 - return i2c_add_driver(&ad5446_i2c_driver); 508 - } 509 - 510 - static void __exit ad5446_i2c_unregister_driver(void) 511 - { 512 - i2c_del_driver(&ad5446_i2c_driver); 513 - } 514 - 515 - #else 516 - 517 - static inline int ad5446_i2c_register_driver(void) { return 0; } 518 - static inline void ad5446_i2c_unregister_driver(void) { } 519 - 520 - #endif 521 - 522 - static int __init ad5446_init(void) 523 - { 524 - int ret; 525 - 526 - ret = ad5446_spi_register_driver(); 527 - if (ret) 528 - return ret; 529 - 530 - ret = ad5446_i2c_register_driver(); 531 - if (ret) { 532 - ad5446_spi_unregister_driver(); 533 - return ret; 534 - } 535 - 536 - return 0; 537 - } 538 - module_init(ad5446_init); 539 - 540 - static void __exit ad5446_exit(void) 541 - { 542 - ad5446_i2c_unregister_driver(); 543 - ad5446_spi_unregister_driver(); 544 - } 545 - module_exit(ad5446_exit); 263 + EXPORT_SYMBOL_NS_GPL(ad5446_probe, "IIO_AD5446"); 546 264 547 265 MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); 548 - MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC"); 266 + MODULE_DESCRIPTION("Analog Devices CORE AD5446 DAC and similar devices"); 549 267 MODULE_LICENSE("GPL v2");
+77
drivers/iio/dac/ad5446.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _LINUX_AD5446_H 3 + #define _LINUX_AD5446_H 4 + 5 + #include <linux/bits.h> 6 + #include <linux/compiler.h> 7 + #include <linux/iio/iio.h> 8 + #include <linux/mutex.h> 9 + #include <linux/types.h> 10 + 11 + struct device; 12 + 13 + extern const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[]; 14 + 15 + #define _AD5446_CHANNEL(bits, storage, _shift, ext) { \ 16 + .type = IIO_VOLTAGE, \ 17 + .indexed = 1, \ 18 + .output = 1, \ 19 + .channel = 0, \ 20 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 21 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 22 + .scan_type = { \ 23 + .sign = 'u', \ 24 + .realbits = (bits), \ 25 + .storagebits = (storage), \ 26 + .shift = (_shift), \ 27 + }, \ 28 + .ext_info = (ext), \ 29 + } 30 + 31 + #define AD5446_CHANNEL(bits, storage, shift) \ 32 + _AD5446_CHANNEL(bits, storage, shift, NULL) 33 + 34 + #define AD5446_CHANNEL_POWERDOWN(bits, storage, shift) \ 35 + _AD5446_CHANNEL(bits, storage, shift, ad5446_ext_info_powerdown) 36 + 37 + /** 38 + * struct ad5446_state - driver instance specific data 39 + * @dev: this device 40 + * @chip_info: chip model specific constants, available modes etc 41 + * @vref_mv: actual reference voltage used 42 + * @cached_val: store/retrieve values during power down 43 + * @pwr_down_mode: power down mode (1k, 100k or tristate) 44 + * @pwr_down: true if the device is in power down 45 + * @lock: lock to protect the data buffer during write ops 46 + */ 47 + struct ad5446_state { 48 + struct device *dev; 49 + const struct ad5446_chip_info *chip_info; 50 + unsigned short vref_mv; 51 + unsigned int cached_val; 52 + unsigned int pwr_down_mode; 53 + unsigned int pwr_down; 54 + /* mutex to protect device shared data */ 55 + struct mutex lock; 56 + union { 57 + __be16 d16; 58 + u8 d24[3]; 59 + } __aligned(IIO_DMA_MINALIGN); 60 + }; 61 + 62 + /** 63 + * struct ad5446_chip_info - chip specific information 64 + * @channel: channel spec for the DAC 65 + * @int_vref_mv: AD5620/40/60: the internal reference voltage 66 + * @write: chip specific helper function to write to the register 67 + */ 68 + struct ad5446_chip_info { 69 + struct iio_chan_spec channel; 70 + u16 int_vref_mv; 71 + int (*write)(struct ad5446_state *st, unsigned int val); 72 + }; 73 + 74 + int ad5446_probe(struct device *dev, const char *name, 75 + const struct ad5446_chip_info *chip_info); 76 + 77 + #endif
+15 -17
drivers/iio/dac/ltc2688.c
··· 6 6 */ 7 7 #include <linux/bitfield.h> 8 8 #include <linux/bits.h> 9 + #include <linux/cleanup.h> 9 10 #include <linux/clk.h> 10 11 #include <linux/device.h> 11 12 #include <linux/gpio/consumer.h> ··· 209 208 code = FIELD_PREP(LTC2688_DITHER_RAW_MASK, code); 210 209 } 211 210 212 - mutex_lock(&st->lock); 211 + guard(mutex)(&st->lock); 213 212 /* select the correct input register to read from */ 214 213 ret = regmap_update_bits(st->regmap, LTC2688_CMD_A_B_SELECT, BIT(chan), 215 214 input << chan); 216 215 if (ret) 217 - goto out_unlock; 216 + return ret; 218 217 219 218 /* 220 219 * If in dither/toggle mode the dac should be updated by an ··· 225 224 else 226 225 reg = LTC2688_CMD_CH_CODE(chan); 227 226 228 - ret = regmap_write(st->regmap, reg, code); 229 - out_unlock: 230 - mutex_unlock(&st->lock); 231 - return ret; 227 + return regmap_write(st->regmap, reg, code); 232 228 } 233 229 234 230 static int ltc2688_dac_code_read(struct ltc2688_state *st, u32 chan, u32 input, ··· 234 236 struct ltc2688_chan *c = &st->channels[chan]; 235 237 int ret; 236 238 237 - mutex_lock(&st->lock); 239 + guard(mutex)(&st->lock); 238 240 ret = regmap_update_bits(st->regmap, LTC2688_CMD_A_B_SELECT, BIT(chan), 239 241 input << chan); 240 242 if (ret) 241 - goto out_unlock; 243 + return ret; 242 244 243 245 ret = regmap_read(st->regmap, LTC2688_CMD_CH_CODE(chan), code); 244 - out_unlock: 245 - mutex_unlock(&st->lock); 246 + if (ret) 247 + return ret; 246 248 247 249 if (!c->toggle_chan && input == LTC2688_INPUT_B) 248 250 *code = FIELD_GET(LTC2688_DITHER_RAW_MASK, *code); 249 251 250 - return ret; 252 + return 0; 251 253 } 252 254 253 255 static const int ltc2688_raw_range[] = {0, 1, U16_MAX}; ··· 357 359 if (ret) 358 360 return ret; 359 361 360 - mutex_lock(&st->lock); 362 + guard(mutex)(&st->lock); 361 363 ret = regmap_update_bits(st->regmap, LTC2688_CMD_TOGGLE_DITHER_EN, 362 364 BIT(chan->channel), en << chan->channel); 363 365 if (ret) 364 - goto out_unlock; 366 + return ret; 365 367 366 368 c->mode = en ? LTC2688_MODE_DITHER_TOGGLE : LTC2688_MODE_DEFAULT; 367 - out_unlock: 368 - mutex_unlock(&st->lock); 369 369 370 - return ret ?: len; 370 + return len; 371 371 } 372 372 373 373 static ssize_t ltc2688_reg_bool_get(struct iio_dev *indio_dev, ··· 949 953 950 954 /* Just write this once. No need to do it in every regmap read. */ 951 955 st->tx_data[3] = LTC2688_CMD_NOOP; 952 - mutex_init(&st->lock); 956 + ret = devm_mutex_init(dev, &st->lock); 957 + if (ret) 958 + return ret; 953 959 954 960 st->regmap = devm_regmap_init(dev, &ltc2688_regmap_bus, st, 955 961 &ltc2688_regmap_config);
+35 -3
drivers/iio/health/max30100.c
··· 5 5 * Copyright (C) 2015, 2018 6 6 * Author: Matt Ranostay <matt.ranostay@konsulko.com> 7 7 * 8 - * TODO: enable pulse length controls via device tree properties 9 8 */ 10 9 11 10 #include <linux/module.h> ··· 17 18 #include <linux/mutex.h> 18 19 #include <linux/property.h> 19 20 #include <linux/regmap.h> 21 + #include <linux/bitfield.h> 20 22 #include <linux/iio/iio.h> 21 23 #include <linux/iio/buffer.h> 22 24 #include <linux/iio/kfifo_buf.h> ··· 52 52 #define MAX30100_REG_MODE_CONFIG_PWR BIT(7) 53 53 54 54 #define MAX30100_REG_SPO2_CONFIG 0x07 55 + #define MAX30100_REG_SPO2_CONFIG_PW_MASK GENMASK(1, 0) 56 + #define MAX30100_REG_SPO2_CONFIG_200US 0x0 57 + #define MAX30100_REG_SPO2_CONFIG_400US 0x1 58 + #define MAX30100_REG_SPO2_CONFIG_800US 0x2 59 + #define MAX30100_REG_SPO2_CONFIG_1600US 0x3 55 60 #define MAX30100_REG_SPO2_CONFIG_100HZ BIT(2) 56 61 #define MAX30100_REG_SPO2_CONFIG_HI_RES_EN BIT(6) 57 - #define MAX30100_REG_SPO2_CONFIG_1600US 0x3 58 62 59 63 #define MAX30100_REG_LED_CONFIG 0x09 60 64 #define MAX30100_REG_LED_CONFIG_LED_MASK 0x0f ··· 310 306 MAX30100_REG_LED_CONFIG_LED_MASK, reg); 311 307 } 312 308 309 + static int max30100_get_pulse_width(unsigned int pwidth_us) 310 + { 311 + switch (pwidth_us) { 312 + case 200: 313 + return MAX30100_REG_SPO2_CONFIG_200US; 314 + case 400: 315 + return MAX30100_REG_SPO2_CONFIG_400US; 316 + case 800: 317 + return MAX30100_REG_SPO2_CONFIG_800US; 318 + case 1600: 319 + return MAX30100_REG_SPO2_CONFIG_1600US; 320 + default: 321 + return -EINVAL; 322 + } 323 + } 324 + 313 325 static int max30100_chip_init(struct max30100_data *data) 314 326 { 315 327 int ret; 328 + int pulse_width; 329 + /* set default LED pulse-width to 1600 us */ 330 + unsigned int pulse_us = 1600; 331 + struct device *dev = &data->client->dev; 316 332 317 333 /* setup LED current settings */ 318 334 ret = max30100_led_init(data); 319 335 if (ret) 320 336 return ret; 321 337 338 + /* Read LED pulse-width-us from DT */ 339 + device_property_read_u32(dev, "maxim,pulse-width-us", &pulse_us); 340 + 341 + pulse_width = max30100_get_pulse_width(pulse_us); 342 + if (pulse_width < 0) 343 + return dev_err_probe(dev, pulse_width, "invalid LED pulse-width %uus\n", pulse_us); 344 + 322 345 /* enable hi-res SPO2 readings at 100Hz */ 323 346 ret = regmap_write(data->regmap, MAX30100_REG_SPO2_CONFIG, 324 347 MAX30100_REG_SPO2_CONFIG_HI_RES_EN | 325 - MAX30100_REG_SPO2_CONFIG_100HZ); 348 + MAX30100_REG_SPO2_CONFIG_100HZ | 349 + FIELD_PREP(MAX30100_REG_SPO2_CONFIG_PW_MASK, pulse_width)); 326 350 if (ret) 327 351 return ret; 328 352
+2
drivers/iio/imu/Kconfig
··· 109 109 be called kmx61. 110 110 111 111 source "drivers/iio/imu/inv_icm42600/Kconfig" 112 + source "drivers/iio/imu/inv_icm45600/Kconfig" 112 113 source "drivers/iio/imu/inv_mpu6050/Kconfig" 113 114 114 115 config SMI240 ··· 125 124 This driver can also be built as a module. If so, the module will be 126 125 called smi240. 127 126 127 + source "drivers/iio/imu/smi330/Kconfig" 128 128 source "drivers/iio/imu/st_lsm6dsx/Kconfig" 129 129 source "drivers/iio/imu/st_lsm9ds0/Kconfig" 130 130
+2
drivers/iio/imu/Makefile
··· 25 25 obj-$(CONFIG_FXOS8700_SPI) += fxos8700_spi.o 26 26 27 27 obj-y += inv_icm42600/ 28 + obj-y += inv_icm45600/ 28 29 obj-y += inv_mpu6050/ 29 30 30 31 obj-$(CONFIG_KMX61) += kmx61.o 31 32 32 33 obj-$(CONFIG_SMI240) += smi240.o 33 34 35 + obj-y += smi330/ 34 36 obj-y += st_lsm6dsx/ 35 37 obj-y += st_lsm9ds0/
+361 -20
drivers/iio/imu/bmi270/bmi270_core.c
··· 31 31 32 32 #define BMI270_INT_STATUS_0_REG 0x1c 33 33 #define BMI270_INT_STATUS_0_STEP_CNT_MSK BIT(1) 34 + #define BMI270_INT_STATUS_0_NOMOTION_MSK BIT(5) 35 + #define BMI270_INT_STATUS_0_MOTION_MSK BIT(6) 34 36 35 37 #define BMI270_INT_STATUS_1_REG 0x1d 36 38 #define BMI270_INT_STATUS_1_ACC_GYR_DRDY_MSK GENMASK(7, 6) ··· 83 81 #define BMI270_INT1_MAP_FEAT_REG 0x56 84 82 #define BMI270_INT2_MAP_FEAT_REG 0x57 85 83 #define BMI270_INT_MAP_FEAT_STEP_CNT_WTRMRK_MSK BIT(1) 84 + #define BMI270_INT_MAP_FEAT_NOMOTION_MSK BIT(5) 85 + #define BMI270_INT_MAP_FEAT_ANYMOTION_MSK BIT(6) 86 86 87 87 #define BMI270_INT_MAP_DATA_REG 0x58 88 88 #define BMI270_INT_MAP_DATA_DRDY_INT1_MSK BIT(2) ··· 110 106 #define BMI270_STEP_SC26_RST_CNT_MSK BIT(10) 111 107 #define BMI270_STEP_SC26_EN_CNT_MSK BIT(12) 112 108 109 + #define BMI270_FEAT_MOTION_DURATION_MSK GENMASK(12, 0) 110 + #define BMI270_FEAT_MOTION_X_EN_MSK BIT(13) 111 + #define BMI270_FEAT_MOTION_Y_EN_MSK BIT(14) 112 + #define BMI270_FEAT_MOTION_Z_EN_MSK BIT(15) 113 + #define BMI270_FEAT_MOTION_XYZ_EN_MSK GENMASK(15, 13) 114 + #define BMI270_FEAT_MOTION_THRESHOLD_MSK GENMASK(10, 0) 115 + #define BMI270_FEAT_MOTION_OUT_CONF_MSK GENMASK(14, 11) 116 + #define BMI270_FEAT_MOTION_ENABLE_MSK BIT(15) 117 + 118 + #define BMI270_MOTION_XYZ_MSK GENMASK(2, 0) 119 + 120 + /* See pages 92 and 93 of the datasheet */ 121 + #define BMI270_MOTION_THRES_FULL_SCALE GENMASK(10, 0) 122 + #define BMI270_MOTION_DURAT_SCALE 50 123 + #define BMI270_MOTION_DURAT_MAX 162 124 + 125 + /* 9.81 * 1000000 m/s^2 */ 126 + #define BMI270_G_MICRO_M_S_2 9810000 127 + 113 128 /* See datasheet section 4.6.14, Temperature Sensor */ 114 129 #define BMI270_TEMP_OFFSET 11776 115 130 #define BMI270_TEMP_SCALE 1953125 ··· 136 113 /* See page 90 of datasheet. The step counter "holds implicitly a 20x factor" */ 137 114 #define BMI270_STEP_COUNTER_FACTOR 20 138 115 #define BMI270_STEP_COUNTER_MAX 20460 116 + 117 + #define BMI270_INT_MICRO_TO_RAW(val, val2, scale) \ 118 + ((val) * (scale) + ((val2) * (scale)) / MEGA) 119 + #define BMI270_RAW_TO_MICRO(raw, scale) \ 120 + ((((raw) % (scale)) * MEGA) / scale) 139 121 140 122 #define BMI260_INIT_DATA_FILE "bmi260-init-data.fw" 141 123 #define BMI270_INIT_DATA_FILE "bmi270-init-data.fw" ··· 337 309 }; 338 310 339 311 enum bmi270_feature_reg_id { 312 + /* Page 1 registers */ 313 + BMI270_ANYMO1_REG, 314 + BMI270_ANYMO2_REG, 315 + /* Page 2 registers */ 316 + BMI270_NOMO1_REG, 317 + BMI270_NOMO2_REG, 318 + /* Page 6 registers */ 340 319 BMI270_SC_26_REG, 341 320 }; 342 321 ··· 353 318 }; 354 319 355 320 static const struct bmi270_feature_reg bmi270_feature_regs[] = { 321 + [BMI270_ANYMO1_REG] = { 322 + .page = 1, 323 + .addr = 0x3c, 324 + }, 325 + [BMI270_ANYMO2_REG] = { 326 + .page = 1, 327 + .addr = 0x3e, 328 + }, 329 + [BMI270_NOMO1_REG] = { 330 + .page = 2, 331 + .addr = 0x30, 332 + }, 333 + [BMI270_NOMO2_REG] = { 334 + .page = 2, 335 + .addr = 0x32, 336 + }, 356 337 [BMI270_SC_26_REG] = { 357 338 .page = 6, 358 339 .addr = 0x32, ··· 490 439 state)); 491 440 } 492 441 442 + static int bmi270_motion_reg(enum iio_event_type type, enum iio_event_info info) 443 + { 444 + switch (info) { 445 + case IIO_EV_INFO_PERIOD: 446 + switch (type) { 447 + case IIO_EV_TYPE_MAG_ADAPTIVE: 448 + return BMI270_ANYMO1_REG; 449 + case IIO_EV_TYPE_ROC: 450 + return BMI270_NOMO1_REG; 451 + default: 452 + return -EINVAL; 453 + } 454 + case IIO_EV_INFO_VALUE: 455 + switch (type) { 456 + case IIO_EV_TYPE_MAG_ADAPTIVE: 457 + return BMI270_ANYMO2_REG; 458 + case IIO_EV_TYPE_ROC: 459 + return BMI270_NOMO2_REG; 460 + default: 461 + return -EINVAL; 462 + } 463 + default: 464 + return -EINVAL; 465 + } 466 + } 467 + 468 + static int bmi270_anymotion_event_en(struct bmi270_data *data, 469 + struct iio_chan_spec const *chan, 470 + bool state) 471 + { 472 + u16 axis_msk, axis_field_val, regval; 473 + int ret, irq_reg; 474 + bool axis_en; 475 + 476 + irq_reg = bmi270_int_map_reg(data->irq_pin); 477 + if (irq_reg < 0) 478 + return irq_reg; 479 + 480 + guard(mutex)(&data->mutex); 481 + 482 + ret = bmi270_read_feature_reg(data, BMI270_ANYMO1_REG, &regval); 483 + if (ret) 484 + return ret; 485 + 486 + switch (chan->channel2) { 487 + case IIO_MOD_X: 488 + axis_msk = BMI270_FEAT_MOTION_X_EN_MSK; 489 + axis_field_val = FIELD_PREP(BMI270_FEAT_MOTION_X_EN_MSK, state); 490 + axis_en = FIELD_GET(BMI270_FEAT_MOTION_Y_EN_MSK, regval) | 491 + FIELD_GET(BMI270_FEAT_MOTION_Z_EN_MSK, regval); 492 + break; 493 + case IIO_MOD_Y: 494 + axis_msk = BMI270_FEAT_MOTION_Y_EN_MSK; 495 + axis_field_val = FIELD_PREP(BMI270_FEAT_MOTION_Y_EN_MSK, state); 496 + axis_en = FIELD_GET(BMI270_FEAT_MOTION_X_EN_MSK, regval) | 497 + FIELD_GET(BMI270_FEAT_MOTION_Z_EN_MSK, regval); 498 + break; 499 + case IIO_MOD_Z: 500 + axis_msk = BMI270_FEAT_MOTION_Z_EN_MSK; 501 + axis_field_val = FIELD_PREP(BMI270_FEAT_MOTION_Z_EN_MSK, state); 502 + axis_en = FIELD_GET(BMI270_FEAT_MOTION_X_EN_MSK, regval) | 503 + FIELD_GET(BMI270_FEAT_MOTION_Y_EN_MSK, regval); 504 + break; 505 + default: 506 + return -EINVAL; 507 + } 508 + 509 + ret = bmi270_update_feature_reg(data, BMI270_ANYMO1_REG, axis_msk, 510 + axis_field_val); 511 + if (ret) 512 + return ret; 513 + 514 + ret = bmi270_update_feature_reg(data, BMI270_ANYMO2_REG, 515 + BMI270_FEAT_MOTION_ENABLE_MSK, 516 + FIELD_PREP(BMI270_FEAT_MOTION_ENABLE_MSK, 517 + state || axis_en)); 518 + if (ret) 519 + return ret; 520 + 521 + return regmap_update_bits(data->regmap, irq_reg, 522 + BMI270_INT_MAP_FEAT_ANYMOTION_MSK, 523 + FIELD_PREP(BMI270_INT_MAP_FEAT_ANYMOTION_MSK, 524 + state || axis_en)); 525 + } 526 + 527 + static int bmi270_nomotion_event_en(struct bmi270_data *data, bool state) 528 + { 529 + int ret, irq_reg; 530 + 531 + irq_reg = bmi270_int_map_reg(data->irq_pin); 532 + if (irq_reg < 0) 533 + return irq_reg; 534 + 535 + guard(mutex)(&data->mutex); 536 + 537 + ret = bmi270_update_feature_reg(data, BMI270_NOMO1_REG, 538 + BMI270_FEAT_MOTION_XYZ_EN_MSK, 539 + FIELD_PREP(BMI270_FEAT_MOTION_XYZ_EN_MSK, 540 + state ? BMI270_MOTION_XYZ_MSK : 0)); 541 + if (ret) 542 + return ret; 543 + 544 + ret = bmi270_update_feature_reg(data, BMI270_NOMO2_REG, 545 + BMI270_FEAT_MOTION_ENABLE_MSK, 546 + FIELD_PREP(BMI270_FEAT_MOTION_ENABLE_MSK, 547 + state)); 548 + if (ret) 549 + return ret; 550 + 551 + return regmap_update_bits(data->regmap, irq_reg, 552 + BMI270_INT_MAP_FEAT_NOMOTION_MSK, 553 + FIELD_PREP(BMI270_INT_MAP_FEAT_NOMOTION_MSK, 554 + state)); 555 + } 556 + 493 557 static int bmi270_set_scale(struct bmi270_data *data, int chan_type, int uscale) 494 558 { 495 559 int i; ··· 644 478 int ret; 645 479 unsigned int val; 646 480 struct bmi270_scale_item bmi270_scale_item; 647 - 648 - guard(mutex)(&data->mutex); 649 481 650 482 switch (chan_type) { 651 483 case IIO_ACCEL: ··· 777 613 778 614 if (FIELD_GET(BMI270_INT_STATUS_1_ACC_GYR_DRDY_MSK, status1)) 779 615 iio_trigger_poll_nested(data->trig); 616 + 617 + if (FIELD_GET(BMI270_INT_STATUS_0_MOTION_MSK, status0)) 618 + iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, 619 + IIO_MOD_X_OR_Y_OR_Z, 620 + IIO_EV_TYPE_MAG_ADAPTIVE, 621 + IIO_EV_DIR_RISING), 622 + timestamp); 623 + 624 + if (FIELD_GET(BMI270_INT_STATUS_0_NOMOTION_MSK, status0)) 625 + iio_push_event(indio_dev, IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, 626 + IIO_MOD_X_AND_Y_AND_Z, 627 + IIO_EV_TYPE_ROC, 628 + IIO_EV_DIR_RISING), 629 + timestamp); 780 630 781 631 if (FIELD_GET(BMI270_INT_STATUS_0_STEP_CNT_MSK, status0)) 782 632 iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_STEPS, 0, ··· 1005 827 } 1006 828 } 1007 829 830 + static ssize_t in_accel_value_available_show(struct device *dev, 831 + struct device_attribute *attr, 832 + char *buf) 833 + { 834 + struct iio_dev *indio_dev = dev_to_iio_dev(dev); 835 + struct bmi270_data *data = iio_priv(indio_dev); 836 + int ret, scale, uscale; 837 + unsigned int step, max; 838 + 839 + ret = bmi270_get_scale(data, IIO_ACCEL, &scale, &uscale); 840 + if (ret) 841 + return ret; 842 + 843 + max = BMI270_G_MICRO_M_S_2 / uscale; 844 + step = max / BMI270_MOTION_THRES_FULL_SCALE; 845 + 846 + return sysfs_emit(buf, "[0 %u %u]\n", step, max); 847 + } 848 + 849 + static IIO_DEVICE_ATTR_RO(in_accel_value_available, 0); 850 + 851 + static IIO_CONST_ATTR(in_accel_period_available, "[0.0 0.02 162.0]"); 852 + 853 + static struct attribute *bmi270_event_attributes[] = { 854 + &iio_dev_attr_in_accel_value_available.dev_attr.attr, 855 + &iio_const_attr_in_accel_period_available.dev_attr.attr, 856 + NULL 857 + }; 858 + 859 + static const struct attribute_group bmi270_event_attribute_group = { 860 + .attrs = bmi270_event_attributes, 861 + }; 862 + 1008 863 static int bmi270_write_event_config(struct iio_dev *indio_dev, 1009 864 const struct iio_chan_spec *chan, 1010 865 enum iio_event_type type, ··· 1046 835 struct bmi270_data *data = iio_priv(indio_dev); 1047 836 1048 837 switch (type) { 838 + case IIO_EV_TYPE_MAG_ADAPTIVE: 839 + return bmi270_anymotion_event_en(data, chan, state); 840 + case IIO_EV_TYPE_ROC: 841 + return bmi270_nomotion_event_en(data, state); 1049 842 case IIO_EV_TYPE_CHANGE: 1050 843 return bmi270_step_wtrmrk_en(data, state); 1051 844 default: ··· 1063 848 enum iio_event_direction dir) 1064 849 { 1065 850 struct bmi270_data *data = iio_priv(indio_dev); 851 + bool feat_en, axis_en; 1066 852 int ret, reg, regval; 853 + u16 motion_reg; 1067 854 1068 855 guard(mutex)(&data->mutex); 1069 856 857 + reg = bmi270_int_map_reg(data->irq_pin); 858 + if (reg < 0) 859 + return reg; 860 + 861 + ret = regmap_read(data->regmap, reg, &regval); 862 + if (ret) 863 + return ret; 864 + 1070 865 switch (chan->type) { 1071 866 case IIO_STEPS: 1072 - reg = bmi270_int_map_reg(data->irq_pin); 1073 - if (reg) 1074 - return reg; 867 + return !!FIELD_GET(BMI270_INT_MAP_FEAT_STEP_CNT_WTRMRK_MSK, regval); 868 + case IIO_ACCEL: 869 + switch (type) { 870 + case IIO_EV_TYPE_ROC: 871 + return !!FIELD_GET(BMI270_INT_MAP_FEAT_NOMOTION_MSK, regval); 872 + case IIO_EV_TYPE_MAG_ADAPTIVE: 873 + ret = bmi270_read_feature_reg(data, BMI270_ANYMO1_REG, 874 + &motion_reg); 875 + if (ret) 876 + return ret; 1075 877 1076 - ret = regmap_read(data->regmap, reg, &regval); 1077 - if (ret) 1078 - return ret; 1079 - return FIELD_GET(BMI270_INT_MAP_FEAT_STEP_CNT_WTRMRK_MSK, 1080 - regval) ? 1 : 0; 878 + feat_en = FIELD_GET(BMI270_INT_MAP_FEAT_ANYMOTION_MSK, 879 + regval); 880 + switch (chan->channel2) { 881 + case IIO_MOD_X: 882 + axis_en = FIELD_GET(BMI270_FEAT_MOTION_X_EN_MSK, 883 + motion_reg); 884 + break; 885 + case IIO_MOD_Y: 886 + axis_en = FIELD_GET(BMI270_FEAT_MOTION_Y_EN_MSK, 887 + motion_reg); 888 + break; 889 + case IIO_MOD_Z: 890 + axis_en = FIELD_GET(BMI270_FEAT_MOTION_Z_EN_MSK, 891 + motion_reg); 892 + break; 893 + default: 894 + return -EINVAL; 895 + } 896 + return axis_en && feat_en; 897 + default: 898 + return -EINVAL; 899 + } 1081 900 default: 1082 901 return -EINVAL; 1083 902 } ··· 1125 876 int val, int val2) 1126 877 { 1127 878 struct bmi270_data *data = iio_priv(indio_dev); 1128 - unsigned int raw; 879 + unsigned int raw, mask, regval; 880 + int ret, reg, scale, uscale; 881 + u64 tmp; 1129 882 1130 883 guard(mutex)(&data->mutex); 1131 884 1132 - switch (type) { 1133 - case IIO_EV_TYPE_CHANGE: 885 + if (type == IIO_EV_TYPE_CHANGE) { 1134 886 if (!in_range(val, 0, BMI270_STEP_COUNTER_MAX + 1)) 1135 887 return -EINVAL; 1136 888 1137 889 raw = val / BMI270_STEP_COUNTER_FACTOR; 1138 - return bmi270_update_feature_reg(data, BMI270_SC_26_REG, 1139 - BMI270_STEP_SC26_WTRMRK_MSK, 1140 - FIELD_PREP(BMI270_STEP_SC26_WTRMRK_MSK, 1141 - raw)); 890 + mask = BMI270_STEP_SC26_WTRMRK_MSK; 891 + regval = FIELD_PREP(BMI270_STEP_SC26_WTRMRK_MSK, raw); 892 + return bmi270_update_feature_reg(data, BMI270_SC_26_REG, mask, 893 + regval); 894 + } 895 + 896 + reg = bmi270_motion_reg(type, info); 897 + if (reg < 0) 898 + return reg; 899 + 900 + switch (info) { 901 + case IIO_EV_INFO_VALUE: 902 + ret = bmi270_get_scale(data, IIO_ACCEL, &scale, &uscale); 903 + if (ret) 904 + return ret; 905 + 906 + if (!in_range(val, 0, (BMI270_G_MICRO_M_S_2 / uscale) + 1)) 907 + return -EINVAL; 908 + 909 + tmp = (u64)val * BMI270_MOTION_THRES_FULL_SCALE * uscale; 910 + raw = DIV_ROUND_CLOSEST_ULL(tmp, BMI270_G_MICRO_M_S_2); 911 + mask = BMI270_FEAT_MOTION_THRESHOLD_MSK; 912 + regval = FIELD_PREP(BMI270_FEAT_MOTION_THRESHOLD_MSK, raw); 913 + return bmi270_update_feature_reg(data, reg, mask, regval); 914 + case IIO_EV_INFO_PERIOD: 915 + if (!in_range(val, 0, BMI270_MOTION_DURAT_MAX + 1)) 916 + return -EINVAL; 917 + 918 + raw = BMI270_INT_MICRO_TO_RAW(val, val2, 919 + BMI270_MOTION_DURAT_SCALE); 920 + mask = BMI270_FEAT_MOTION_DURATION_MSK; 921 + regval = FIELD_PREP(BMI270_FEAT_MOTION_DURATION_MSK, raw); 922 + return bmi270_update_feature_reg(data, reg, mask, regval); 1142 923 default: 1143 924 return -EINVAL; 1144 925 } ··· 1182 903 int *val, int *val2) 1183 904 { 1184 905 struct bmi270_data *data = iio_priv(indio_dev); 906 + int ret, reg, scale, uscale; 1185 907 unsigned int raw; 1186 908 u16 regval; 1187 - int ret; 909 + u64 tmp; 1188 910 1189 911 guard(mutex)(&data->mutex); 1190 912 1191 - switch (type) { 1192 - case IIO_EV_TYPE_CHANGE: 913 + if (type == IIO_EV_TYPE_CHANGE) { 1193 914 ret = bmi270_read_feature_reg(data, BMI270_SC_26_REG, &regval); 1194 915 if (ret) 1195 916 return ret; ··· 1197 918 raw = FIELD_GET(BMI270_STEP_SC26_WTRMRK_MSK, regval); 1198 919 *val = raw * BMI270_STEP_COUNTER_FACTOR; 1199 920 return IIO_VAL_INT; 921 + } 922 + 923 + reg = bmi270_motion_reg(type, info); 924 + if (reg < 0) 925 + return reg; 926 + 927 + switch (info) { 928 + case IIO_EV_INFO_VALUE: 929 + ret = bmi270_read_feature_reg(data, reg, &regval); 930 + if (ret) 931 + return ret; 932 + 933 + ret = bmi270_get_scale(data, IIO_ACCEL, &scale, &uscale); 934 + if (ret) 935 + return ret; 936 + 937 + raw = FIELD_GET(BMI270_FEAT_MOTION_THRESHOLD_MSK, regval); 938 + tmp = (u64)raw * BMI270_G_MICRO_M_S_2; 939 + *val = DIV_ROUND_CLOSEST_ULL(tmp, 940 + BMI270_MOTION_THRES_FULL_SCALE * uscale); 941 + return IIO_VAL_INT; 942 + case IIO_EV_INFO_PERIOD: 943 + ret = bmi270_read_feature_reg(data, reg, &regval); 944 + if (ret) 945 + return ret; 946 + 947 + raw = FIELD_GET(BMI270_FEAT_MOTION_DURATION_MSK, regval); 948 + *val = raw / BMI270_MOTION_DURAT_SCALE; 949 + *val2 = BMI270_RAW_TO_MICRO(raw, BMI270_MOTION_DURAT_SCALE); 950 + return IIO_VAL_INT_PLUS_MICRO; 1200 951 default: 1201 952 return -EINVAL; 1202 953 } ··· 1238 929 .mask_shared_by_type = BIT(IIO_EV_INFO_ENABLE) | BIT(IIO_EV_INFO_VALUE), 1239 930 }; 1240 931 932 + static const struct iio_event_spec bmi270_anymotion_event = { 933 + .type = IIO_EV_TYPE_MAG_ADAPTIVE, 934 + .dir = IIO_EV_DIR_RISING, 935 + .mask_separate = BIT(IIO_EV_INFO_ENABLE), 936 + .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_PERIOD), 937 + }; 938 + 939 + static const struct iio_event_spec bmi270_nomotion_event = { 940 + .type = IIO_EV_TYPE_ROC, 941 + .dir = IIO_EV_DIR_RISING, 942 + .mask_separate = BIT(IIO_EV_INFO_ENABLE), 943 + .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE) | BIT(IIO_EV_INFO_PERIOD), 944 + }; 945 + 1241 946 static const struct iio_info bmi270_info = { 1242 947 .read_raw = bmi270_read_raw, 1243 948 .write_raw = bmi270_write_raw, ··· 1260 937 .read_event_config = bmi270_read_event_config, 1261 938 .write_event_value = bmi270_write_event_value, 1262 939 .read_event_value = bmi270_read_event_value, 940 + .event_attrs = &bmi270_event_attribute_group, 1263 941 }; 1264 942 1265 943 #define BMI270_ACCEL_CHANNEL(_axis) { \ ··· 1280 956 .storagebits = 16, \ 1281 957 .endianness = IIO_LE, \ 1282 958 }, \ 959 + .event_spec = &bmi270_anymotion_event, \ 960 + .num_event_specs = 1, \ 1283 961 } 1284 962 1285 963 #define BMI270_ANG_VEL_CHANNEL(_axis) { \ ··· 1326 1000 .num_event_specs = 1, 1327 1001 }, 1328 1002 IIO_CHAN_SOFT_TIMESTAMP(BMI270_SCAN_TIMESTAMP), 1003 + { 1004 + .type = IIO_ACCEL, 1005 + .modified = 1, 1006 + .channel2 = IIO_MOD_X_AND_Y_AND_Z, 1007 + .scan_index = -1, /* Fake channel */ 1008 + .event_spec = &bmi270_nomotion_event, 1009 + .num_event_specs = 1, 1010 + }, 1329 1011 }; 1330 1012 1331 1013 static int bmi270_int_pin_config(struct bmi270_data *data, ··· 1440 1106 if (ret) 1441 1107 return dev_err_probe(data->dev, ret, 1442 1108 "Trigger registration failed\n"); 1109 + 1110 + /* Disable axes for motion events */ 1111 + ret = bmi270_update_feature_reg(data, BMI270_ANYMO1_REG, 1112 + BMI270_FEAT_MOTION_XYZ_EN_MSK, 1113 + FIELD_PREP(BMI270_FEAT_MOTION_XYZ_EN_MSK, 0)); 1114 + if (ret) 1115 + return ret; 1443 1116 1444 1117 data->irq_pin = irq_pin; 1445 1118
+1 -1
drivers/iio/imu/bmi270/bmi270_spi.c
··· 60 60 &bmi270_spi_regmap_config); 61 61 if (IS_ERR(regmap)) 62 62 return dev_err_probe(dev, PTR_ERR(regmap), 63 - "Failed to init i2c regmap"); 63 + "Failed to init spi regmap\n"); 64 64 65 65 return bmi270_core_probe(dev, regmap, chip_info); 66 66 }
+70
drivers/iio/imu/inv_icm45600/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + config INV_ICM45600 4 + tristate 5 + select IIO_BUFFER 6 + select IIO_KFIFO_BUF 7 + select IIO_INV_SENSORS_TIMESTAMP 8 + 9 + config INV_ICM45600_I2C 10 + tristate "InvenSense ICM-456xx I2C driver" 11 + depends on I2C 12 + select INV_ICM45600 13 + select REGMAP_I2C 14 + help 15 + This driver supports the InvenSense ICM-456xx motion tracking 16 + devices over I2C. 17 + Supported devices: 18 + - ICM-45605 19 + - ICM-45606 20 + - ICM-45608 21 + - ICM-45634 22 + - ICM-45686 23 + - ICM-45687 24 + - ICM-45688-P 25 + - ICM-45689 26 + 27 + This driver can be built as a module. The module will be called 28 + inv-icm45600-i2c. 29 + 30 + config INV_ICM45600_SPI 31 + tristate "InvenSense ICM-456xx SPI driver" 32 + depends on SPI_MASTER 33 + select INV_ICM45600 34 + select REGMAP_SPI 35 + help 36 + This driver supports the InvenSense ICM-456xx motion tracking 37 + devices over SPI. 38 + Supported devices: 39 + - ICM-45605 40 + - ICM-45606 41 + - ICM-45608 42 + - ICM-45634 43 + - ICM-45686 44 + - ICM-45687 45 + - ICM-45688-P 46 + - ICM-45689 47 + 48 + This driver can be built as a module. The module will be called 49 + inv-icm45600-spi. 50 + 51 + config INV_ICM45600_I3C 52 + tristate "InvenSense ICM-456xx I3C driver" 53 + depends on I3C 54 + select INV_ICM45600 55 + select REGMAP_I3C 56 + help 57 + This driver supports the InvenSense ICM-456xx motion tracking 58 + devices over I3C. 59 + Supported devices: 60 + - ICM-45605 61 + - ICM-45606 62 + - ICM-45608 63 + - ICM-45634 64 + - ICM-45686 65 + - ICM-45687 66 + - ICM-45688-P 67 + - ICM-45689 68 + 69 + This driver can be built as a module. The module will be called 70 + inv-icm45600-i3c.
+16
drivers/iio/imu/inv_icm45600/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + obj-$(CONFIG_INV_ICM45600) += inv-icm45600.o 4 + inv-icm45600-y += inv_icm45600_core.o 5 + inv-icm45600-y += inv_icm45600_buffer.o 6 + inv-icm45600-y += inv_icm45600_gyro.o 7 + inv-icm45600-y += inv_icm45600_accel.o 8 + 9 + obj-$(CONFIG_INV_ICM45600_I2C) += inv-icm45600-i2c.o 10 + inv-icm45600-i2c-y += inv_icm45600_i2c.o 11 + 12 + obj-$(CONFIG_INV_ICM45600_SPI) += inv-icm45600-spi.o 13 + inv-icm45600-spi-y += inv_icm45600_spi.o 14 + 15 + obj-$(CONFIG_INV_ICM45600_I3C) += inv-icm45600-i3c.o 16 + inv-icm45600-i3c-y += inv_icm45600_i3c.o
+385
drivers/iio/imu/inv_icm45600/inv_icm45600.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* Copyright (C) 2025 Invensense, Inc. */ 3 + 4 + #ifndef INV_ICM45600_H_ 5 + #define INV_ICM45600_H_ 6 + 7 + #include <linux/bits.h> 8 + #include <linux/limits.h> 9 + #include <linux/mutex.h> 10 + #include <linux/regmap.h> 11 + #include <linux/regulator/consumer.h> 12 + #include <linux/sizes.h> 13 + #include <linux/types.h> 14 + 15 + #include <linux/iio/common/inv_sensors_timestamp.h> 16 + #include <linux/iio/iio.h> 17 + 18 + #include "inv_icm45600_buffer.h" 19 + 20 + #define INV_ICM45600_REG_BANK_MASK GENMASK(15, 8) 21 + #define INV_ICM45600_REG_ADDR_MASK GENMASK(7, 0) 22 + 23 + enum inv_icm45600_sensor_mode { 24 + INV_ICM45600_SENSOR_MODE_OFF, 25 + INV_ICM45600_SENSOR_MODE_STANDBY, 26 + INV_ICM45600_SENSOR_MODE_LOW_POWER, 27 + INV_ICM45600_SENSOR_MODE_LOW_NOISE, 28 + INV_ICM45600_SENSOR_MODE_MAX 29 + }; 30 + 31 + /* gyroscope fullscale values */ 32 + enum inv_icm45600_gyro_fs { 33 + INV_ICM45600_GYRO_FS_2000DPS, 34 + INV_ICM45600_GYRO_FS_1000DPS, 35 + INV_ICM45600_GYRO_FS_500DPS, 36 + INV_ICM45600_GYRO_FS_250DPS, 37 + INV_ICM45600_GYRO_FS_125DPS, 38 + INV_ICM45600_GYRO_FS_62_5DPS, 39 + INV_ICM45600_GYRO_FS_31_25DPS, 40 + INV_ICM45600_GYRO_FS_15_625DPS, 41 + INV_ICM45600_GYRO_FS_MAX 42 + }; 43 + 44 + enum inv_icm45686_gyro_fs { 45 + INV_ICM45686_GYRO_FS_4000DPS, 46 + INV_ICM45686_GYRO_FS_2000DPS, 47 + INV_ICM45686_GYRO_FS_1000DPS, 48 + INV_ICM45686_GYRO_FS_500DPS, 49 + INV_ICM45686_GYRO_FS_250DPS, 50 + INV_ICM45686_GYRO_FS_125DPS, 51 + INV_ICM45686_GYRO_FS_62_5DPS, 52 + INV_ICM45686_GYRO_FS_31_25DPS, 53 + INV_ICM45686_GYRO_FS_15_625DPS, 54 + INV_ICM45686_GYRO_FS_MAX 55 + }; 56 + 57 + /* accelerometer fullscale values */ 58 + enum inv_icm45600_accel_fs { 59 + INV_ICM45600_ACCEL_FS_16G, 60 + INV_ICM45600_ACCEL_FS_8G, 61 + INV_ICM45600_ACCEL_FS_4G, 62 + INV_ICM45600_ACCEL_FS_2G, 63 + INV_ICM45600_ACCEL_FS_MAX 64 + }; 65 + 66 + enum inv_icm45686_accel_fs { 67 + INV_ICM45686_ACCEL_FS_32G, 68 + INV_ICM45686_ACCEL_FS_16G, 69 + INV_ICM45686_ACCEL_FS_8G, 70 + INV_ICM45686_ACCEL_FS_4G, 71 + INV_ICM45686_ACCEL_FS_2G, 72 + INV_ICM45686_ACCEL_FS_MAX 73 + }; 74 + 75 + /* ODR suffixed by LN or LP are Low-Noise or Low-Power mode only */ 76 + enum inv_icm45600_odr { 77 + INV_ICM45600_ODR_6400HZ_LN = 0x03, 78 + INV_ICM45600_ODR_3200HZ_LN, 79 + INV_ICM45600_ODR_1600HZ_LN, 80 + INV_ICM45600_ODR_800HZ_LN, 81 + INV_ICM45600_ODR_400HZ, 82 + INV_ICM45600_ODR_200HZ, 83 + INV_ICM45600_ODR_100HZ, 84 + INV_ICM45600_ODR_50HZ, 85 + INV_ICM45600_ODR_25HZ, 86 + INV_ICM45600_ODR_12_5HZ, 87 + INV_ICM45600_ODR_6_25HZ_LP, 88 + INV_ICM45600_ODR_3_125HZ_LP, 89 + INV_ICM45600_ODR_1_5625HZ_LP, 90 + INV_ICM45600_ODR_MAX 91 + }; 92 + 93 + struct inv_icm45600_sensor_conf { 94 + u8 mode; 95 + u8 fs; 96 + u8 odr; 97 + u8 filter; 98 + }; 99 + 100 + #define INV_ICM45600_SENSOR_CONF_KEEP_VALUES { U8_MAX, U8_MAX, U8_MAX, U8_MAX } 101 + 102 + struct inv_icm45600_conf { 103 + struct inv_icm45600_sensor_conf gyro; 104 + struct inv_icm45600_sensor_conf accel; 105 + }; 106 + 107 + struct inv_icm45600_suspended { 108 + enum inv_icm45600_sensor_mode gyro; 109 + enum inv_icm45600_sensor_mode accel; 110 + }; 111 + 112 + struct inv_icm45600_chip_info { 113 + u8 whoami; 114 + const char *name; 115 + const struct inv_icm45600_conf *conf; 116 + const int *accel_scales; 117 + const int accel_scales_len; 118 + const int *gyro_scales; 119 + const int gyro_scales_len; 120 + }; 121 + 122 + extern const struct inv_icm45600_chip_info inv_icm45605_chip_info; 123 + extern const struct inv_icm45600_chip_info inv_icm45606_chip_info; 124 + extern const struct inv_icm45600_chip_info inv_icm45608_chip_info; 125 + extern const struct inv_icm45600_chip_info inv_icm45634_chip_info; 126 + extern const struct inv_icm45600_chip_info inv_icm45686_chip_info; 127 + extern const struct inv_icm45600_chip_info inv_icm45687_chip_info; 128 + extern const struct inv_icm45600_chip_info inv_icm45688p_chip_info; 129 + extern const struct inv_icm45600_chip_info inv_icm45689_chip_info; 130 + 131 + extern const int inv_icm45600_accel_scale[][2]; 132 + extern const int inv_icm45686_accel_scale[][2]; 133 + extern const int inv_icm45600_gyro_scale[][2]; 134 + extern const int inv_icm45686_gyro_scale[][2]; 135 + 136 + /** 137 + * struct inv_icm45600_state - driver state variables 138 + * @lock: lock for serializing multiple registers access. 139 + * @map: regmap pointer. 140 + * @vddio_supply: I/O voltage regulator for the chip. 141 + * @orientation: sensor chip orientation relative to main hardware. 142 + * @conf: chip sensors configurations. 143 + * @suspended: suspended sensors configuration. 144 + * @indio_gyro: gyroscope IIO device. 145 + * @indio_accel: accelerometer IIO device. 146 + * @chip_info: chip driver data. 147 + * @timestamp: interrupt timestamps. 148 + * @fifo: FIFO management structure. 149 + * @buffer: data transfer buffer aligned for DMA. 150 + */ 151 + struct inv_icm45600_state { 152 + struct mutex lock; 153 + struct regmap *map; 154 + struct regulator *vddio_supply; 155 + struct iio_mount_matrix orientation; 156 + struct inv_icm45600_conf conf; 157 + struct inv_icm45600_suspended suspended; 158 + struct iio_dev *indio_gyro; 159 + struct iio_dev *indio_accel; 160 + const struct inv_icm45600_chip_info *chip_info; 161 + struct { 162 + s64 gyro; 163 + s64 accel; 164 + } timestamp; 165 + struct inv_icm45600_fifo fifo; 166 + union { 167 + u8 buff[2]; 168 + __le16 u16; 169 + u8 ireg[3]; 170 + } buffer __aligned(IIO_DMA_MINALIGN); 171 + }; 172 + 173 + /** 174 + * struct inv_icm45600_sensor_state - sensor state variables 175 + * @scales: table of scales. 176 + * @scales_len: length (nb of items) of the scales table. 177 + * @power_mode: sensor requested power mode (for common frequencies) 178 + * @ts: timestamp module states. 179 + */ 180 + struct inv_icm45600_sensor_state { 181 + const int *scales; 182 + size_t scales_len; 183 + enum inv_icm45600_sensor_mode power_mode; 184 + struct inv_sensors_timestamp ts; 185 + }; 186 + 187 + /* Virtual register addresses: @bank on MSB (16 bits), @address on LSB */ 188 + 189 + /* Indirect register access */ 190 + #define INV_ICM45600_REG_IREG_ADDR 0x7C 191 + #define INV_ICM45600_REG_IREG_DATA 0x7E 192 + 193 + /* Direct acces registers */ 194 + #define INV_ICM45600_REG_MISC2 0x007F 195 + #define INV_ICM45600_MISC2_SOFT_RESET BIT(1) 196 + 197 + #define INV_ICM45600_REG_DRIVE_CONFIG0 0x0032 198 + #define INV_ICM45600_DRIVE_CONFIG0_SPI_MASK GENMASK(3, 1) 199 + #define INV_ICM45600_SPI_SLEW_RATE_0_5NS 6 200 + #define INV_ICM45600_SPI_SLEW_RATE_4NS 5 201 + #define INV_ICM45600_SPI_SLEW_RATE_5NS 4 202 + #define INV_ICM45600_SPI_SLEW_RATE_7NS 3 203 + #define INV_ICM45600_SPI_SLEW_RATE_10NS 2 204 + #define INV_ICM45600_SPI_SLEW_RATE_14NS 1 205 + #define INV_ICM45600_SPI_SLEW_RATE_38NS 0 206 + 207 + #define INV_ICM45600_REG_INT1_CONFIG2 0x0018 208 + #define INV_ICM45600_INT1_CONFIG2_PUSH_PULL BIT(2) 209 + #define INV_ICM45600_INT1_CONFIG2_LATCHED BIT(1) 210 + #define INV_ICM45600_INT1_CONFIG2_ACTIVE_HIGH BIT(0) 211 + #define INV_ICM45600_INT1_CONFIG2_ACTIVE_LOW 0x00 212 + 213 + #define INV_ICM45600_REG_FIFO_CONFIG0 0x001D 214 + #define INV_ICM45600_FIFO_CONFIG0_MODE_MASK GENMASK(7, 6) 215 + #define INV_ICM45600_FIFO_CONFIG0_MODE_BYPASS 0 216 + #define INV_ICM45600_FIFO_CONFIG0_MODE_STREAM 1 217 + #define INV_ICM45600_FIFO_CONFIG0_MODE_STOP_ON_FULL 2 218 + #define INV_ICM45600_FIFO_CONFIG0_FIFO_DEPTH_MASK GENMASK(5, 0) 219 + #define INV_ICM45600_FIFO_CONFIG0_FIFO_DEPTH_MAX 0x1F 220 + 221 + #define INV_ICM45600_REG_FIFO_CONFIG2 0x0020 222 + #define INV_ICM45600_REG_FIFO_CONFIG2_FIFO_FLUSH BIT(7) 223 + #define INV_ICM45600_REG_FIFO_CONFIG2_WM_GT_TH BIT(3) 224 + 225 + #define INV_ICM45600_REG_FIFO_CONFIG3 0x0021 226 + #define INV_ICM45600_FIFO_CONFIG3_ES1_EN BIT(5) 227 + #define INV_ICM45600_FIFO_CONFIG3_ES0_EN BIT(4) 228 + #define INV_ICM45600_FIFO_CONFIG3_HIRES_EN BIT(3) 229 + #define INV_ICM45600_FIFO_CONFIG3_GYRO_EN BIT(2) 230 + #define INV_ICM45600_FIFO_CONFIG3_ACCEL_EN BIT(1) 231 + #define INV_ICM45600_FIFO_CONFIG3_IF_EN BIT(0) 232 + 233 + #define INV_ICM45600_REG_FIFO_CONFIG4 0x0022 234 + #define INV_ICM45600_FIFO_CONFIG4_COMP_EN BIT(2) 235 + #define INV_ICM45600_FIFO_CONFIG4_TMST_FSYNC_EN BIT(1) 236 + #define INV_ICM45600_FIFO_CONFIG4_ES0_9B BIT(0) 237 + 238 + /* all sensor data are 16 bits (2 registers wide) in big-endian */ 239 + #define INV_ICM45600_REG_TEMP_DATA 0x000C 240 + #define INV_ICM45600_REG_ACCEL_DATA_X 0x0000 241 + #define INV_ICM45600_REG_ACCEL_DATA_Y 0x0002 242 + #define INV_ICM45600_REG_ACCEL_DATA_Z 0x0004 243 + #define INV_ICM45600_REG_GYRO_DATA_X 0x0006 244 + #define INV_ICM45600_REG_GYRO_DATA_Y 0x0008 245 + #define INV_ICM45600_REG_GYRO_DATA_Z 0x000A 246 + 247 + #define INV_ICM45600_REG_INT_STATUS 0x0019 248 + #define INV_ICM45600_INT_STATUS_RESET_DONE BIT(7) 249 + #define INV_ICM45600_INT_STATUS_AUX1_AGC_RDY BIT(6) 250 + #define INV_ICM45600_INT_STATUS_AP_AGC_RDY BIT(5) 251 + #define INV_ICM45600_INT_STATUS_AP_FSYNC BIT(4) 252 + #define INV_ICM45600_INT_STATUS_AUX1_DRDY BIT(3) 253 + #define INV_ICM45600_INT_STATUS_DATA_RDY BIT(2) 254 + #define INV_ICM45600_INT_STATUS_FIFO_THS BIT(1) 255 + #define INV_ICM45600_INT_STATUS_FIFO_FULL BIT(0) 256 + 257 + /* 258 + * FIFO access registers 259 + * FIFO count is 16 bits (2 registers) 260 + * FIFO data is a continuous read register to read FIFO content 261 + */ 262 + #define INV_ICM45600_REG_FIFO_COUNT 0x0012 263 + #define INV_ICM45600_REG_FIFO_DATA 0x0014 264 + 265 + #define INV_ICM45600_REG_PWR_MGMT0 0x0010 266 + #define INV_ICM45600_PWR_MGMT0_GYRO_MODE_MASK GENMASK(3, 2) 267 + #define INV_ICM45600_PWR_MGMT0_ACCEL_MODE_MASK GENMASK(1, 0) 268 + 269 + #define INV_ICM45600_REG_ACCEL_CONFIG0 0x001B 270 + #define INV_ICM45600_ACCEL_CONFIG0_FS_MASK GENMASK(6, 4) 271 + #define INV_ICM45600_ACCEL_CONFIG0_ODR_MASK GENMASK(3, 0) 272 + #define INV_ICM45600_REG_GYRO_CONFIG0 0x001C 273 + #define INV_ICM45600_GYRO_CONFIG0_FS_MASK GENMASK(7, 4) 274 + #define INV_ICM45600_GYRO_CONFIG0_ODR_MASK GENMASK(3, 0) 275 + 276 + #define INV_ICM45600_REG_SMC_CONTROL_0 0xA258 277 + #define INV_ICM45600_SMC_CONTROL_0_ACCEL_LP_CLK_SEL BIT(4) 278 + #define INV_ICM45600_SMC_CONTROL_0_TMST_EN BIT(0) 279 + 280 + /* FIFO watermark is 16 bits (2 registers wide) in little-endian */ 281 + #define INV_ICM45600_REG_FIFO_WATERMARK 0x001E 282 + 283 + /* FIFO is configured for 8kb */ 284 + #define INV_ICM45600_FIFO_SIZE_MAX SZ_8K 285 + 286 + #define INV_ICM45600_REG_INT1_CONFIG0 0x0016 287 + #define INV_ICM45600_INT1_CONFIG0_RESET_DONE_EN BIT(7) 288 + #define INV_ICM45600_INT1_CONFIG0_AUX1_AGC_RDY_EN BIT(6) 289 + #define INV_ICM45600_INT1_CONFIG0_AP_AGC_RDY_EN BIT(5) 290 + #define INV_ICM45600_INT1_CONFIG0_AP_FSYNC_EN BIT(4) 291 + #define INV_ICM45600_INT1_CONFIG0_AUX1_DRDY_EN BIT(3) 292 + #define INV_ICM45600_INT1_CONFIG0_DRDY_EN BIT(2) 293 + #define INV_ICM45600_INT1_CONFIG0_FIFO_THS_EN BIT(1) 294 + #define INV_ICM45600_INT1_CONFIG0_FIFO_FULL_EN BIT(0) 295 + 296 + #define INV_ICM45600_REG_WHOAMI 0x0072 297 + #define INV_ICM45600_WHOAMI_ICM45605 0xE5 298 + #define INV_ICM45600_WHOAMI_ICM45686 0xE9 299 + #define INV_ICM45600_WHOAMI_ICM45688P 0xE7 300 + #define INV_ICM45600_WHOAMI_ICM45608 0x81 301 + #define INV_ICM45600_WHOAMI_ICM45634 0x82 302 + #define INV_ICM45600_WHOAMI_ICM45689 0x83 303 + #define INV_ICM45600_WHOAMI_ICM45606 0x84 304 + #define INV_ICM45600_WHOAMI_ICM45687 0x85 305 + 306 + /* Gyro USER offset */ 307 + #define INV_ICM45600_IPREG_SYS1_REG_42 0xA42A 308 + #define INV_ICM45600_IPREG_SYS1_REG_56 0xA438 309 + #define INV_ICM45600_IPREG_SYS1_REG_70 0xA446 310 + #define INV_ICM45600_GYRO_OFFUSER_MASK GENMASK(13, 0) 311 + /* Gyro Averaging filter */ 312 + #define INV_ICM45600_IPREG_SYS1_REG_170 0xA4AA 313 + #define INV_ICM45600_IPREG_SYS1_170_GYRO_LP_AVG_MASK GENMASK(4, 1) 314 + #define INV_ICM45600_GYRO_LP_AVG_SEL_8X 5 315 + #define INV_ICM45600_GYRO_LP_AVG_SEL_2X 1 316 + /* Accel USER offset */ 317 + #define INV_ICM45600_IPREG_SYS2_REG_24 0xA518 318 + #define INV_ICM45600_IPREG_SYS2_REG_32 0xA520 319 + #define INV_ICM45600_IPREG_SYS2_REG_40 0xA528 320 + #define INV_ICM45600_ACCEL_OFFUSER_MASK GENMASK(13, 0) 321 + /* Accel averaging filter */ 322 + #define INV_ICM45600_IPREG_SYS2_REG_129 0xA581 323 + #define INV_ICM45600_ACCEL_LP_AVG_SEL_1X 0x0000 324 + #define INV_ICM45600_ACCEL_LP_AVG_SEL_4X 0x0002 325 + 326 + /* Sleep times required by the driver */ 327 + #define INV_ICM45600_ACCEL_STARTUP_TIME_MS 60 328 + #define INV_ICM45600_GYRO_STARTUP_TIME_MS 60 329 + #define INV_ICM45600_GYRO_STOP_TIME_MS 150 330 + #define INV_ICM45600_IREG_DELAY_US 4 331 + 332 + typedef int (*inv_icm45600_bus_setup)(struct inv_icm45600_state *); 333 + 334 + extern const struct dev_pm_ops inv_icm45600_pm_ops; 335 + 336 + const struct iio_mount_matrix * 337 + inv_icm45600_get_mount_matrix(const struct iio_dev *indio_dev, 338 + const struct iio_chan_spec *chan); 339 + 340 + #define INV_ICM45600_TEMP_CHAN(_index) \ 341 + { \ 342 + .type = IIO_TEMP, \ 343 + .info_mask_separate = \ 344 + BIT(IIO_CHAN_INFO_RAW) | \ 345 + BIT(IIO_CHAN_INFO_OFFSET) | \ 346 + BIT(IIO_CHAN_INFO_SCALE), \ 347 + .scan_index = _index, \ 348 + .scan_type = { \ 349 + .sign = 's', \ 350 + .realbits = 16, \ 351 + .storagebits = 16, \ 352 + .endianness = IIO_LE, \ 353 + }, \ 354 + } 355 + 356 + int inv_icm45600_temp_read_raw(struct iio_dev *indio_dev, 357 + struct iio_chan_spec const *chan, 358 + int *val, int *val2, long mask); 359 + 360 + u32 inv_icm45600_odr_to_period(enum inv_icm45600_odr odr); 361 + 362 + int inv_icm45600_set_accel_conf(struct inv_icm45600_state *st, 363 + struct inv_icm45600_sensor_conf *conf, 364 + unsigned int *sleep_ms); 365 + 366 + int inv_icm45600_set_gyro_conf(struct inv_icm45600_state *st, 367 + struct inv_icm45600_sensor_conf *conf, 368 + unsigned int *sleep_ms); 369 + 370 + int inv_icm45600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg, 371 + unsigned int writeval, unsigned int *readval); 372 + 373 + int inv_icm45600_core_probe(struct regmap *regmap, 374 + const struct inv_icm45600_chip_info *chip_info, 375 + bool reset, inv_icm45600_bus_setup bus_setup); 376 + 377 + struct iio_dev *inv_icm45600_gyro_init(struct inv_icm45600_state *st); 378 + 379 + int inv_icm45600_gyro_parse_fifo(struct iio_dev *indio_dev); 380 + 381 + struct iio_dev *inv_icm45600_accel_init(struct inv_icm45600_state *st); 382 + 383 + int inv_icm45600_accel_parse_fifo(struct iio_dev *indio_dev); 384 + 385 + #endif
+782
drivers/iio/imu/inv_icm45600/inv_icm45600_accel.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (C) 2025 Invensense, Inc. 4 + */ 5 + 6 + #include <linux/delay.h> 7 + #include <linux/device.h> 8 + #include <linux/err.h> 9 + #include <linux/math64.h> 10 + #include <linux/mutex.h> 11 + #include <linux/pm_runtime.h> 12 + #include <linux/regmap.h> 13 + #include <linux/types.h> 14 + 15 + #include <linux/iio/buffer.h> 16 + #include <linux/iio/common/inv_sensors_timestamp.h> 17 + #include <linux/iio/iio.h> 18 + #include <linux/iio/kfifo_buf.h> 19 + 20 + #include "inv_icm45600_buffer.h" 21 + #include "inv_icm45600.h" 22 + 23 + enum inv_icm45600_accel_scan { 24 + INV_ICM45600_ACCEL_SCAN_X, 25 + INV_ICM45600_ACCEL_SCAN_Y, 26 + INV_ICM45600_ACCEL_SCAN_Z, 27 + INV_ICM45600_ACCEL_SCAN_TEMP, 28 + INV_ICM45600_ACCEL_SCAN_TIMESTAMP, 29 + }; 30 + 31 + static const struct iio_chan_spec_ext_info inv_icm45600_accel_ext_infos[] = { 32 + IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, inv_icm45600_get_mount_matrix), 33 + { } 34 + }; 35 + 36 + #define INV_ICM45600_ACCEL_CHAN(_modifier, _index, _ext_info) \ 37 + { \ 38 + .type = IIO_ACCEL, \ 39 + .modified = 1, \ 40 + .channel2 = _modifier, \ 41 + .info_mask_separate = \ 42 + BIT(IIO_CHAN_INFO_RAW) | \ 43 + BIT(IIO_CHAN_INFO_CALIBBIAS), \ 44 + .info_mask_shared_by_type = \ 45 + BIT(IIO_CHAN_INFO_SCALE), \ 46 + .info_mask_shared_by_type_available = \ 47 + BIT(IIO_CHAN_INFO_SCALE) | \ 48 + BIT(IIO_CHAN_INFO_CALIBBIAS), \ 49 + .info_mask_shared_by_all = \ 50 + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 51 + .info_mask_shared_by_all_available = \ 52 + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 53 + .scan_index = _index, \ 54 + .scan_type = { \ 55 + .sign = 's', \ 56 + .realbits = 16, \ 57 + .storagebits = 16, \ 58 + .endianness = IIO_LE, \ 59 + }, \ 60 + .ext_info = _ext_info, \ 61 + } 62 + 63 + static const struct iio_chan_spec inv_icm45600_accel_channels[] = { 64 + INV_ICM45600_ACCEL_CHAN(IIO_MOD_X, INV_ICM45600_ACCEL_SCAN_X, 65 + inv_icm45600_accel_ext_infos), 66 + INV_ICM45600_ACCEL_CHAN(IIO_MOD_Y, INV_ICM45600_ACCEL_SCAN_Y, 67 + inv_icm45600_accel_ext_infos), 68 + INV_ICM45600_ACCEL_CHAN(IIO_MOD_Z, INV_ICM45600_ACCEL_SCAN_Z, 69 + inv_icm45600_accel_ext_infos), 70 + INV_ICM45600_TEMP_CHAN(INV_ICM45600_ACCEL_SCAN_TEMP), 71 + IIO_CHAN_SOFT_TIMESTAMP(INV_ICM45600_ACCEL_SCAN_TIMESTAMP), 72 + }; 73 + 74 + /* 75 + * IIO buffer data: size must be a power of 2 and timestamp aligned 76 + * 16 bytes: 6 bytes acceleration, 2 bytes temperature, 8 bytes timestamp 77 + */ 78 + struct inv_icm45600_accel_buffer { 79 + struct inv_icm45600_fifo_sensor_data accel; 80 + s16 temp; 81 + aligned_s64 timestamp; 82 + }; 83 + 84 + static const unsigned long inv_icm45600_accel_scan_masks[] = { 85 + /* 3-axis accel + temperature */ 86 + BIT(INV_ICM45600_ACCEL_SCAN_X) | 87 + BIT(INV_ICM45600_ACCEL_SCAN_Y) | 88 + BIT(INV_ICM45600_ACCEL_SCAN_Z) | 89 + BIT(INV_ICM45600_ACCEL_SCAN_TEMP), 90 + 0 91 + }; 92 + 93 + /* enable accelerometer sensor and FIFO write */ 94 + static int inv_icm45600_accel_update_scan_mode(struct iio_dev *indio_dev, 95 + const unsigned long *scan_mask) 96 + { 97 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 98 + struct inv_icm45600_sensor_state *accel_st = iio_priv(indio_dev); 99 + struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; 100 + unsigned int fifo_en = 0; 101 + unsigned int sleep = 0; 102 + int ret; 103 + 104 + scoped_guard(mutex, &st->lock) { 105 + if (*scan_mask & BIT(INV_ICM45600_ACCEL_SCAN_TEMP)) 106 + fifo_en |= INV_ICM45600_SENSOR_TEMP; 107 + 108 + if (*scan_mask & (BIT(INV_ICM45600_ACCEL_SCAN_X) | 109 + BIT(INV_ICM45600_ACCEL_SCAN_Y) | 110 + BIT(INV_ICM45600_ACCEL_SCAN_Z))) { 111 + /* enable accel sensor */ 112 + conf.mode = accel_st->power_mode; 113 + ret = inv_icm45600_set_accel_conf(st, &conf, &sleep); 114 + if (ret) 115 + return ret; 116 + fifo_en |= INV_ICM45600_SENSOR_ACCEL; 117 + } 118 + 119 + /* Update data FIFO write. */ 120 + ret = inv_icm45600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); 121 + } 122 + 123 + /* Sleep required time. */ 124 + if (sleep) 125 + msleep(sleep); 126 + 127 + return ret; 128 + } 129 + 130 + static int _inv_icm45600_accel_read_sensor(struct inv_icm45600_state *st, 131 + struct inv_icm45600_sensor_state *accel_st, 132 + unsigned int reg, int *val) 133 + { 134 + struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; 135 + int ret; 136 + 137 + /* enable accel sensor */ 138 + conf.mode = accel_st->power_mode; 139 + ret = inv_icm45600_set_accel_conf(st, &conf, NULL); 140 + if (ret) 141 + return ret; 142 + 143 + /* read accel register data */ 144 + ret = regmap_bulk_read(st->map, reg, &st->buffer.u16, sizeof(st->buffer.u16)); 145 + if (ret) 146 + return ret; 147 + 148 + *val = sign_extend32(le16_to_cpup(&st->buffer.u16), 15); 149 + if (*val == INV_ICM45600_DATA_INVALID) 150 + return -ENODATA; 151 + 152 + return 0; 153 + } 154 + 155 + static int inv_icm45600_accel_read_sensor(struct iio_dev *indio_dev, 156 + struct iio_chan_spec const *chan, 157 + int *val) 158 + { 159 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 160 + struct inv_icm45600_sensor_state *accel_st = iio_priv(indio_dev); 161 + struct device *dev = regmap_get_device(st->map); 162 + unsigned int reg; 163 + int ret; 164 + 165 + if (chan->type != IIO_ACCEL) 166 + return -EINVAL; 167 + 168 + switch (chan->channel2) { 169 + case IIO_MOD_X: 170 + reg = INV_ICM45600_REG_ACCEL_DATA_X; 171 + break; 172 + case IIO_MOD_Y: 173 + reg = INV_ICM45600_REG_ACCEL_DATA_Y; 174 + break; 175 + case IIO_MOD_Z: 176 + reg = INV_ICM45600_REG_ACCEL_DATA_Z; 177 + break; 178 + default: 179 + return -EINVAL; 180 + } 181 + 182 + ret = pm_runtime_resume_and_get(dev); 183 + if (ret) 184 + return ret; 185 + 186 + scoped_guard(mutex, &st->lock) 187 + ret = _inv_icm45600_accel_read_sensor(st, accel_st, reg, val); 188 + 189 + pm_runtime_put_autosuspend(dev); 190 + 191 + return ret; 192 + } 193 + 194 + /* IIO format int + nano */ 195 + const int inv_icm45600_accel_scale[][2] = { 196 + /* +/- 16G => 0.004788403 m/s-2 */ 197 + [INV_ICM45600_ACCEL_FS_16G] = { 0, 4788403 }, 198 + /* +/- 8G => 0.002394202 m/s-2 */ 199 + [INV_ICM45600_ACCEL_FS_8G] = { 0, 2394202 }, 200 + /* +/- 4G => 0.001197101 m/s-2 */ 201 + [INV_ICM45600_ACCEL_FS_4G] = { 0, 1197101 }, 202 + /* +/- 2G => 0.000598550 m/s-2 */ 203 + [INV_ICM45600_ACCEL_FS_2G] = { 0, 598550 }, 204 + }; 205 + 206 + const int inv_icm45686_accel_scale[][2] = { 207 + /* +/- 32G => 0.009576806 m/s-2 */ 208 + [INV_ICM45686_ACCEL_FS_32G] = { 0, 9576806 }, 209 + /* +/- 16G => 0.004788403 m/s-2 */ 210 + [INV_ICM45686_ACCEL_FS_16G] = { 0, 4788403 }, 211 + /* +/- 8G => 0.002394202 m/s-2 */ 212 + [INV_ICM45686_ACCEL_FS_8G] = { 0, 2394202 }, 213 + /* +/- 4G => 0.001197101 m/s-2 */ 214 + [INV_ICM45686_ACCEL_FS_4G] = { 0, 1197101 }, 215 + /* +/- 2G => 0.000598550 m/s-2 */ 216 + [INV_ICM45686_ACCEL_FS_2G] = { 0, 598550 }, 217 + }; 218 + 219 + static int inv_icm45600_accel_read_scale(struct iio_dev *indio_dev, 220 + int *val, int *val2) 221 + { 222 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 223 + struct inv_icm45600_sensor_state *accel_st = iio_priv(indio_dev); 224 + unsigned int idx; 225 + 226 + idx = st->conf.accel.fs; 227 + 228 + /* Full scale register starts at 1 for not High FSR parts */ 229 + if (accel_st->scales == (const int *)&inv_icm45600_accel_scale) 230 + idx--; 231 + 232 + *val = accel_st->scales[2 * idx]; 233 + *val2 = accel_st->scales[2 * idx + 1]; 234 + return IIO_VAL_INT_PLUS_NANO; 235 + } 236 + 237 + static int inv_icm45600_accel_write_scale(struct iio_dev *indio_dev, 238 + int val, int val2) 239 + { 240 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 241 + struct inv_icm45600_sensor_state *accel_st = iio_priv(indio_dev); 242 + struct device *dev = regmap_get_device(st->map); 243 + unsigned int idx; 244 + struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; 245 + int ret; 246 + 247 + for (idx = 0; idx < accel_st->scales_len; idx += 2) { 248 + if (val == accel_st->scales[idx] && 249 + val2 == accel_st->scales[idx + 1]) 250 + break; 251 + } 252 + if (idx == accel_st->scales_len) 253 + return -EINVAL; 254 + 255 + conf.fs = idx / 2; 256 + 257 + /* Full scale register starts at 1 for not High FSR parts */ 258 + if (accel_st->scales == (const int *)&inv_icm45600_accel_scale) 259 + conf.fs++; 260 + 261 + ret = pm_runtime_resume_and_get(dev); 262 + if (ret) 263 + return ret; 264 + 265 + scoped_guard(mutex, &st->lock) 266 + ret = inv_icm45600_set_accel_conf(st, &conf, NULL); 267 + 268 + pm_runtime_put_autosuspend(dev); 269 + 270 + return ret; 271 + } 272 + 273 + /* IIO format int + micro */ 274 + static const int inv_icm45600_accel_odr[] = { 275 + 1, 562500, /* 1.5625Hz */ 276 + 3, 125000, /* 3.125Hz */ 277 + 6, 250000, /* 6.25Hz */ 278 + 12, 500000, /* 12.5Hz */ 279 + 25, 0, /* 25Hz */ 280 + 50, 0, /* 50Hz */ 281 + 100, 0, /* 100Hz */ 282 + 200, 0, /* 200Hz */ 283 + 400, 0, /* 400Hz */ 284 + 800, 0, /* 800Hz */ 285 + 1600, 0, /* 1.6kHz */ 286 + 3200, 0, /* 3.2kHz */ 287 + 6400, 0, /* 6.4kHz */ 288 + }; 289 + 290 + static const int inv_icm45600_accel_odr_conv[] = { 291 + INV_ICM45600_ODR_1_5625HZ_LP, 292 + INV_ICM45600_ODR_3_125HZ_LP, 293 + INV_ICM45600_ODR_6_25HZ_LP, 294 + INV_ICM45600_ODR_12_5HZ, 295 + INV_ICM45600_ODR_25HZ, 296 + INV_ICM45600_ODR_50HZ, 297 + INV_ICM45600_ODR_100HZ, 298 + INV_ICM45600_ODR_200HZ, 299 + INV_ICM45600_ODR_400HZ, 300 + INV_ICM45600_ODR_800HZ_LN, 301 + INV_ICM45600_ODR_1600HZ_LN, 302 + INV_ICM45600_ODR_3200HZ_LN, 303 + INV_ICM45600_ODR_6400HZ_LN, 304 + }; 305 + 306 + static int inv_icm45600_accel_read_odr(struct inv_icm45600_state *st, 307 + int *val, int *val2) 308 + { 309 + unsigned int odr; 310 + unsigned int i; 311 + 312 + odr = st->conf.accel.odr; 313 + 314 + for (i = 0; i < ARRAY_SIZE(inv_icm45600_accel_odr_conv); ++i) { 315 + if (inv_icm45600_accel_odr_conv[i] == odr) 316 + break; 317 + } 318 + if (i >= ARRAY_SIZE(inv_icm45600_accel_odr_conv)) 319 + return -EINVAL; 320 + 321 + *val = inv_icm45600_accel_odr[2 * i]; 322 + *val2 = inv_icm45600_accel_odr[2 * i + 1]; 323 + 324 + return IIO_VAL_INT_PLUS_MICRO; 325 + } 326 + 327 + static int _inv_icm45600_accel_write_odr(struct iio_dev *indio_dev, int odr) 328 + { 329 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 330 + struct inv_icm45600_sensor_state *accel_st = iio_priv(indio_dev); 331 + struct inv_sensors_timestamp *ts = &accel_st->ts; 332 + struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; 333 + int ret; 334 + 335 + conf.odr = odr; 336 + ret = inv_sensors_timestamp_update_odr(ts, inv_icm45600_odr_to_period(conf.odr), 337 + iio_buffer_enabled(indio_dev)); 338 + if (ret) 339 + return ret; 340 + 341 + if (st->conf.accel.mode != INV_ICM45600_SENSOR_MODE_OFF) 342 + conf.mode = accel_st->power_mode; 343 + 344 + ret = inv_icm45600_set_accel_conf(st, &conf, NULL); 345 + if (ret) 346 + return ret; 347 + 348 + inv_icm45600_buffer_update_fifo_period(st); 349 + inv_icm45600_buffer_update_watermark(st); 350 + 351 + return 0; 352 + } 353 + 354 + static int inv_icm45600_accel_write_odr(struct iio_dev *indio_dev, 355 + int val, int val2) 356 + { 357 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 358 + struct device *dev = regmap_get_device(st->map); 359 + unsigned int idx; 360 + int odr; 361 + int ret; 362 + 363 + for (idx = 0; idx < ARRAY_SIZE(inv_icm45600_accel_odr); idx += 2) { 364 + if (val == inv_icm45600_accel_odr[idx] && 365 + val2 == inv_icm45600_accel_odr[idx + 1]) 366 + break; 367 + } 368 + if (idx >= ARRAY_SIZE(inv_icm45600_accel_odr)) 369 + return -EINVAL; 370 + 371 + odr = inv_icm45600_accel_odr_conv[idx / 2]; 372 + 373 + ret = pm_runtime_resume_and_get(dev); 374 + if (ret) 375 + return ret; 376 + 377 + scoped_guard(mutex, &st->lock) 378 + ret = _inv_icm45600_accel_write_odr(indio_dev, odr); 379 + 380 + pm_runtime_put_autosuspend(dev); 381 + 382 + return ret; 383 + } 384 + 385 + /* 386 + * Calibration bias values, IIO range format int + micro. 387 + * Value is limited to +/-1g coded on 14 bits signed. Step is 0.125mg. 388 + */ 389 + static int inv_icm45600_accel_calibbias[] = { 390 + -9, 806650, /* min: -9.806650 m/s² */ 391 + 0, 1197, /* step: 0.001197 m/s² */ 392 + 9, 805453, /* max: 9.805453 m/s² */ 393 + }; 394 + 395 + static int inv_icm45600_accel_read_offset(struct inv_icm45600_state *st, 396 + struct iio_chan_spec const *chan, 397 + int *val, int *val2) 398 + { 399 + struct device *dev = regmap_get_device(st->map); 400 + s64 val64; 401 + s32 bias; 402 + unsigned int reg; 403 + s16 offset; 404 + int ret; 405 + 406 + if (chan->type != IIO_ACCEL) 407 + return -EINVAL; 408 + 409 + switch (chan->channel2) { 410 + case IIO_MOD_X: 411 + reg = INV_ICM45600_IPREG_SYS2_REG_24; 412 + break; 413 + case IIO_MOD_Y: 414 + reg = INV_ICM45600_IPREG_SYS2_REG_32; 415 + break; 416 + case IIO_MOD_Z: 417 + reg = INV_ICM45600_IPREG_SYS2_REG_40; 418 + break; 419 + default: 420 + return -EINVAL; 421 + } 422 + 423 + ret = pm_runtime_resume_and_get(dev); 424 + if (ret) 425 + return ret; 426 + 427 + scoped_guard(mutex, &st->lock) 428 + ret = regmap_bulk_read(st->map, reg, &st->buffer.u16, sizeof(st->buffer.u16)); 429 + 430 + pm_runtime_put_autosuspend(dev); 431 + if (ret) 432 + return ret; 433 + 434 + offset = le16_to_cpup(&st->buffer.u16) & INV_ICM45600_ACCEL_OFFUSER_MASK; 435 + /* 14 bits signed value */ 436 + offset = sign_extend32(offset, 13); 437 + 438 + /* 439 + * convert raw offset to g then to m/s² 440 + * 14 bits signed raw step 1/8192g 441 + * g to m/s²: 9.806650 442 + * result in micro (* 1000000) 443 + * (offset * 9806650) / 8192 444 + */ 445 + val64 = (s64)offset * 9806650LL; 446 + /* for rounding, add + or - divisor (8192) divided by 2 */ 447 + if (val64 >= 0) 448 + val64 += 8192LL / 2LL; 449 + else 450 + val64 -= 8192LL / 2LL; 451 + bias = div_s64(val64, 8192L); 452 + *val = bias / 1000000L; 453 + *val2 = bias % 1000000L; 454 + 455 + return IIO_VAL_INT_PLUS_MICRO; 456 + } 457 + 458 + static int inv_icm45600_accel_write_offset(struct inv_icm45600_state *st, 459 + struct iio_chan_spec const *chan, 460 + int val, int val2) 461 + { 462 + struct device *dev = regmap_get_device(st->map); 463 + s64 val64; 464 + s32 min, max; 465 + unsigned int reg; 466 + s16 offset; 467 + int ret; 468 + 469 + if (chan->type != IIO_ACCEL) 470 + return -EINVAL; 471 + 472 + switch (chan->channel2) { 473 + case IIO_MOD_X: 474 + reg = INV_ICM45600_IPREG_SYS2_REG_24; 475 + break; 476 + case IIO_MOD_Y: 477 + reg = INV_ICM45600_IPREG_SYS2_REG_32; 478 + break; 479 + case IIO_MOD_Z: 480 + reg = INV_ICM45600_IPREG_SYS2_REG_40; 481 + break; 482 + default: 483 + return -EINVAL; 484 + } 485 + 486 + /* inv_icm45600_accel_calibbias: min - step - max in micro */ 487 + min = inv_icm45600_accel_calibbias[0] * 1000000L - 488 + inv_icm45600_accel_calibbias[1]; 489 + max = inv_icm45600_accel_calibbias[4] * 1000000L + 490 + inv_icm45600_accel_calibbias[5]; 491 + val64 = (s64)val * 1000000LL; 492 + if (val >= 0) 493 + val64 += (s64)val2; 494 + else 495 + val64 -= (s64)val2; 496 + if (val64 < min || val64 > max) 497 + return -EINVAL; 498 + 499 + /* 500 + * convert m/s² to g then to raw value 501 + * m/s² to g: 1 / 9.806650 502 + * g to raw 14 bits signed, step 1/8192g: * 8192 503 + * val in micro (1000000) 504 + * val * 8192 / (9.806650 * 1000000) 505 + */ 506 + val64 = val64 * 8192LL; 507 + /* for rounding, add + or - divisor (9806650) divided by 2 */ 508 + if (val64 >= 0) 509 + val64 += 9806650 / 2; 510 + else 511 + val64 -= 9806650 / 2; 512 + offset = div_s64(val64, 9806650); 513 + 514 + /* clamp value limited to 14 bits signed */ 515 + offset = clamp(offset, -8192, 8191); 516 + 517 + st->buffer.u16 = cpu_to_le16(offset & INV_ICM45600_ACCEL_OFFUSER_MASK); 518 + 519 + ret = pm_runtime_resume_and_get(dev); 520 + if (ret) 521 + return ret; 522 + 523 + scoped_guard(mutex, &st->lock) 524 + ret = regmap_bulk_write(st->map, reg, &st->buffer.u16, sizeof(st->buffer.u16)); 525 + 526 + pm_runtime_put_autosuspend(dev); 527 + return ret; 528 + } 529 + 530 + static int inv_icm45600_accel_read_raw(struct iio_dev *indio_dev, 531 + struct iio_chan_spec const *chan, 532 + int *val, int *val2, long mask) 533 + { 534 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 535 + int ret; 536 + 537 + switch (chan->type) { 538 + case IIO_ACCEL: 539 + break; 540 + case IIO_TEMP: 541 + return inv_icm45600_temp_read_raw(indio_dev, chan, val, val2, mask); 542 + default: 543 + return -EINVAL; 544 + } 545 + 546 + switch (mask) { 547 + case IIO_CHAN_INFO_RAW: 548 + if (!iio_device_claim_direct(indio_dev)) 549 + return -EBUSY; 550 + ret = inv_icm45600_accel_read_sensor(indio_dev, chan, val); 551 + iio_device_release_direct(indio_dev); 552 + if (ret) 553 + return ret; 554 + return IIO_VAL_INT; 555 + case IIO_CHAN_INFO_SCALE: 556 + return inv_icm45600_accel_read_scale(indio_dev, val, val2); 557 + case IIO_CHAN_INFO_SAMP_FREQ: 558 + return inv_icm45600_accel_read_odr(st, val, val2); 559 + case IIO_CHAN_INFO_CALIBBIAS: 560 + return inv_icm45600_accel_read_offset(st, chan, val, val2); 561 + default: 562 + return -EINVAL; 563 + } 564 + } 565 + 566 + static int inv_icm45600_accel_read_avail(struct iio_dev *indio_dev, 567 + struct iio_chan_spec const *chan, 568 + const int **vals, 569 + int *type, int *length, long mask) 570 + { 571 + struct inv_icm45600_sensor_state *accel_st = iio_priv(indio_dev); 572 + 573 + if (chan->type != IIO_ACCEL) 574 + return -EINVAL; 575 + 576 + switch (mask) { 577 + case IIO_CHAN_INFO_SCALE: 578 + *vals = accel_st->scales; 579 + *type = IIO_VAL_INT_PLUS_NANO; 580 + *length = accel_st->scales_len; 581 + return IIO_AVAIL_LIST; 582 + case IIO_CHAN_INFO_SAMP_FREQ: 583 + *vals = inv_icm45600_accel_odr; 584 + *type = IIO_VAL_INT_PLUS_MICRO; 585 + *length = ARRAY_SIZE(inv_icm45600_accel_odr); 586 + return IIO_AVAIL_LIST; 587 + case IIO_CHAN_INFO_CALIBBIAS: 588 + *vals = inv_icm45600_accel_calibbias; 589 + *type = IIO_VAL_INT_PLUS_MICRO; 590 + return IIO_AVAIL_RANGE; 591 + default: 592 + return -EINVAL; 593 + } 594 + } 595 + 596 + static int inv_icm45600_accel_write_raw(struct iio_dev *indio_dev, 597 + struct iio_chan_spec const *chan, 598 + int val, int val2, long mask) 599 + { 600 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 601 + int ret; 602 + 603 + if (chan->type != IIO_ACCEL) 604 + return -EINVAL; 605 + 606 + switch (mask) { 607 + case IIO_CHAN_INFO_SCALE: 608 + if (!iio_device_claim_direct(indio_dev)) 609 + return -EBUSY; 610 + ret = inv_icm45600_accel_write_scale(indio_dev, val, val2); 611 + iio_device_release_direct(indio_dev); 612 + return ret; 613 + case IIO_CHAN_INFO_SAMP_FREQ: 614 + return inv_icm45600_accel_write_odr(indio_dev, val, val2); 615 + case IIO_CHAN_INFO_CALIBBIAS: 616 + if (!iio_device_claim_direct(indio_dev)) 617 + return -EBUSY; 618 + ret = inv_icm45600_accel_write_offset(st, chan, val, val2); 619 + iio_device_release_direct(indio_dev); 620 + return ret; 621 + default: 622 + return -EINVAL; 623 + } 624 + } 625 + 626 + static int inv_icm45600_accel_write_raw_get_fmt(struct iio_dev *indio_dev, 627 + struct iio_chan_spec const *chan, 628 + long mask) 629 + { 630 + if (chan->type != IIO_ACCEL) 631 + return -EINVAL; 632 + 633 + switch (mask) { 634 + case IIO_CHAN_INFO_SCALE: 635 + return IIO_VAL_INT_PLUS_NANO; 636 + case IIO_CHAN_INFO_SAMP_FREQ: 637 + return IIO_VAL_INT_PLUS_MICRO; 638 + case IIO_CHAN_INFO_CALIBBIAS: 639 + return IIO_VAL_INT_PLUS_MICRO; 640 + default: 641 + return -EINVAL; 642 + } 643 + } 644 + 645 + static int inv_icm45600_accel_hwfifo_set_watermark(struct iio_dev *indio_dev, 646 + unsigned int val) 647 + { 648 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 649 + 650 + guard(mutex)(&st->lock); 651 + 652 + st->fifo.watermark.accel = val; 653 + return inv_icm45600_buffer_update_watermark(st); 654 + } 655 + 656 + static int inv_icm45600_accel_hwfifo_flush(struct iio_dev *indio_dev, 657 + unsigned int count) 658 + { 659 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 660 + int ret; 661 + 662 + if (count == 0) 663 + return 0; 664 + 665 + guard(mutex)(&st->lock); 666 + 667 + ret = inv_icm45600_buffer_hwfifo_flush(st, count); 668 + if (ret) 669 + return ret; 670 + 671 + return st->fifo.nb.accel; 672 + } 673 + 674 + static const struct iio_info inv_icm45600_accel_info = { 675 + .read_raw = inv_icm45600_accel_read_raw, 676 + .read_avail = inv_icm45600_accel_read_avail, 677 + .write_raw = inv_icm45600_accel_write_raw, 678 + .write_raw_get_fmt = inv_icm45600_accel_write_raw_get_fmt, 679 + .debugfs_reg_access = inv_icm45600_debugfs_reg, 680 + .update_scan_mode = inv_icm45600_accel_update_scan_mode, 681 + .hwfifo_set_watermark = inv_icm45600_accel_hwfifo_set_watermark, 682 + .hwfifo_flush_to_buffer = inv_icm45600_accel_hwfifo_flush, 683 + }; 684 + 685 + struct iio_dev *inv_icm45600_accel_init(struct inv_icm45600_state *st) 686 + { 687 + struct device *dev = regmap_get_device(st->map); 688 + struct inv_icm45600_sensor_state *accel_st; 689 + struct inv_sensors_timestamp_chip ts_chip; 690 + struct iio_dev *indio_dev; 691 + const char *name; 692 + int ret; 693 + 694 + name = devm_kasprintf(dev, GFP_KERNEL, "%s-accel", st->chip_info->name); 695 + if (!name) 696 + return ERR_PTR(-ENOMEM); 697 + 698 + indio_dev = devm_iio_device_alloc(dev, sizeof(*accel_st)); 699 + if (!indio_dev) 700 + return ERR_PTR(-ENOMEM); 701 + accel_st = iio_priv(indio_dev); 702 + 703 + accel_st->scales = st->chip_info->accel_scales; 704 + accel_st->scales_len = st->chip_info->accel_scales_len * 2; 705 + 706 + /* low-power (LP) mode by default at init, no ULP mode */ 707 + accel_st->power_mode = INV_ICM45600_SENSOR_MODE_LOW_POWER; 708 + ret = regmap_set_bits(st->map, INV_ICM45600_REG_SMC_CONTROL_0, 709 + INV_ICM45600_SMC_CONTROL_0_ACCEL_LP_CLK_SEL); 710 + if (ret) 711 + return ERR_PTR(ret); 712 + 713 + /* 714 + * clock period is 32kHz (31250ns) 715 + * jitter is +/- 2% (20 per mille) 716 + */ 717 + ts_chip.clock_period = 31250; 718 + ts_chip.jitter = 20; 719 + ts_chip.init_period = inv_icm45600_odr_to_period(st->conf.accel.odr); 720 + inv_sensors_timestamp_init(&accel_st->ts, &ts_chip); 721 + 722 + iio_device_set_drvdata(indio_dev, st); 723 + indio_dev->name = name; 724 + indio_dev->info = &inv_icm45600_accel_info; 725 + indio_dev->modes = INDIO_DIRECT_MODE; 726 + indio_dev->channels = inv_icm45600_accel_channels; 727 + indio_dev->num_channels = ARRAY_SIZE(inv_icm45600_accel_channels); 728 + indio_dev->available_scan_masks = inv_icm45600_accel_scan_masks; 729 + 730 + ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, 731 + &inv_icm45600_buffer_ops); 732 + if (ret) 733 + return ERR_PTR(ret); 734 + 735 + ret = devm_iio_device_register(dev, indio_dev); 736 + if (ret) 737 + return ERR_PTR(ret); 738 + 739 + return indio_dev; 740 + } 741 + 742 + int inv_icm45600_accel_parse_fifo(struct iio_dev *indio_dev) 743 + { 744 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 745 + struct inv_icm45600_sensor_state *accel_st = iio_priv(indio_dev); 746 + struct inv_sensors_timestamp *ts = &accel_st->ts; 747 + ssize_t i, size; 748 + unsigned int no; 749 + 750 + /* parse all fifo packets */ 751 + for (i = 0, no = 0; i < st->fifo.count; i += size, ++no) { 752 + struct inv_icm45600_accel_buffer buffer = { }; 753 + const struct inv_icm45600_fifo_sensor_data *accel, *gyro; 754 + const __le16 *timestamp; 755 + const s8 *temp; 756 + unsigned int odr; 757 + s64 ts_val; 758 + 759 + size = inv_icm45600_fifo_decode_packet(&st->fifo.data[i], 760 + &accel, &gyro, &temp, &timestamp, &odr); 761 + /* quit if error or FIFO is empty */ 762 + if (size <= 0) 763 + return size; 764 + 765 + /* skip packet if no accel data or data is invalid */ 766 + if (accel == NULL || !inv_icm45600_fifo_is_data_valid(accel)) 767 + continue; 768 + 769 + /* update odr */ 770 + if (odr & INV_ICM45600_SENSOR_ACCEL) 771 + inv_sensors_timestamp_apply_odr(ts, st->fifo.period, 772 + st->fifo.nb.total, no); 773 + 774 + memcpy(&buffer.accel, accel, sizeof(buffer.accel)); 775 + /* convert 8 bits FIFO temperature in high resolution format */ 776 + buffer.temp = temp ? (*temp * 64) : 0; 777 + ts_val = inv_sensors_timestamp_pop(ts); 778 + iio_push_to_buffers_with_ts(indio_dev, &buffer, sizeof(buffer), ts_val); 779 + } 780 + 781 + return 0; 782 + }
+558
drivers/iio/imu/inv_icm45600/inv_icm45600_buffer.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* Copyright (C) 2025 Invensense, Inc. */ 3 + 4 + #include <linux/bitfield.h> 5 + #include <linux/delay.h> 6 + #include <linux/device.h> 7 + #include <linux/err.h> 8 + #include <linux/minmax.h> 9 + #include <linux/mutex.h> 10 + #include <linux/pm_runtime.h> 11 + #include <linux/regmap.h> 12 + #include <linux/time.h> 13 + #include <linux/types.h> 14 + 15 + #include <asm/byteorder.h> 16 + 17 + #include <linux/iio/buffer.h> 18 + #include <linux/iio/common/inv_sensors_timestamp.h> 19 + #include <linux/iio/iio.h> 20 + 21 + #include "inv_icm45600_buffer.h" 22 + #include "inv_icm45600.h" 23 + 24 + /* FIFO header: 1 byte */ 25 + #define INV_ICM45600_FIFO_EXT_HEADER BIT(7) 26 + #define INV_ICM45600_FIFO_HEADER_ACCEL BIT(6) 27 + #define INV_ICM45600_FIFO_HEADER_GYRO BIT(5) 28 + #define INV_ICM45600_FIFO_HEADER_HIGH_RES BIT(4) 29 + #define INV_ICM45600_FIFO_HEADER_TMST_FSYNC GENMASK(3, 2) 30 + #define INV_ICM45600_FIFO_HEADER_ODR_ACCEL BIT(1) 31 + #define INV_ICM45600_FIFO_HEADER_ODR_GYRO BIT(0) 32 + 33 + struct inv_icm45600_fifo_1sensor_packet { 34 + u8 header; 35 + struct inv_icm45600_fifo_sensor_data data; 36 + s8 temp; 37 + } __packed; 38 + 39 + struct inv_icm45600_fifo_2sensors_packet { 40 + u8 header; 41 + struct inv_icm45600_fifo_sensor_data accel; 42 + struct inv_icm45600_fifo_sensor_data gyro; 43 + s8 temp; 44 + __le16 timestamp; 45 + } __packed; 46 + 47 + ssize_t inv_icm45600_fifo_decode_packet(const void *packet, 48 + const struct inv_icm45600_fifo_sensor_data **accel, 49 + const struct inv_icm45600_fifo_sensor_data **gyro, 50 + const s8 **temp, 51 + const __le16 **timestamp, unsigned int *odr) 52 + { 53 + const struct inv_icm45600_fifo_1sensor_packet *pack1 = packet; 54 + const struct inv_icm45600_fifo_2sensors_packet *pack2 = packet; 55 + u8 header = *((const u8 *)packet); 56 + 57 + /* FIFO extended header */ 58 + if (header & INV_ICM45600_FIFO_EXT_HEADER) { 59 + /* Not yet supported */ 60 + return 0; 61 + } 62 + 63 + /* handle odr flags. */ 64 + *odr = 0; 65 + if (header & INV_ICM45600_FIFO_HEADER_ODR_GYRO) 66 + *odr |= INV_ICM45600_SENSOR_GYRO; 67 + if (header & INV_ICM45600_FIFO_HEADER_ODR_ACCEL) 68 + *odr |= INV_ICM45600_SENSOR_ACCEL; 69 + 70 + /* Accel + Gyro data are present. */ 71 + if ((header & INV_ICM45600_FIFO_HEADER_ACCEL) && 72 + (header & INV_ICM45600_FIFO_HEADER_GYRO)) { 73 + *accel = &pack2->accel; 74 + *gyro = &pack2->gyro; 75 + *temp = &pack2->temp; 76 + *timestamp = &pack2->timestamp; 77 + return sizeof(*pack2); 78 + } 79 + 80 + /* Accel data only. */ 81 + if (header & INV_ICM45600_FIFO_HEADER_ACCEL) { 82 + *accel = &pack1->data; 83 + *gyro = NULL; 84 + *temp = &pack1->temp; 85 + *timestamp = NULL; 86 + return sizeof(*pack1); 87 + } 88 + 89 + /* Gyro data only. */ 90 + if (header & INV_ICM45600_FIFO_HEADER_GYRO) { 91 + *accel = NULL; 92 + *gyro = &pack1->data; 93 + *temp = &pack1->temp; 94 + *timestamp = NULL; 95 + return sizeof(*pack1); 96 + } 97 + 98 + /* Invalid packet if here. */ 99 + return -EINVAL; 100 + } 101 + 102 + void inv_icm45600_buffer_update_fifo_period(struct inv_icm45600_state *st) 103 + { 104 + u32 period_gyro, period_accel; 105 + 106 + if (st->fifo.en & INV_ICM45600_SENSOR_GYRO) 107 + period_gyro = inv_icm45600_odr_to_period(st->conf.gyro.odr); 108 + else 109 + period_gyro = U32_MAX; 110 + 111 + if (st->fifo.en & INV_ICM45600_SENSOR_ACCEL) 112 + period_accel = inv_icm45600_odr_to_period(st->conf.accel.odr); 113 + else 114 + period_accel = U32_MAX; 115 + 116 + st->fifo.period = min(period_gyro, period_accel); 117 + } 118 + 119 + int inv_icm45600_buffer_set_fifo_en(struct inv_icm45600_state *st, 120 + unsigned int fifo_en) 121 + { 122 + unsigned int mask; 123 + int ret; 124 + 125 + mask = INV_ICM45600_FIFO_CONFIG3_GYRO_EN | 126 + INV_ICM45600_FIFO_CONFIG3_ACCEL_EN; 127 + 128 + ret = regmap_assign_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG3, mask, 129 + (fifo_en & INV_ICM45600_SENSOR_GYRO) || 130 + (fifo_en & INV_ICM45600_SENSOR_ACCEL)); 131 + if (ret) 132 + return ret; 133 + 134 + st->fifo.en = fifo_en; 135 + inv_icm45600_buffer_update_fifo_period(st); 136 + 137 + return 0; 138 + } 139 + 140 + static unsigned int inv_icm45600_wm_truncate(unsigned int watermark, size_t packet_size, 141 + unsigned int fifo_period) 142 + { 143 + size_t watermark_max, grace_samples; 144 + 145 + /* Keep 20ms for processing FIFO.*/ 146 + grace_samples = (20U * NSEC_PER_MSEC) / fifo_period; 147 + if (grace_samples < 1) 148 + grace_samples = 1; 149 + 150 + watermark_max = INV_ICM45600_FIFO_SIZE_MAX / packet_size; 151 + watermark_max -= grace_samples; 152 + 153 + return min(watermark, watermark_max); 154 + } 155 + 156 + /** 157 + * inv_icm45600_buffer_update_watermark - update watermark FIFO threshold 158 + * @st: driver internal state 159 + * 160 + * FIFO watermark threshold is computed based on the required watermark values 161 + * set for gyro and accel sensors. Since watermark is all about acceptable data 162 + * latency, use the smallest setting between the 2. It means choosing the 163 + * smallest latency but this is not as simple as choosing the smallest watermark 164 + * value. Latency depends on watermark and ODR. It requires several steps: 165 + * 1) compute gyro and accel latencies and choose the smallest value. 166 + * 2) adapt the chosen latency so that it is a multiple of both gyro and accel 167 + * ones. Otherwise it is possible that you don't meet a requirement. (for 168 + * example with gyro @100Hz wm 4 and accel @100Hz with wm 6, choosing the 169 + * value of 4 will not meet accel latency requirement because 6 is not a 170 + * multiple of 4. You need to use the value 2.) 171 + * 3) Since all periods are multiple of each others, watermark is computed by 172 + * dividing this computed latency by the smallest period, which corresponds 173 + * to the FIFO frequency. 174 + * 175 + * Returns: 0 on success, a negative error code otherwise. 176 + */ 177 + int inv_icm45600_buffer_update_watermark(struct inv_icm45600_state *st) 178 + { 179 + const size_t packet_size = sizeof(struct inv_icm45600_fifo_2sensors_packet); 180 + unsigned int wm_gyro, wm_accel, watermark; 181 + u32 period_gyro, period_accel, period; 182 + u32 latency_gyro, latency_accel, latency; 183 + 184 + /* Compute sensors latency, depending on sensor watermark and odr. */ 185 + wm_gyro = inv_icm45600_wm_truncate(st->fifo.watermark.gyro, packet_size, 186 + st->fifo.period); 187 + wm_accel = inv_icm45600_wm_truncate(st->fifo.watermark.accel, packet_size, 188 + st->fifo.period); 189 + /* Use us for odr to avoid overflow using 32 bits values. */ 190 + period_gyro = inv_icm45600_odr_to_period(st->conf.gyro.odr) / NSEC_PER_USEC; 191 + period_accel = inv_icm45600_odr_to_period(st->conf.accel.odr) / NSEC_PER_USEC; 192 + latency_gyro = period_gyro * wm_gyro; 193 + latency_accel = period_accel * wm_accel; 194 + 195 + /* 0 value for watermark means that the sensor is turned off. */ 196 + if (wm_gyro == 0 && wm_accel == 0) 197 + return 0; 198 + 199 + if (latency_gyro == 0) { 200 + watermark = wm_accel; 201 + st->fifo.watermark.eff_accel = wm_accel; 202 + } else if (latency_accel == 0) { 203 + watermark = wm_gyro; 204 + st->fifo.watermark.eff_gyro = wm_gyro; 205 + } else { 206 + /* Compute the smallest latency that is a multiple of both. */ 207 + if (latency_gyro <= latency_accel) 208 + latency = latency_gyro - (latency_accel % latency_gyro); 209 + else 210 + latency = latency_accel - (latency_gyro % latency_accel); 211 + /* Use the shortest period. */ 212 + period = min(period_gyro, period_accel); 213 + /* All this works because periods are multiple of each others. */ 214 + watermark = max(latency / period, 1); 215 + /* Update effective watermark. */ 216 + st->fifo.watermark.eff_gyro = max(latency / period_gyro, 1); 217 + st->fifo.watermark.eff_accel = max(latency / period_accel, 1); 218 + } 219 + 220 + st->buffer.u16 = cpu_to_le16(watermark); 221 + return regmap_bulk_write(st->map, INV_ICM45600_REG_FIFO_WATERMARK, 222 + &st->buffer.u16, sizeof(st->buffer.u16)); 223 + } 224 + 225 + static int inv_icm45600_buffer_preenable(struct iio_dev *indio_dev) 226 + { 227 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 228 + struct device *dev = regmap_get_device(st->map); 229 + struct inv_icm45600_sensor_state *sensor_st = iio_priv(indio_dev); 230 + struct inv_sensors_timestamp *ts = &sensor_st->ts; 231 + int ret; 232 + 233 + ret = pm_runtime_resume_and_get(dev); 234 + if (ret) 235 + return ret; 236 + 237 + guard(mutex)(&st->lock); 238 + inv_sensors_timestamp_reset(ts); 239 + 240 + return 0; 241 + } 242 + 243 + /* 244 + * Update_scan_mode callback is turning sensors on and setting data FIFO enable 245 + * bits. 246 + */ 247 + static int inv_icm45600_buffer_postenable(struct iio_dev *indio_dev) 248 + { 249 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 250 + unsigned int val; 251 + int ret; 252 + 253 + guard(mutex)(&st->lock); 254 + 255 + /* Exit if FIFO is already on. */ 256 + if (st->fifo.on) { 257 + st->fifo.on++; 258 + return 0; 259 + } 260 + 261 + ret = regmap_set_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG2, 262 + INV_ICM45600_REG_FIFO_CONFIG2_FIFO_FLUSH); 263 + if (ret) 264 + return ret; 265 + 266 + ret = regmap_set_bits(st->map, INV_ICM45600_REG_INT1_CONFIG0, 267 + INV_ICM45600_INT1_CONFIG0_FIFO_THS_EN | 268 + INV_ICM45600_INT1_CONFIG0_FIFO_FULL_EN); 269 + if (ret) 270 + return ret; 271 + 272 + val = FIELD_PREP(INV_ICM45600_FIFO_CONFIG0_MODE_MASK, 273 + INV_ICM45600_FIFO_CONFIG0_MODE_STREAM); 274 + ret = regmap_update_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG0, 275 + INV_ICM45600_FIFO_CONFIG0_MODE_MASK, val); 276 + if (ret) 277 + return ret; 278 + 279 + /* Enable writing sensor data to FIFO. */ 280 + ret = regmap_set_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG3, 281 + INV_ICM45600_FIFO_CONFIG3_IF_EN); 282 + if (ret) 283 + return ret; 284 + 285 + st->fifo.on++; 286 + return 0; 287 + } 288 + 289 + static int inv_icm45600_buffer_predisable(struct iio_dev *indio_dev) 290 + { 291 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 292 + unsigned int val; 293 + int ret; 294 + 295 + guard(mutex)(&st->lock); 296 + 297 + /* Exit if there are several sensors using the FIFO. */ 298 + if (st->fifo.on > 1) { 299 + st->fifo.on--; 300 + return 0; 301 + } 302 + 303 + /* Disable writing sensor data to FIFO. */ 304 + ret = regmap_clear_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG3, 305 + INV_ICM45600_FIFO_CONFIG3_IF_EN); 306 + if (ret) 307 + return ret; 308 + 309 + val = FIELD_PREP(INV_ICM45600_FIFO_CONFIG0_MODE_MASK, 310 + INV_ICM45600_FIFO_CONFIG0_MODE_BYPASS); 311 + ret = regmap_update_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG0, 312 + INV_ICM45600_FIFO_CONFIG0_MODE_MASK, val); 313 + if (ret) 314 + return ret; 315 + 316 + ret = regmap_clear_bits(st->map, INV_ICM45600_REG_INT1_CONFIG0, 317 + INV_ICM45600_INT1_CONFIG0_FIFO_THS_EN | 318 + INV_ICM45600_INT1_CONFIG0_FIFO_FULL_EN); 319 + if (ret) 320 + return ret; 321 + 322 + ret = regmap_set_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG2, 323 + INV_ICM45600_REG_FIFO_CONFIG2_FIFO_FLUSH); 324 + if (ret) 325 + return ret; 326 + 327 + st->fifo.on--; 328 + return 0; 329 + } 330 + 331 + static int _inv_icm45600_buffer_postdisable(struct inv_icm45600_state *st, 332 + unsigned int sensor, unsigned int *watermark, 333 + unsigned int *sleep) 334 + { 335 + struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; 336 + int ret; 337 + 338 + ret = inv_icm45600_buffer_set_fifo_en(st, st->fifo.en & ~sensor); 339 + if (ret) 340 + return ret; 341 + 342 + *watermark = 0; 343 + ret = inv_icm45600_buffer_update_watermark(st); 344 + if (ret) 345 + return ret; 346 + 347 + conf.mode = INV_ICM45600_SENSOR_MODE_OFF; 348 + if (sensor == INV_ICM45600_SENSOR_GYRO) 349 + return inv_icm45600_set_gyro_conf(st, &conf, sleep); 350 + else 351 + return inv_icm45600_set_accel_conf(st, &conf, sleep); 352 + } 353 + 354 + static int inv_icm45600_buffer_postdisable(struct iio_dev *indio_dev) 355 + { 356 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 357 + struct device *dev = regmap_get_device(st->map); 358 + unsigned int sensor; 359 + unsigned int *watermark; 360 + unsigned int sleep; 361 + int ret; 362 + 363 + if (indio_dev == st->indio_gyro) { 364 + sensor = INV_ICM45600_SENSOR_GYRO; 365 + watermark = &st->fifo.watermark.gyro; 366 + } else if (indio_dev == st->indio_accel) { 367 + sensor = INV_ICM45600_SENSOR_ACCEL; 368 + watermark = &st->fifo.watermark.accel; 369 + } else { 370 + return -EINVAL; 371 + } 372 + 373 + sleep = 0; 374 + scoped_guard(mutex, &st->lock) 375 + ret = _inv_icm45600_buffer_postdisable(st, sensor, watermark, &sleep); 376 + 377 + /* Sleep required time. */ 378 + if (sleep) 379 + msleep(sleep); 380 + 381 + pm_runtime_put_autosuspend(dev); 382 + 383 + return ret; 384 + } 385 + 386 + const struct iio_buffer_setup_ops inv_icm45600_buffer_ops = { 387 + .preenable = inv_icm45600_buffer_preenable, 388 + .postenable = inv_icm45600_buffer_postenable, 389 + .predisable = inv_icm45600_buffer_predisable, 390 + .postdisable = inv_icm45600_buffer_postdisable, 391 + }; 392 + 393 + int inv_icm45600_buffer_fifo_read(struct inv_icm45600_state *st, 394 + unsigned int max) 395 + { 396 + const ssize_t packet_size = sizeof(struct inv_icm45600_fifo_2sensors_packet); 397 + __le16 *raw_fifo_count; 398 + size_t fifo_nb, i; 399 + ssize_t size; 400 + const struct inv_icm45600_fifo_sensor_data *accel, *gyro; 401 + const __le16 *timestamp; 402 + const s8 *temp; 403 + unsigned int odr; 404 + int ret; 405 + 406 + /* Reset all samples counters. */ 407 + st->fifo.count = 0; 408 + st->fifo.nb.gyro = 0; 409 + st->fifo.nb.accel = 0; 410 + st->fifo.nb.total = 0; 411 + 412 + raw_fifo_count = &st->buffer.u16; 413 + ret = regmap_bulk_read(st->map, INV_ICM45600_REG_FIFO_COUNT, 414 + raw_fifo_count, sizeof(*raw_fifo_count)); 415 + if (ret) 416 + return ret; 417 + 418 + /* Check and limit number of samples if requested. */ 419 + fifo_nb = le16_to_cpup(raw_fifo_count); 420 + if (fifo_nb == 0) 421 + return 0; 422 + if (max > 0 && fifo_nb > max) 423 + fifo_nb = max; 424 + 425 + /* Try to read all FIFO data in internal buffer. */ 426 + st->fifo.count = fifo_nb * packet_size; 427 + ret = regmap_noinc_read(st->map, INV_ICM45600_REG_FIFO_DATA, 428 + st->fifo.data, st->fifo.count); 429 + if (ret == -ENOTSUPP || ret == -EFBIG) { 430 + /* Read full fifo is not supported, read samples one by one. */ 431 + ret = 0; 432 + for (i = 0; i < st->fifo.count && ret == 0; i += packet_size) 433 + ret = regmap_noinc_read(st->map, INV_ICM45600_REG_FIFO_DATA, 434 + &st->fifo.data[i], packet_size); 435 + } 436 + if (ret) 437 + return ret; 438 + 439 + for (i = 0; i < st->fifo.count; i += size) { 440 + size = inv_icm45600_fifo_decode_packet(&st->fifo.data[i], &accel, &gyro, 441 + &temp, &timestamp, &odr); 442 + if (size <= 0) 443 + /* No more sample in buffer */ 444 + break; 445 + if (gyro && inv_icm45600_fifo_is_data_valid(gyro)) 446 + st->fifo.nb.gyro++; 447 + if (accel && inv_icm45600_fifo_is_data_valid(accel)) 448 + st->fifo.nb.accel++; 449 + st->fifo.nb.total++; 450 + } 451 + 452 + return 0; 453 + } 454 + 455 + int inv_icm45600_buffer_fifo_parse(struct inv_icm45600_state *st) 456 + { 457 + struct inv_icm45600_sensor_state *gyro_st = iio_priv(st->indio_gyro); 458 + struct inv_icm45600_sensor_state *accel_st = iio_priv(st->indio_accel); 459 + struct inv_sensors_timestamp *ts; 460 + int ret; 461 + 462 + if (st->fifo.nb.total == 0) 463 + return 0; 464 + 465 + /* Handle gyroscope timestamp and FIFO data parsing. */ 466 + if (st->fifo.nb.gyro > 0) { 467 + ts = &gyro_st->ts; 468 + inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_gyro, 469 + st->timestamp.gyro); 470 + ret = inv_icm45600_gyro_parse_fifo(st->indio_gyro); 471 + if (ret) 472 + return ret; 473 + } 474 + 475 + /* Handle accelerometer timestamp and FIFO data parsing. */ 476 + if (st->fifo.nb.accel > 0) { 477 + ts = &accel_st->ts; 478 + inv_sensors_timestamp_interrupt(ts, st->fifo.watermark.eff_accel, 479 + st->timestamp.accel); 480 + ret = inv_icm45600_accel_parse_fifo(st->indio_accel); 481 + if (ret) 482 + return ret; 483 + } 484 + 485 + return 0; 486 + } 487 + 488 + int inv_icm45600_buffer_hwfifo_flush(struct inv_icm45600_state *st, 489 + unsigned int count) 490 + { 491 + struct inv_icm45600_sensor_state *gyro_st = iio_priv(st->indio_gyro); 492 + struct inv_icm45600_sensor_state *accel_st = iio_priv(st->indio_accel); 493 + struct inv_sensors_timestamp *ts; 494 + s64 gyro_ts, accel_ts; 495 + int ret; 496 + 497 + gyro_ts = iio_get_time_ns(st->indio_gyro); 498 + accel_ts = iio_get_time_ns(st->indio_accel); 499 + 500 + ret = inv_icm45600_buffer_fifo_read(st, count); 501 + if (ret) 502 + return ret; 503 + 504 + if (st->fifo.nb.total == 0) 505 + return 0; 506 + 507 + if (st->fifo.nb.gyro > 0) { 508 + ts = &gyro_st->ts; 509 + inv_sensors_timestamp_interrupt(ts, st->fifo.nb.gyro, gyro_ts); 510 + ret = inv_icm45600_gyro_parse_fifo(st->indio_gyro); 511 + if (ret) 512 + return ret; 513 + } 514 + 515 + if (st->fifo.nb.accel > 0) { 516 + ts = &accel_st->ts; 517 + inv_sensors_timestamp_interrupt(ts, st->fifo.nb.accel, accel_ts); 518 + ret = inv_icm45600_accel_parse_fifo(st->indio_accel); 519 + if (ret) 520 + return ret; 521 + } 522 + 523 + return 0; 524 + } 525 + 526 + int inv_icm45600_buffer_init(struct inv_icm45600_state *st) 527 + { 528 + int ret; 529 + unsigned int val; 530 + 531 + st->fifo.watermark.eff_gyro = 1; 532 + st->fifo.watermark.eff_accel = 1; 533 + 534 + /* Disable all FIFO EN bits. */ 535 + ret = regmap_write(st->map, INV_ICM45600_REG_FIFO_CONFIG3, 0); 536 + if (ret) 537 + return ret; 538 + 539 + /* Disable FIFO and set depth. */ 540 + val = FIELD_PREP(INV_ICM45600_FIFO_CONFIG0_MODE_MASK, 541 + INV_ICM45600_FIFO_CONFIG0_MODE_BYPASS) | 542 + FIELD_PREP(INV_ICM45600_FIFO_CONFIG0_FIFO_DEPTH_MASK, 543 + INV_ICM45600_FIFO_CONFIG0_FIFO_DEPTH_MAX); 544 + 545 + ret = regmap_write(st->map, INV_ICM45600_REG_FIFO_CONFIG0, val); 546 + if (ret) 547 + return ret; 548 + 549 + /* Enable only timestamp in fifo, disable compression. */ 550 + ret = regmap_write(st->map, INV_ICM45600_REG_FIFO_CONFIG4, 551 + INV_ICM45600_FIFO_CONFIG4_TMST_FSYNC_EN); 552 + if (ret) 553 + return ret; 554 + 555 + /* Enable FIFO continuous watermark interrupt. */ 556 + return regmap_set_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG2, 557 + INV_ICM45600_REG_FIFO_CONFIG2_WM_GT_TH); 558 + }
+101
drivers/iio/imu/inv_icm45600/inv_icm45600_buffer.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 + /* Copyright (C) 2025 Invensense, Inc. */ 3 + 4 + #ifndef INV_ICM45600_BUFFER_H_ 5 + #define INV_ICM45600_BUFFER_H_ 6 + 7 + #include <linux/bits.h> 8 + #include <linux/limits.h> 9 + #include <linux/types.h> 10 + 11 + #include <asm/byteorder.h> 12 + 13 + #include <linux/iio/iio.h> 14 + 15 + struct inv_icm45600_state; 16 + 17 + #define INV_ICM45600_SENSOR_GYRO BIT(0) 18 + #define INV_ICM45600_SENSOR_ACCEL BIT(1) 19 + #define INV_ICM45600_SENSOR_TEMP BIT(2) 20 + 21 + /** 22 + * struct inv_icm45600_fifo - FIFO state variables 23 + * @on: reference counter for FIFO on. 24 + * @en: bits field of INV_ICM45600_SENSOR_* for FIFO EN bits. 25 + * @period: FIFO internal period. 26 + * @watermark: watermark configuration values for accel and gyro. 27 + * @watermark.gyro: requested watermark for gyro. 28 + * @watermark.accel: requested watermark for accel. 29 + * @watermark.eff_gyro: effective watermark for gyro. 30 + * @watermark.eff_accel: effective watermark for accel. 31 + * @count: number of bytes in the FIFO data buffer. 32 + * @nb: gyro, accel and total samples in the FIFO data buffer. 33 + * @data: FIFO data buffer aligned for DMA (8kB) 34 + */ 35 + struct inv_icm45600_fifo { 36 + unsigned int on; 37 + unsigned int en; 38 + u32 period; 39 + struct { 40 + unsigned int gyro; 41 + unsigned int accel; 42 + unsigned int eff_gyro; 43 + unsigned int eff_accel; 44 + } watermark; 45 + size_t count; 46 + struct { 47 + size_t gyro; 48 + size_t accel; 49 + size_t total; 50 + } nb; 51 + u8 *data; 52 + }; 53 + 54 + /* FIFO data packet */ 55 + struct inv_icm45600_fifo_sensor_data { 56 + __le16 x; 57 + __le16 y; 58 + __le16 z; 59 + } __packed; 60 + #define INV_ICM45600_DATA_INVALID S16_MIN 61 + 62 + static inline bool 63 + inv_icm45600_fifo_is_data_valid(const struct inv_icm45600_fifo_sensor_data *s) 64 + { 65 + s16 x, y, z; 66 + 67 + x = le16_to_cpu(s->x); 68 + y = le16_to_cpu(s->y); 69 + z = le16_to_cpu(s->z); 70 + 71 + return (x != INV_ICM45600_DATA_INVALID || 72 + y != INV_ICM45600_DATA_INVALID || 73 + z != INV_ICM45600_DATA_INVALID); 74 + } 75 + 76 + ssize_t inv_icm45600_fifo_decode_packet(const void *packet, 77 + const struct inv_icm45600_fifo_sensor_data **accel, 78 + const struct inv_icm45600_fifo_sensor_data **gyro, 79 + const s8 **temp, 80 + const __le16 **timestamp, unsigned int *odr); 81 + 82 + extern const struct iio_buffer_setup_ops inv_icm45600_buffer_ops; 83 + 84 + int inv_icm45600_buffer_init(struct inv_icm45600_state *st); 85 + 86 + void inv_icm45600_buffer_update_fifo_period(struct inv_icm45600_state *st); 87 + 88 + int inv_icm45600_buffer_set_fifo_en(struct inv_icm45600_state *st, 89 + unsigned int fifo_en); 90 + 91 + int inv_icm45600_buffer_update_watermark(struct inv_icm45600_state *st); 92 + 93 + int inv_icm45600_buffer_fifo_read(struct inv_icm45600_state *st, 94 + unsigned int max); 95 + 96 + int inv_icm45600_buffer_fifo_parse(struct inv_icm45600_state *st); 97 + 98 + int inv_icm45600_buffer_hwfifo_flush(struct inv_icm45600_state *st, 99 + unsigned int count); 100 + 101 + #endif
+988
drivers/iio/imu/inv_icm45600/inv_icm45600_core.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* Copyright (C) 2025 Invensense, Inc. */ 3 + 4 + #include <linux/bitfield.h> 5 + #include <linux/delay.h> 6 + #include <linux/device.h> 7 + #include <linux/err.h> 8 + #include <linux/interrupt.h> 9 + #include <linux/irq.h> 10 + #include <linux/limits.h> 11 + #include <linux/minmax.h> 12 + #include <linux/module.h> 13 + #include <linux/mutex.h> 14 + #include <linux/pm_runtime.h> 15 + #include <linux/property.h> 16 + #include <linux/regmap.h> 17 + #include <linux/regulator/consumer.h> 18 + #include <linux/time.h> 19 + #include <linux/types.h> 20 + 21 + #include <asm/byteorder.h> 22 + 23 + #include <linux/iio/iio.h> 24 + 25 + #include "inv_icm45600_buffer.h" 26 + #include "inv_icm45600.h" 27 + 28 + static int inv_icm45600_ireg_read(struct regmap *map, unsigned int reg, 29 + u8 *data, size_t count) 30 + { 31 + const struct device *dev = regmap_get_device(map); 32 + struct inv_icm45600_state *st = dev_get_drvdata(dev); 33 + unsigned int d; 34 + size_t i; 35 + int ret; 36 + 37 + st->buffer.ireg[0] = FIELD_GET(INV_ICM45600_REG_BANK_MASK, reg); 38 + st->buffer.ireg[1] = FIELD_GET(INV_ICM45600_REG_ADDR_MASK, reg); 39 + 40 + /* Burst write address. */ 41 + ret = regmap_bulk_write(map, INV_ICM45600_REG_IREG_ADDR, st->buffer.ireg, 2); 42 + /* 43 + * Wait while the device is busy processing the address. 44 + * Datasheet: 13.3 MINIMUM WAIT TIME-GAP 45 + */ 46 + fsleep(INV_ICM45600_IREG_DELAY_US); 47 + if (ret) 48 + return ret; 49 + 50 + /* Read the data. */ 51 + for (i = 0; i < count; i++) { 52 + ret = regmap_read(map, INV_ICM45600_REG_IREG_DATA, &d); 53 + /* 54 + * Wait while the device is busy processing the address. 55 + * Datasheet: 13.3 MINIMUM WAIT TIME-GAP 56 + */ 57 + fsleep(INV_ICM45600_IREG_DELAY_US); 58 + if (ret) 59 + return ret; 60 + data[i] = d; 61 + } 62 + 63 + return 0; 64 + } 65 + 66 + static int inv_icm45600_ireg_write(struct regmap *map, unsigned int reg, 67 + const u8 *data, size_t count) 68 + { 69 + const struct device *dev = regmap_get_device(map); 70 + struct inv_icm45600_state *st = dev_get_drvdata(dev); 71 + size_t i; 72 + int ret; 73 + 74 + st->buffer.ireg[0] = FIELD_GET(INV_ICM45600_REG_BANK_MASK, reg); 75 + st->buffer.ireg[1] = FIELD_GET(INV_ICM45600_REG_ADDR_MASK, reg); 76 + st->buffer.ireg[2] = data[0]; 77 + 78 + /* Burst write address and first byte. */ 79 + ret = regmap_bulk_write(map, INV_ICM45600_REG_IREG_ADDR, st->buffer.ireg, 3); 80 + /* 81 + * Wait while the device is busy processing the address. 82 + * Datasheet: 13.3 MINIMUM WAIT TIME-GAP 83 + */ 84 + fsleep(INV_ICM45600_IREG_DELAY_US); 85 + if (ret) 86 + return ret; 87 + 88 + /* Write the remaining bytes. */ 89 + for (i = 1; i < count; i++) { 90 + ret = regmap_write(map, INV_ICM45600_REG_IREG_DATA, data[i]); 91 + /* 92 + * Wait while the device is busy processing the address. 93 + * Datasheet: 13.3 MINIMUM WAIT TIME-GAP 94 + */ 95 + fsleep(INV_ICM45600_IREG_DELAY_US); 96 + if (ret) 97 + return ret; 98 + } 99 + 100 + return 0; 101 + } 102 + 103 + static int inv_icm45600_read(void *context, const void *reg_buf, size_t reg_size, 104 + void *val_buf, size_t val_size) 105 + { 106 + unsigned int reg = be16_to_cpup(reg_buf); 107 + struct regmap *map = context; 108 + 109 + if (FIELD_GET(INV_ICM45600_REG_BANK_MASK, reg)) 110 + return inv_icm45600_ireg_read(map, reg, val_buf, val_size); 111 + 112 + return regmap_bulk_read(map, FIELD_GET(INV_ICM45600_REG_ADDR_MASK, reg), 113 + val_buf, val_size); 114 + } 115 + 116 + static int inv_icm45600_write(void *context, const void *data, size_t count) 117 + { 118 + const u8 *d = data; 119 + unsigned int reg = be16_to_cpup(data); 120 + struct regmap *map = context; 121 + 122 + if (FIELD_GET(INV_ICM45600_REG_BANK_MASK, reg)) 123 + return inv_icm45600_ireg_write(map, reg, d + 2, count - 2); 124 + 125 + return regmap_bulk_write(map, FIELD_GET(INV_ICM45600_REG_ADDR_MASK, reg), 126 + d + 2, count - 2); 127 + } 128 + 129 + static const struct regmap_bus inv_icm45600_regmap_bus = { 130 + .read = inv_icm45600_read, 131 + .write = inv_icm45600_write, 132 + }; 133 + 134 + static const struct regmap_config inv_icm45600_regmap_config = { 135 + .reg_bits = 16, 136 + .val_bits = 8, 137 + }; 138 + 139 + /* These are the chip initial default configurations (default FS value is based on icm45686) */ 140 + static const struct inv_icm45600_conf inv_icm45600_default_conf = { 141 + .gyro = { 142 + .mode = INV_ICM45600_SENSOR_MODE_OFF, 143 + .fs = INV_ICM45686_GYRO_FS_2000DPS, 144 + .odr = INV_ICM45600_ODR_800HZ_LN, 145 + .filter = INV_ICM45600_GYRO_LP_AVG_SEL_8X, 146 + }, 147 + .accel = { 148 + .mode = INV_ICM45600_SENSOR_MODE_OFF, 149 + .fs = INV_ICM45686_ACCEL_FS_16G, 150 + .odr = INV_ICM45600_ODR_800HZ_LN, 151 + .filter = INV_ICM45600_ACCEL_LP_AVG_SEL_4X, 152 + }, 153 + }; 154 + 155 + static const struct inv_icm45600_conf inv_icm45686_default_conf = { 156 + .gyro = { 157 + .mode = INV_ICM45600_SENSOR_MODE_OFF, 158 + .fs = INV_ICM45686_GYRO_FS_4000DPS, 159 + .odr = INV_ICM45600_ODR_800HZ_LN, 160 + .filter = INV_ICM45600_GYRO_LP_AVG_SEL_8X, 161 + }, 162 + .accel = { 163 + .mode = INV_ICM45600_SENSOR_MODE_OFF, 164 + .fs = INV_ICM45686_ACCEL_FS_32G, 165 + .odr = INV_ICM45600_ODR_800HZ_LN, 166 + .filter = INV_ICM45600_ACCEL_LP_AVG_SEL_4X, 167 + }, 168 + }; 169 + 170 + const struct inv_icm45600_chip_info inv_icm45605_chip_info = { 171 + .whoami = INV_ICM45600_WHOAMI_ICM45605, 172 + .name = "icm45605", 173 + .conf = &inv_icm45600_default_conf, 174 + .accel_scales = (const int *)inv_icm45600_accel_scale, 175 + .accel_scales_len = INV_ICM45600_ACCEL_FS_MAX, 176 + .gyro_scales = (const int *)inv_icm45600_gyro_scale, 177 + .gyro_scales_len = INV_ICM45600_GYRO_FS_MAX, 178 + }; 179 + EXPORT_SYMBOL_NS_GPL(inv_icm45605_chip_info, "IIO_ICM45600"); 180 + 181 + const struct inv_icm45600_chip_info inv_icm45606_chip_info = { 182 + .whoami = INV_ICM45600_WHOAMI_ICM45606, 183 + .name = "icm45606", 184 + .conf = &inv_icm45600_default_conf, 185 + .accel_scales = (const int *)inv_icm45600_accel_scale, 186 + .accel_scales_len = INV_ICM45600_ACCEL_FS_MAX, 187 + .gyro_scales = (const int *)inv_icm45600_gyro_scale, 188 + .gyro_scales_len = INV_ICM45600_GYRO_FS_MAX, 189 + }; 190 + EXPORT_SYMBOL_NS_GPL(inv_icm45606_chip_info, "IIO_ICM45600"); 191 + 192 + const struct inv_icm45600_chip_info inv_icm45608_chip_info = { 193 + .whoami = INV_ICM45600_WHOAMI_ICM45608, 194 + .name = "icm45608", 195 + .conf = &inv_icm45600_default_conf, 196 + .accel_scales = (const int *)inv_icm45600_accel_scale, 197 + .accel_scales_len = INV_ICM45600_ACCEL_FS_MAX, 198 + .gyro_scales = (const int *)inv_icm45600_gyro_scale, 199 + .gyro_scales_len = INV_ICM45600_GYRO_FS_MAX, 200 + }; 201 + EXPORT_SYMBOL_NS_GPL(inv_icm45608_chip_info, "IIO_ICM45600"); 202 + 203 + const struct inv_icm45600_chip_info inv_icm45634_chip_info = { 204 + .whoami = INV_ICM45600_WHOAMI_ICM45634, 205 + .name = "icm45634", 206 + .conf = &inv_icm45600_default_conf, 207 + .accel_scales = (const int *)inv_icm45600_accel_scale, 208 + .accel_scales_len = INV_ICM45600_ACCEL_FS_MAX, 209 + .gyro_scales = (const int *)inv_icm45600_gyro_scale, 210 + .gyro_scales_len = INV_ICM45600_GYRO_FS_MAX, 211 + }; 212 + EXPORT_SYMBOL_NS_GPL(inv_icm45634_chip_info, "IIO_ICM45600"); 213 + 214 + const struct inv_icm45600_chip_info inv_icm45686_chip_info = { 215 + .whoami = INV_ICM45600_WHOAMI_ICM45686, 216 + .name = "icm45686", 217 + .conf = &inv_icm45686_default_conf, 218 + .accel_scales = (const int *)inv_icm45686_accel_scale, 219 + .accel_scales_len = INV_ICM45686_ACCEL_FS_MAX, 220 + .gyro_scales = (const int *)inv_icm45686_gyro_scale, 221 + .gyro_scales_len = INV_ICM45686_GYRO_FS_MAX, 222 + }; 223 + EXPORT_SYMBOL_NS_GPL(inv_icm45686_chip_info, "IIO_ICM45600"); 224 + 225 + const struct inv_icm45600_chip_info inv_icm45687_chip_info = { 226 + .whoami = INV_ICM45600_WHOAMI_ICM45687, 227 + .name = "icm45687", 228 + .conf = &inv_icm45686_default_conf, 229 + .accel_scales = (const int *)inv_icm45686_accel_scale, 230 + .accel_scales_len = INV_ICM45686_ACCEL_FS_MAX, 231 + .gyro_scales = (const int *)inv_icm45686_gyro_scale, 232 + .gyro_scales_len = INV_ICM45686_GYRO_FS_MAX, 233 + }; 234 + EXPORT_SYMBOL_NS_GPL(inv_icm45687_chip_info, "IIO_ICM45600"); 235 + 236 + const struct inv_icm45600_chip_info inv_icm45688p_chip_info = { 237 + .whoami = INV_ICM45600_WHOAMI_ICM45688P, 238 + .name = "icm45688p", 239 + .conf = &inv_icm45686_default_conf, 240 + .accel_scales = (const int *)inv_icm45686_accel_scale, 241 + .accel_scales_len = INV_ICM45686_ACCEL_FS_MAX, 242 + .gyro_scales = (const int *)inv_icm45686_gyro_scale, 243 + .gyro_scales_len = INV_ICM45686_GYRO_FS_MAX, 244 + }; 245 + EXPORT_SYMBOL_NS_GPL(inv_icm45688p_chip_info, "IIO_ICM45600"); 246 + 247 + const struct inv_icm45600_chip_info inv_icm45689_chip_info = { 248 + .whoami = INV_ICM45600_WHOAMI_ICM45689, 249 + .name = "icm45689", 250 + .conf = &inv_icm45686_default_conf, 251 + .accel_scales = (const int *)inv_icm45686_accel_scale, 252 + .accel_scales_len = INV_ICM45686_ACCEL_FS_MAX, 253 + .gyro_scales = (const int *)inv_icm45686_gyro_scale, 254 + .gyro_scales_len = INV_ICM45686_GYRO_FS_MAX, 255 + }; 256 + EXPORT_SYMBOL_NS_GPL(inv_icm45689_chip_info, "IIO_ICM45600"); 257 + 258 + const struct iio_mount_matrix * 259 + inv_icm45600_get_mount_matrix(const struct iio_dev *indio_dev, 260 + const struct iio_chan_spec *chan) 261 + { 262 + const struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 263 + 264 + return &st->orientation; 265 + } 266 + 267 + u32 inv_icm45600_odr_to_period(enum inv_icm45600_odr odr) 268 + { 269 + static const u32 odr_periods[INV_ICM45600_ODR_MAX] = { 270 + /* 3 first values are reserved, left to 0 */ 271 + [INV_ICM45600_ODR_6400HZ_LN] = 156250, 272 + [INV_ICM45600_ODR_3200HZ_LN] = 312500, 273 + [INV_ICM45600_ODR_1600HZ_LN] = 625000, 274 + [INV_ICM45600_ODR_800HZ_LN] = 1250000, 275 + [INV_ICM45600_ODR_400HZ] = 2500000, 276 + [INV_ICM45600_ODR_200HZ] = 5000000, 277 + [INV_ICM45600_ODR_100HZ] = 10000000, 278 + [INV_ICM45600_ODR_50HZ] = 20000000, 279 + [INV_ICM45600_ODR_25HZ] = 40000000, 280 + [INV_ICM45600_ODR_12_5HZ] = 80000000, 281 + [INV_ICM45600_ODR_6_25HZ_LP] = 160000000, 282 + [INV_ICM45600_ODR_3_125HZ_LP] = 320000000, 283 + [INV_ICM45600_ODR_1_5625HZ_LP] = 640000000, 284 + }; 285 + 286 + return odr_periods[odr]; 287 + } 288 + 289 + static int inv_icm45600_set_pwr_mgmt0(struct inv_icm45600_state *st, 290 + enum inv_icm45600_sensor_mode gyro, 291 + enum inv_icm45600_sensor_mode accel, 292 + unsigned int *sleep_ms) 293 + { 294 + enum inv_icm45600_sensor_mode oldgyro = st->conf.gyro.mode; 295 + enum inv_icm45600_sensor_mode oldaccel = st->conf.accel.mode; 296 + unsigned int sleepval; 297 + unsigned int val; 298 + int ret; 299 + 300 + /* if nothing changed, exit */ 301 + if (gyro == oldgyro && accel == oldaccel) 302 + return 0; 303 + 304 + val = FIELD_PREP(INV_ICM45600_PWR_MGMT0_GYRO_MODE_MASK, gyro) | 305 + FIELD_PREP(INV_ICM45600_PWR_MGMT0_ACCEL_MODE_MASK, accel); 306 + ret = regmap_write(st->map, INV_ICM45600_REG_PWR_MGMT0, val); 307 + if (ret) 308 + return ret; 309 + 310 + st->conf.gyro.mode = gyro; 311 + st->conf.accel.mode = accel; 312 + 313 + /* Compute the required wait time for sensors to stabilize. */ 314 + sleepval = 0; 315 + if (accel != oldaccel && oldaccel == INV_ICM45600_SENSOR_MODE_OFF) 316 + sleepval = max(sleepval, INV_ICM45600_ACCEL_STARTUP_TIME_MS); 317 + 318 + if (gyro != oldgyro) { 319 + if (oldgyro == INV_ICM45600_SENSOR_MODE_OFF) 320 + sleepval = max(sleepval, INV_ICM45600_GYRO_STARTUP_TIME_MS); 321 + else if (gyro == INV_ICM45600_SENSOR_MODE_OFF) 322 + sleepval = max(sleepval, INV_ICM45600_GYRO_STOP_TIME_MS); 323 + } 324 + 325 + /* Deferred sleep value if sleep pointer is provided or direct sleep */ 326 + if (sleep_ms) 327 + *sleep_ms = sleepval; 328 + else if (sleepval) 329 + msleep(sleepval); 330 + 331 + return 0; 332 + } 333 + 334 + static void inv_icm45600_set_default_conf(struct inv_icm45600_sensor_conf *conf, 335 + struct inv_icm45600_sensor_conf *oldconf) 336 + { 337 + /* Sanitize missing values with current values. */ 338 + if (conf->mode == U8_MAX) 339 + conf->mode = oldconf->mode; 340 + if (conf->fs == U8_MAX) 341 + conf->fs = oldconf->fs; 342 + if (conf->odr == U8_MAX) 343 + conf->odr = oldconf->odr; 344 + if (conf->filter == U8_MAX) 345 + conf->filter = oldconf->filter; 346 + } 347 + 348 + int inv_icm45600_set_accel_conf(struct inv_icm45600_state *st, 349 + struct inv_icm45600_sensor_conf *conf, 350 + unsigned int *sleep_ms) 351 + { 352 + struct inv_icm45600_sensor_conf *oldconf = &st->conf.accel; 353 + unsigned int val; 354 + int ret; 355 + 356 + inv_icm45600_set_default_conf(conf, oldconf); 357 + 358 + /* Force the power mode against the ODR when sensor is on. */ 359 + if (conf->mode > INV_ICM45600_SENSOR_MODE_STANDBY) { 360 + if (conf->odr <= INV_ICM45600_ODR_800HZ_LN) { 361 + conf->mode = INV_ICM45600_SENSOR_MODE_LOW_NOISE; 362 + } else { 363 + conf->mode = INV_ICM45600_SENSOR_MODE_LOW_POWER; 364 + /* sanitize averaging value depending on ODR for low-power mode */ 365 + /* maximum 1x @400Hz */ 366 + if (conf->odr == INV_ICM45600_ODR_400HZ) 367 + conf->filter = INV_ICM45600_ACCEL_LP_AVG_SEL_1X; 368 + else 369 + conf->filter = INV_ICM45600_ACCEL_LP_AVG_SEL_4X; 370 + } 371 + } 372 + 373 + /* Set accel fullscale & odr. */ 374 + if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { 375 + val = FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_FS_MASK, conf->fs) | 376 + FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_ODR_MASK, conf->odr); 377 + ret = regmap_write(st->map, INV_ICM45600_REG_ACCEL_CONFIG0, val); 378 + if (ret) 379 + return ret; 380 + oldconf->fs = conf->fs; 381 + oldconf->odr = conf->odr; 382 + } 383 + 384 + /* Set accel low-power average filter. */ 385 + if (conf->filter != oldconf->filter) { 386 + ret = regmap_write(st->map, INV_ICM45600_IPREG_SYS2_REG_129, 387 + conf->filter); 388 + if (ret) 389 + return ret; 390 + oldconf->filter = conf->filter; 391 + } 392 + 393 + /* Update the sensor accel mode. */ 394 + return inv_icm45600_set_pwr_mgmt0(st, st->conf.gyro.mode, conf->mode, 395 + sleep_ms); 396 + } 397 + 398 + int inv_icm45600_set_gyro_conf(struct inv_icm45600_state *st, 399 + struct inv_icm45600_sensor_conf *conf, 400 + unsigned int *sleep_ms) 401 + { 402 + struct inv_icm45600_sensor_conf *oldconf = &st->conf.gyro; 403 + unsigned int val; 404 + int ret; 405 + 406 + inv_icm45600_set_default_conf(conf, oldconf); 407 + 408 + /* Force the power mode against ODR when sensor is on. */ 409 + if (conf->mode > INV_ICM45600_SENSOR_MODE_STANDBY) { 410 + if (conf->odr >= INV_ICM45600_ODR_6_25HZ_LP) { 411 + conf->mode = INV_ICM45600_SENSOR_MODE_LOW_POWER; 412 + conf->filter = INV_ICM45600_GYRO_LP_AVG_SEL_8X; 413 + } else { 414 + conf->mode = INV_ICM45600_SENSOR_MODE_LOW_NOISE; 415 + } 416 + } 417 + 418 + /* Set gyro fullscale & odr. */ 419 + if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { 420 + val = FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_FS_MASK, conf->fs) | 421 + FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_ODR_MASK, conf->odr); 422 + ret = regmap_write(st->map, INV_ICM45600_REG_GYRO_CONFIG0, val); 423 + if (ret) 424 + return ret; 425 + oldconf->fs = conf->fs; 426 + oldconf->odr = conf->odr; 427 + } 428 + 429 + /* Set gyro low-power average filter. */ 430 + if (conf->filter != oldconf->filter) { 431 + val = FIELD_PREP(INV_ICM45600_IPREG_SYS1_170_GYRO_LP_AVG_MASK, conf->filter); 432 + ret = regmap_update_bits(st->map, INV_ICM45600_IPREG_SYS1_REG_170, 433 + INV_ICM45600_IPREG_SYS1_170_GYRO_LP_AVG_MASK, val); 434 + if (ret) 435 + return ret; 436 + oldconf->filter = conf->filter; 437 + } 438 + 439 + /* Update the sensor gyro mode. */ 440 + return inv_icm45600_set_pwr_mgmt0(st, conf->mode, st->conf.accel.mode, 441 + sleep_ms); 442 + } 443 + 444 + int inv_icm45600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg, 445 + unsigned int writeval, unsigned int *readval) 446 + { 447 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 448 + 449 + guard(mutex)(&st->lock); 450 + 451 + if (readval) 452 + return regmap_read(st->map, reg, readval); 453 + else 454 + return regmap_write(st->map, reg, writeval); 455 + } 456 + 457 + static int inv_icm45600_set_conf(struct inv_icm45600_state *st, 458 + const struct inv_icm45600_conf *conf) 459 + { 460 + unsigned int val; 461 + int ret; 462 + 463 + val = FIELD_PREP(INV_ICM45600_PWR_MGMT0_GYRO_MODE_MASK, conf->gyro.mode) | 464 + FIELD_PREP(INV_ICM45600_PWR_MGMT0_ACCEL_MODE_MASK, conf->accel.mode); 465 + ret = regmap_write(st->map, INV_ICM45600_REG_PWR_MGMT0, val); 466 + if (ret) 467 + return ret; 468 + 469 + val = FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_FS_MASK, conf->gyro.fs) | 470 + FIELD_PREP(INV_ICM45600_GYRO_CONFIG0_ODR_MASK, conf->gyro.odr); 471 + ret = regmap_write(st->map, INV_ICM45600_REG_GYRO_CONFIG0, val); 472 + if (ret) 473 + return ret; 474 + 475 + val = FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_FS_MASK, conf->accel.fs) | 476 + FIELD_PREP(INV_ICM45600_ACCEL_CONFIG0_ODR_MASK, conf->accel.odr); 477 + ret = regmap_write(st->map, INV_ICM45600_REG_ACCEL_CONFIG0, val); 478 + if (ret) 479 + return ret; 480 + 481 + /* Save configuration. */ 482 + st->conf = *conf; 483 + 484 + return 0; 485 + } 486 + 487 + /** 488 + * inv_icm45600_setup() - check and setup chip 489 + * @st: driver internal state 490 + * @chip_info: detected chip description 491 + * @reset: define whether a reset is required or not 492 + * @bus_setup: callback for setting up bus specific registers 493 + * 494 + * Returns: 0 on success, a negative error code otherwise. 495 + */ 496 + static int inv_icm45600_setup(struct inv_icm45600_state *st, 497 + const struct inv_icm45600_chip_info *chip_info, 498 + bool reset, inv_icm45600_bus_setup bus_setup) 499 + { 500 + const struct device *dev = regmap_get_device(st->map); 501 + unsigned int val; 502 + int ret; 503 + 504 + /* Set chip bus configuration if specified. */ 505 + if (bus_setup) { 506 + ret = bus_setup(st); 507 + if (ret) 508 + return ret; 509 + } 510 + 511 + /* Check chip self-identification value. */ 512 + ret = regmap_read(st->map, INV_ICM45600_REG_WHOAMI, &val); 513 + if (ret) 514 + return ret; 515 + if (val != chip_info->whoami) { 516 + /* 517 + * SPI interface has no ack mechanism. 518 + * 0xFF or 0x00 whoami means no response from the device. 519 + */ 520 + if (val == U8_MAX || val == 0) 521 + return dev_err_probe(dev, -ENODEV, 522 + "Invalid whoami %#02x expected %#02x (%s)\n", 523 + val, chip_info->whoami, chip_info->name); 524 + 525 + dev_warn(dev, "Unexpected whoami %#02x expected %#02x (%s)\n", 526 + val, chip_info->whoami, chip_info->name); 527 + } 528 + 529 + st->chip_info = chip_info; 530 + 531 + if (reset) { 532 + /* Reset previous state. */ 533 + ret = regmap_write(st->map, INV_ICM45600_REG_MISC2, 534 + INV_ICM45600_MISC2_SOFT_RESET); 535 + if (ret) 536 + return ret; 537 + /* 538 + * IMU reset time. 539 + * Datasheet: 16.84 REG_MISC2 540 + */ 541 + fsleep(USEC_PER_MSEC); 542 + 543 + if (bus_setup) { 544 + ret = bus_setup(st); 545 + if (ret) 546 + return ret; 547 + } 548 + 549 + ret = regmap_read(st->map, INV_ICM45600_REG_INT_STATUS, &val); 550 + if (ret) 551 + return ret; 552 + if (!(val & INV_ICM45600_INT_STATUS_RESET_DONE)) { 553 + dev_err(dev, "reset error, reset done bit not set\n"); 554 + return -ENODEV; 555 + } 556 + } 557 + 558 + return inv_icm45600_set_conf(st, chip_info->conf); 559 + } 560 + 561 + static irqreturn_t inv_icm45600_irq_timestamp(int irq, void *_data) 562 + { 563 + struct inv_icm45600_state *st = _data; 564 + 565 + st->timestamp.gyro = iio_get_time_ns(st->indio_gyro); 566 + st->timestamp.accel = iio_get_time_ns(st->indio_accel); 567 + 568 + return IRQ_WAKE_THREAD; 569 + } 570 + 571 + static irqreturn_t inv_icm45600_irq_handler(int irq, void *_data) 572 + { 573 + struct inv_icm45600_state *st = _data; 574 + struct device *dev = regmap_get_device(st->map); 575 + unsigned int mask, status; 576 + int ret; 577 + 578 + guard(mutex)(&st->lock); 579 + 580 + ret = regmap_read(st->map, INV_ICM45600_REG_INT_STATUS, &status); 581 + if (ret) 582 + return IRQ_HANDLED; 583 + 584 + /* Read the FIFO data. */ 585 + mask = INV_ICM45600_INT_STATUS_FIFO_THS | INV_ICM45600_INT_STATUS_FIFO_FULL; 586 + if (status & mask) { 587 + ret = inv_icm45600_buffer_fifo_read(st, 0); 588 + if (ret) { 589 + dev_err(dev, "FIFO read error %d\n", ret); 590 + return IRQ_HANDLED; 591 + } 592 + ret = inv_icm45600_buffer_fifo_parse(st); 593 + if (ret) 594 + dev_err(dev, "FIFO parsing error %d\n", ret); 595 + } 596 + 597 + /* FIFO full warning. */ 598 + if (status & INV_ICM45600_INT_STATUS_FIFO_FULL) 599 + dev_warn(dev, "FIFO full possible data lost!\n"); 600 + 601 + return IRQ_HANDLED; 602 + } 603 + 604 + /** 605 + * inv_icm45600_irq_init() - initialize int pin and interrupt handler 606 + * @st: driver internal state 607 + * @irq: irq number 608 + * @irq_type: irq trigger type 609 + * @open_drain: true if irq is open drain, false for push-pull 610 + * 611 + * Returns: 0 on success, a negative error code otherwise. 612 + */ 613 + static int inv_icm45600_irq_init(struct inv_icm45600_state *st, int irq, 614 + int irq_type, bool open_drain) 615 + { 616 + struct device *dev = regmap_get_device(st->map); 617 + unsigned int val; 618 + int ret; 619 + 620 + /* Configure INT1 interrupt: default is active low on edge. */ 621 + switch (irq_type) { 622 + case IRQF_TRIGGER_RISING: 623 + case IRQF_TRIGGER_HIGH: 624 + val = INV_ICM45600_INT1_CONFIG2_ACTIVE_HIGH; 625 + break; 626 + default: 627 + val = INV_ICM45600_INT1_CONFIG2_ACTIVE_LOW; 628 + break; 629 + } 630 + 631 + switch (irq_type) { 632 + case IRQF_TRIGGER_LOW: 633 + case IRQF_TRIGGER_HIGH: 634 + val |= INV_ICM45600_INT1_CONFIG2_LATCHED; 635 + break; 636 + default: 637 + break; 638 + } 639 + 640 + if (!open_drain) 641 + val |= INV_ICM45600_INT1_CONFIG2_PUSH_PULL; 642 + 643 + ret = regmap_write(st->map, INV_ICM45600_REG_INT1_CONFIG2, val); 644 + if (ret) 645 + return ret; 646 + 647 + return devm_request_threaded_irq(dev, irq, inv_icm45600_irq_timestamp, 648 + inv_icm45600_irq_handler, irq_type | IRQF_ONESHOT, 649 + "inv_icm45600", st); 650 + } 651 + 652 + static int inv_icm45600_timestamp_setup(struct inv_icm45600_state *st) 653 + { 654 + /* Enable timestamps. */ 655 + return regmap_set_bits(st->map, INV_ICM45600_REG_SMC_CONTROL_0, 656 + INV_ICM45600_SMC_CONTROL_0_TMST_EN); 657 + } 658 + 659 + static int inv_icm45600_enable_regulator_vddio(struct inv_icm45600_state *st) 660 + { 661 + int ret; 662 + 663 + ret = regulator_enable(st->vddio_supply); 664 + if (ret) 665 + return ret; 666 + 667 + /* 668 + * Wait a little for supply ramp. 669 + * Duration is empirically defined. 670 + */ 671 + fsleep(3 * USEC_PER_MSEC); 672 + 673 + return 0; 674 + } 675 + 676 + static void inv_icm45600_disable_vddio_reg(void *_data) 677 + { 678 + struct inv_icm45600_state *st = _data; 679 + struct device *dev = regmap_get_device(st->map); 680 + 681 + if (pm_runtime_status_suspended(dev)) 682 + return; 683 + 684 + regulator_disable(st->vddio_supply); 685 + } 686 + 687 + int inv_icm45600_core_probe(struct regmap *regmap, const struct inv_icm45600_chip_info *chip_info, 688 + bool reset, inv_icm45600_bus_setup bus_setup) 689 + { 690 + struct device *dev = regmap_get_device(regmap); 691 + struct inv_icm45600_state *st; 692 + struct regmap *regmap_custom; 693 + struct fwnode_handle *fwnode; 694 + int irq, irq_type; 695 + bool open_drain; 696 + int ret; 697 + 698 + /* Get INT1 only supported interrupt. */ 699 + fwnode = dev_fwnode(dev); 700 + irq = fwnode_irq_get_byname(fwnode, "int1"); 701 + if (irq < 0) 702 + return dev_err_probe(dev, irq, "Missing int1 interrupt\n"); 703 + 704 + irq_type = irq_get_trigger_type(irq); 705 + 706 + open_drain = device_property_read_bool(dev, "drive-open-drain"); 707 + 708 + regmap_custom = devm_regmap_init(dev, &inv_icm45600_regmap_bus, regmap, 709 + &inv_icm45600_regmap_config); 710 + if (IS_ERR(regmap_custom)) 711 + return dev_err_probe(dev, PTR_ERR(regmap_custom), "Failed to register regmap\n"); 712 + 713 + st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); 714 + if (!st) 715 + return -ENOMEM; 716 + 717 + dev_set_drvdata(dev, st); 718 + 719 + st->fifo.data = devm_kzalloc(dev, 8192, GFP_KERNEL); 720 + if (!st->fifo.data) 721 + return -ENOMEM; 722 + 723 + ret = devm_mutex_init(dev, &st->lock); 724 + if (ret) 725 + return ret; 726 + 727 + st->map = regmap_custom; 728 + 729 + ret = iio_read_mount_matrix(dev, &st->orientation); 730 + if (ret) 731 + return dev_err_probe(dev, ret, "Failed to retrieve mounting matrix\n"); 732 + 733 + st->vddio_supply = devm_regulator_get(dev, "vddio"); 734 + if (IS_ERR(st->vddio_supply)) 735 + return PTR_ERR(st->vddio_supply); 736 + 737 + ret = devm_regulator_get_enable(dev, "vdd"); 738 + if (ret) 739 + return dev_err_probe(dev, ret, "Failed to get vdd regulator\n"); 740 + 741 + /* 742 + * Supply ramp time + Start-up time. 743 + * Datasheet: 3.3.2 A.C. Electrical Characteristics 744 + */ 745 + fsleep(5 * USEC_PER_MSEC); 746 + 747 + ret = inv_icm45600_enable_regulator_vddio(st); 748 + if (ret) 749 + return ret; 750 + 751 + ret = devm_add_action_or_reset(dev, inv_icm45600_disable_vddio_reg, st); 752 + if (ret) 753 + return ret; 754 + 755 + ret = inv_icm45600_setup(st, chip_info, reset, bus_setup); 756 + if (ret) 757 + return ret; 758 + 759 + ret = inv_icm45600_timestamp_setup(st); 760 + if (ret) 761 + return ret; 762 + 763 + ret = inv_icm45600_buffer_init(st); 764 + if (ret) 765 + return ret; 766 + 767 + st->indio_gyro = inv_icm45600_gyro_init(st); 768 + if (IS_ERR(st->indio_gyro)) 769 + return PTR_ERR(st->indio_gyro); 770 + 771 + st->indio_accel = inv_icm45600_accel_init(st); 772 + if (IS_ERR(st->indio_accel)) 773 + return PTR_ERR(st->indio_accel); 774 + 775 + ret = inv_icm45600_irq_init(st, irq, irq_type, open_drain); 776 + if (ret) 777 + return ret; 778 + 779 + ret = devm_pm_runtime_set_active_enabled(dev); 780 + if (ret) 781 + return ret; 782 + 783 + pm_runtime_get_noresume(dev); 784 + pm_runtime_set_autosuspend_delay(dev, 2 * USEC_PER_MSEC); 785 + pm_runtime_use_autosuspend(dev); 786 + pm_runtime_put(dev); 787 + 788 + return 0; 789 + } 790 + EXPORT_SYMBOL_NS_GPL(inv_icm45600_core_probe, "IIO_ICM45600"); 791 + 792 + /* 793 + * Suspend saves sensors state and turns everything off. 794 + */ 795 + static int inv_icm45600_suspend(struct device *dev) 796 + { 797 + struct inv_icm45600_state *st = dev_get_drvdata(dev); 798 + int ret; 799 + 800 + scoped_guard(mutex, &st->lock) { 801 + /* Disable FIFO data streaming. */ 802 + if (st->fifo.on) { 803 + unsigned int val; 804 + 805 + /* Clear FIFO_CONFIG3_IF_EN before changing the FIFO configuration */ 806 + ret = regmap_clear_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG3, 807 + INV_ICM45600_FIFO_CONFIG3_IF_EN); 808 + if (ret) 809 + return ret; 810 + val = FIELD_PREP(INV_ICM45600_FIFO_CONFIG0_MODE_MASK, 811 + INV_ICM45600_FIFO_CONFIG0_MODE_BYPASS); 812 + ret = regmap_update_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG0, 813 + INV_ICM45600_FIFO_CONFIG0_MODE_MASK, val); 814 + if (ret) 815 + return ret; 816 + } 817 + 818 + /* Save sensors states */ 819 + st->suspended.gyro = st->conf.gyro.mode; 820 + st->suspended.accel = st->conf.accel.mode; 821 + } 822 + 823 + return pm_runtime_force_suspend(dev); 824 + } 825 + 826 + /* 827 + * System resume gets the system back on and restores the sensors state. 828 + * Manually put runtime power management in system active state. 829 + */ 830 + static int inv_icm45600_resume(struct device *dev) 831 + { 832 + struct inv_icm45600_state *st = dev_get_drvdata(dev); 833 + int ret; 834 + 835 + ret = pm_runtime_force_resume(dev); 836 + if (ret) 837 + return ret; 838 + 839 + scoped_guard(mutex, &st->lock) { 840 + /* Restore sensors state. */ 841 + ret = inv_icm45600_set_pwr_mgmt0(st, st->suspended.gyro, 842 + st->suspended.accel, NULL); 843 + if (ret) 844 + return ret; 845 + 846 + /* Restore FIFO data streaming. */ 847 + if (st->fifo.on) { 848 + struct inv_icm45600_sensor_state *gyro_st = iio_priv(st->indio_gyro); 849 + struct inv_icm45600_sensor_state *accel_st = iio_priv(st->indio_accel); 850 + unsigned int val; 851 + 852 + inv_sensors_timestamp_reset(&gyro_st->ts); 853 + inv_sensors_timestamp_reset(&accel_st->ts); 854 + val = FIELD_PREP(INV_ICM45600_FIFO_CONFIG0_MODE_MASK, 855 + INV_ICM45600_FIFO_CONFIG0_MODE_STREAM); 856 + ret = regmap_update_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG0, 857 + INV_ICM45600_FIFO_CONFIG0_MODE_MASK, val); 858 + if (ret) 859 + return ret; 860 + /* FIFO_CONFIG3_IF_EN must only be set at end of FIFO the configuration */ 861 + ret = regmap_set_bits(st->map, INV_ICM45600_REG_FIFO_CONFIG3, 862 + INV_ICM45600_FIFO_CONFIG3_IF_EN); 863 + if (ret) 864 + return ret; 865 + } 866 + } 867 + 868 + return ret; 869 + } 870 + 871 + /* Runtime suspend will turn off sensors that are enabled by iio devices. */ 872 + static int inv_icm45600_runtime_suspend(struct device *dev) 873 + { 874 + struct inv_icm45600_state *st = dev_get_drvdata(dev); 875 + int ret; 876 + 877 + guard(mutex)(&st->lock); 878 + 879 + /* disable all sensors */ 880 + ret = inv_icm45600_set_pwr_mgmt0(st, INV_ICM45600_SENSOR_MODE_OFF, 881 + INV_ICM45600_SENSOR_MODE_OFF, NULL); 882 + if (ret) 883 + return ret; 884 + 885 + regulator_disable(st->vddio_supply); 886 + 887 + return 0; 888 + } 889 + 890 + /* Sensors are enabled by iio devices, no need to turn them back on here. */ 891 + static int inv_icm45600_runtime_resume(struct device *dev) 892 + { 893 + struct inv_icm45600_state *st = dev_get_drvdata(dev); 894 + 895 + guard(mutex)(&st->lock); 896 + 897 + return inv_icm45600_enable_regulator_vddio(st); 898 + } 899 + 900 + static int _inv_icm45600_temp_read(struct inv_icm45600_state *st, s16 *temp) 901 + { 902 + struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; 903 + int ret; 904 + 905 + /* Make sure a sensor is on. */ 906 + if (st->conf.gyro.mode == INV_ICM45600_SENSOR_MODE_OFF && 907 + st->conf.accel.mode == INV_ICM45600_SENSOR_MODE_OFF) { 908 + conf.mode = INV_ICM45600_SENSOR_MODE_LOW_POWER; 909 + ret = inv_icm45600_set_accel_conf(st, &conf, NULL); 910 + if (ret) 911 + return ret; 912 + } 913 + 914 + ret = regmap_bulk_read(st->map, INV_ICM45600_REG_TEMP_DATA, 915 + &st->buffer.u16, sizeof(st->buffer.u16)); 916 + if (ret) 917 + return ret; 918 + 919 + *temp = (s16)le16_to_cpup(&st->buffer.u16); 920 + if (*temp == INV_ICM45600_DATA_INVALID) 921 + return -EINVAL; 922 + 923 + return 0; 924 + } 925 + 926 + static int inv_icm45600_temp_read(struct inv_icm45600_state *st, s16 *temp) 927 + { 928 + struct device *dev = regmap_get_device(st->map); 929 + int ret; 930 + 931 + ret = pm_runtime_resume_and_get(dev); 932 + if (ret) 933 + return ret; 934 + 935 + scoped_guard(mutex, &st->lock) 936 + ret = _inv_icm45600_temp_read(st, temp); 937 + 938 + pm_runtime_put_autosuspend(dev); 939 + 940 + return ret; 941 + } 942 + 943 + int inv_icm45600_temp_read_raw(struct iio_dev *indio_dev, 944 + struct iio_chan_spec const *chan, 945 + int *val, int *val2, long mask) 946 + { 947 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 948 + s16 temp; 949 + int ret; 950 + 951 + if (chan->type != IIO_TEMP) 952 + return -EINVAL; 953 + 954 + switch (mask) { 955 + case IIO_CHAN_INFO_RAW: 956 + ret = inv_icm45600_temp_read(st, &temp); 957 + if (ret) 958 + return ret; 959 + *val = temp; 960 + return IIO_VAL_INT; 961 + /* 962 + * T°C = (temp / 128) + 25 963 + * Tm°C = 1000 * ((temp * 100 / 12800) + 25) 964 + * scale: 100000 / 13248 = 7.8125 965 + * offset: 25000 966 + */ 967 + case IIO_CHAN_INFO_SCALE: 968 + *val = 7; 969 + *val2 = 812500; 970 + return IIO_VAL_INT_PLUS_MICRO; 971 + case IIO_CHAN_INFO_OFFSET: 972 + *val = 25000; 973 + return IIO_VAL_INT; 974 + default: 975 + return -EINVAL; 976 + } 977 + } 978 + 979 + EXPORT_NS_GPL_DEV_PM_OPS(inv_icm45600_pm_ops, IIO_ICM45600) = { 980 + SYSTEM_SLEEP_PM_OPS(inv_icm45600_suspend, inv_icm45600_resume) 981 + RUNTIME_PM_OPS(inv_icm45600_runtime_suspend, 982 + inv_icm45600_runtime_resume, NULL) 983 + }; 984 + 985 + MODULE_AUTHOR("InvenSense, Inc."); 986 + MODULE_DESCRIPTION("InvenSense ICM-456xx device driver"); 987 + MODULE_LICENSE("GPL"); 988 + MODULE_IMPORT_NS("IIO_INV_SENSORS_TIMESTAMP");
+791
drivers/iio/imu/inv_icm45600/inv_icm45600_gyro.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Copyright (C) 2025 Invensense, Inc. 4 + */ 5 + 6 + #include <linux/delay.h> 7 + #include <linux/device.h> 8 + #include <linux/err.h> 9 + #include <linux/math64.h> 10 + #include <linux/mutex.h> 11 + #include <linux/pm_runtime.h> 12 + #include <linux/regmap.h> 13 + #include <linux/types.h> 14 + 15 + #include <linux/iio/buffer.h> 16 + #include <linux/iio/common/inv_sensors_timestamp.h> 17 + #include <linux/iio/iio.h> 18 + #include <linux/iio/kfifo_buf.h> 19 + 20 + #include "inv_icm45600_buffer.h" 21 + #include "inv_icm45600.h" 22 + 23 + enum inv_icm45600_gyro_scan { 24 + INV_ICM45600_GYRO_SCAN_X, 25 + INV_ICM45600_GYRO_SCAN_Y, 26 + INV_ICM45600_GYRO_SCAN_Z, 27 + INV_ICM45600_GYRO_SCAN_TEMP, 28 + INV_ICM45600_GYRO_SCAN_TIMESTAMP, 29 + }; 30 + 31 + static const struct iio_chan_spec_ext_info inv_icm45600_gyro_ext_infos[] = { 32 + IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, inv_icm45600_get_mount_matrix), 33 + { } 34 + }; 35 + 36 + #define INV_ICM45600_GYRO_CHAN(_modifier, _index, _ext_info) \ 37 + { \ 38 + .type = IIO_ANGL_VEL, \ 39 + .modified = 1, \ 40 + .channel2 = _modifier, \ 41 + .info_mask_separate = \ 42 + BIT(IIO_CHAN_INFO_RAW) | \ 43 + BIT(IIO_CHAN_INFO_CALIBBIAS), \ 44 + .info_mask_shared_by_type = \ 45 + BIT(IIO_CHAN_INFO_SCALE), \ 46 + .info_mask_shared_by_type_available = \ 47 + BIT(IIO_CHAN_INFO_SCALE) | \ 48 + BIT(IIO_CHAN_INFO_CALIBBIAS), \ 49 + .info_mask_shared_by_all = \ 50 + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 51 + .info_mask_shared_by_all_available = \ 52 + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 53 + .scan_index = _index, \ 54 + .scan_type = { \ 55 + .sign = 's', \ 56 + .realbits = 16, \ 57 + .storagebits = 16, \ 58 + .endianness = IIO_LE, \ 59 + }, \ 60 + .ext_info = _ext_info, \ 61 + } 62 + 63 + static const struct iio_chan_spec inv_icm45600_gyro_channels[] = { 64 + INV_ICM45600_GYRO_CHAN(IIO_MOD_X, INV_ICM45600_GYRO_SCAN_X, 65 + inv_icm45600_gyro_ext_infos), 66 + INV_ICM45600_GYRO_CHAN(IIO_MOD_Y, INV_ICM45600_GYRO_SCAN_Y, 67 + inv_icm45600_gyro_ext_infos), 68 + INV_ICM45600_GYRO_CHAN(IIO_MOD_Z, INV_ICM45600_GYRO_SCAN_Z, 69 + inv_icm45600_gyro_ext_infos), 70 + INV_ICM45600_TEMP_CHAN(INV_ICM45600_GYRO_SCAN_TEMP), 71 + IIO_CHAN_SOFT_TIMESTAMP(INV_ICM45600_GYRO_SCAN_TIMESTAMP), 72 + }; 73 + 74 + /* 75 + * IIO buffer data: size must be a power of 2 and timestamp aligned 76 + * 16 bytes: 6 bytes angular velocity, 2 bytes temperature, 8 bytes timestamp 77 + */ 78 + struct inv_icm45600_gyro_buffer { 79 + struct inv_icm45600_fifo_sensor_data gyro; 80 + s16 temp; 81 + aligned_s64 timestamp; 82 + }; 83 + 84 + static const unsigned long inv_icm45600_gyro_scan_masks[] = { 85 + /* 3-axis gyro + temperature */ 86 + BIT(INV_ICM45600_GYRO_SCAN_X) | 87 + BIT(INV_ICM45600_GYRO_SCAN_Y) | 88 + BIT(INV_ICM45600_GYRO_SCAN_Z) | 89 + BIT(INV_ICM45600_GYRO_SCAN_TEMP), 90 + 0 91 + }; 92 + 93 + /* enable gyroscope sensor and FIFO write */ 94 + static int inv_icm45600_gyro_update_scan_mode(struct iio_dev *indio_dev, 95 + const unsigned long *scan_mask) 96 + { 97 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 98 + struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev); 99 + struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; 100 + unsigned int fifo_en = 0; 101 + unsigned int sleep = 0; 102 + int ret; 103 + 104 + scoped_guard(mutex, &st->lock) { 105 + if (*scan_mask & BIT(INV_ICM45600_GYRO_SCAN_TEMP)) 106 + fifo_en |= INV_ICM45600_SENSOR_TEMP; 107 + 108 + if (*scan_mask & (BIT(INV_ICM45600_GYRO_SCAN_X) | 109 + BIT(INV_ICM45600_GYRO_SCAN_Y) | 110 + BIT(INV_ICM45600_GYRO_SCAN_Z))) { 111 + /* enable gyro sensor */ 112 + conf.mode = gyro_st->power_mode; 113 + ret = inv_icm45600_set_gyro_conf(st, &conf, &sleep); 114 + if (ret) 115 + return ret; 116 + fifo_en |= INV_ICM45600_SENSOR_GYRO; 117 + } 118 + ret = inv_icm45600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); 119 + } 120 + if (sleep) 121 + msleep(sleep); 122 + 123 + return ret; 124 + } 125 + 126 + static int _inv_icm45600_gyro_read_sensor(struct inv_icm45600_state *st, 127 + struct inv_icm45600_sensor_state *gyro_st, 128 + unsigned int reg, int *val) 129 + { 130 + struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; 131 + int ret; 132 + 133 + /* enable gyro sensor */ 134 + conf.mode = gyro_st->power_mode; 135 + ret = inv_icm45600_set_gyro_conf(st, &conf, NULL); 136 + if (ret) 137 + return ret; 138 + 139 + /* read gyro register data */ 140 + ret = regmap_bulk_read(st->map, reg, &st->buffer.u16, sizeof(st->buffer.u16)); 141 + if (ret) 142 + return ret; 143 + 144 + *val = sign_extend32(le16_to_cpup(&st->buffer.u16), 15); 145 + if (*val == INV_ICM45600_DATA_INVALID) 146 + return -ENODATA; 147 + 148 + return 0; 149 + } 150 + 151 + static int inv_icm45600_gyro_read_sensor(struct iio_dev *indio_dev, 152 + struct iio_chan_spec const *chan, 153 + int *val) 154 + { 155 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 156 + struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev); 157 + struct device *dev = regmap_get_device(st->map); 158 + unsigned int reg; 159 + int ret; 160 + 161 + if (chan->type != IIO_ANGL_VEL) 162 + return -EINVAL; 163 + 164 + switch (chan->channel2) { 165 + case IIO_MOD_X: 166 + reg = INV_ICM45600_REG_GYRO_DATA_X; 167 + break; 168 + case IIO_MOD_Y: 169 + reg = INV_ICM45600_REG_GYRO_DATA_Y; 170 + break; 171 + case IIO_MOD_Z: 172 + reg = INV_ICM45600_REG_GYRO_DATA_Z; 173 + break; 174 + default: 175 + return -EINVAL; 176 + } 177 + 178 + ret = pm_runtime_resume_and_get(dev); 179 + if (ret) 180 + return ret; 181 + 182 + scoped_guard(mutex, &st->lock) 183 + ret = _inv_icm45600_gyro_read_sensor(st, gyro_st, reg, val); 184 + 185 + pm_runtime_put_autosuspend(dev); 186 + 187 + return ret; 188 + } 189 + 190 + /* IIO format int + nano */ 191 + const int inv_icm45600_gyro_scale[][2] = { 192 + /* +/- 2000dps => 0.001065264 rad/s */ 193 + [INV_ICM45600_GYRO_FS_2000DPS] = { 0, 1065264 }, 194 + /* +/- 1000dps => 0.000532632 rad/s */ 195 + [INV_ICM45600_GYRO_FS_1000DPS] = { 0, 532632 }, 196 + /* +/- 500dps => 0.000266316 rad/s */ 197 + [INV_ICM45600_GYRO_FS_500DPS] = { 0, 266316 }, 198 + /* +/- 250dps => 0.000133158 rad/s */ 199 + [INV_ICM45600_GYRO_FS_250DPS] = { 0, 133158 }, 200 + /* +/- 125dps => 0.000066579 rad/s */ 201 + [INV_ICM45600_GYRO_FS_125DPS] = { 0, 66579 }, 202 + /* +/- 62.5dps => 0.000033290 rad/s */ 203 + [INV_ICM45600_GYRO_FS_62_5DPS] = { 0, 33290 }, 204 + /* +/- 31.25dps => 0.000016645 rad/s */ 205 + [INV_ICM45600_GYRO_FS_31_25DPS] = { 0, 16645 }, 206 + /* +/- 15.625dps => 0.000008322 rad/s */ 207 + [INV_ICM45600_GYRO_FS_15_625DPS] = { 0, 8322 }, 208 + }; 209 + 210 + /* IIO format int + nano */ 211 + const int inv_icm45686_gyro_scale[][2] = { 212 + /* +/- 4000dps => 0.002130529 rad/s */ 213 + [INV_ICM45686_GYRO_FS_4000DPS] = { 0, 2130529 }, 214 + /* +/- 2000dps => 0.001065264 rad/s */ 215 + [INV_ICM45686_GYRO_FS_2000DPS] = { 0, 1065264 }, 216 + /* +/- 1000dps => 0.000532632 rad/s */ 217 + [INV_ICM45686_GYRO_FS_1000DPS] = { 0, 532632 }, 218 + /* +/- 500dps => 0.000266316 rad/s */ 219 + [INV_ICM45686_GYRO_FS_500DPS] = { 0, 266316 }, 220 + /* +/- 250dps => 0.000133158 rad/s */ 221 + [INV_ICM45686_GYRO_FS_250DPS] = { 0, 133158 }, 222 + /* +/- 125dps => 0.000066579 rad/s */ 223 + [INV_ICM45686_GYRO_FS_125DPS] = { 0, 66579 }, 224 + /* +/- 62.5dps => 0.000033290 rad/s */ 225 + [INV_ICM45686_GYRO_FS_62_5DPS] = { 0, 33290 }, 226 + /* +/- 31.25dps => 0.000016645 rad/s */ 227 + [INV_ICM45686_GYRO_FS_31_25DPS] = { 0, 16645 }, 228 + /* +/- 15.625dps => 0.000008322 rad/s */ 229 + [INV_ICM45686_GYRO_FS_15_625DPS] = { 0, 8322 }, 230 + }; 231 + 232 + static int inv_icm45600_gyro_read_scale(struct iio_dev *indio_dev, 233 + int *val, int *val2) 234 + { 235 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 236 + struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev); 237 + unsigned int idx; 238 + 239 + idx = st->conf.gyro.fs; 240 + 241 + /* Full scale register starts at 1 for not High FSR parts */ 242 + if (gyro_st->scales == (const int *)&inv_icm45600_gyro_scale) 243 + idx--; 244 + 245 + *val = gyro_st->scales[2 * idx]; 246 + *val2 = gyro_st->scales[2 * idx + 1]; 247 + return IIO_VAL_INT_PLUS_NANO; 248 + } 249 + 250 + static int inv_icm45600_gyro_write_scale(struct iio_dev *indio_dev, 251 + int val, int val2) 252 + { 253 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 254 + struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev); 255 + struct device *dev = regmap_get_device(st->map); 256 + unsigned int idx; 257 + struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; 258 + int ret; 259 + 260 + for (idx = 0; idx < gyro_st->scales_len; idx += 2) { 261 + if (val == gyro_st->scales[idx] && 262 + val2 == gyro_st->scales[idx + 1]) 263 + break; 264 + } 265 + if (idx == gyro_st->scales_len) 266 + return -EINVAL; 267 + 268 + conf.fs = idx / 2; 269 + 270 + /* Full scale register starts at 1 for not High FSR parts */ 271 + if (gyro_st->scales == (const int *)&inv_icm45600_gyro_scale) 272 + conf.fs++; 273 + 274 + ret = pm_runtime_resume_and_get(dev); 275 + if (ret) 276 + return ret; 277 + 278 + scoped_guard(mutex, &st->lock) 279 + ret = inv_icm45600_set_gyro_conf(st, &conf, NULL); 280 + 281 + pm_runtime_put_autosuspend(dev); 282 + 283 + return ret; 284 + } 285 + 286 + /* IIO format int + micro */ 287 + static const int inv_icm45600_gyro_odr[] = { 288 + 1, 562500, /* 1.5625Hz */ 289 + 3, 125000, /* 3.125Hz */ 290 + 6, 250000, /* 6.25Hz */ 291 + 12, 500000, /* 12.5Hz */ 292 + 25, 0, /* 25Hz */ 293 + 50, 0, /* 50Hz */ 294 + 100, 0, /* 100Hz */ 295 + 200, 0, /* 200Hz */ 296 + 400, 0, /* 400Hz */ 297 + 800, 0, /* 800Hz */ 298 + 1600, 0, /* 1.6kHz */ 299 + 3200, 0, /* 3.2kHz */ 300 + 6400, 0, /* 6.4kHz */ 301 + }; 302 + 303 + static const int inv_icm45600_gyro_odr_conv[] = { 304 + INV_ICM45600_ODR_1_5625HZ_LP, 305 + INV_ICM45600_ODR_3_125HZ_LP, 306 + INV_ICM45600_ODR_6_25HZ_LP, 307 + INV_ICM45600_ODR_12_5HZ, 308 + INV_ICM45600_ODR_25HZ, 309 + INV_ICM45600_ODR_50HZ, 310 + INV_ICM45600_ODR_100HZ, 311 + INV_ICM45600_ODR_200HZ, 312 + INV_ICM45600_ODR_400HZ, 313 + INV_ICM45600_ODR_800HZ_LN, 314 + INV_ICM45600_ODR_1600HZ_LN, 315 + INV_ICM45600_ODR_3200HZ_LN, 316 + INV_ICM45600_ODR_6400HZ_LN, 317 + }; 318 + 319 + static int inv_icm45600_gyro_read_odr(struct inv_icm45600_state *st, 320 + int *val, int *val2) 321 + { 322 + unsigned int odr; 323 + unsigned int i; 324 + 325 + odr = st->conf.gyro.odr; 326 + 327 + for (i = 0; i < ARRAY_SIZE(inv_icm45600_gyro_odr_conv); ++i) { 328 + if (inv_icm45600_gyro_odr_conv[i] == odr) 329 + break; 330 + } 331 + if (i >= ARRAY_SIZE(inv_icm45600_gyro_odr_conv)) 332 + return -EINVAL; 333 + 334 + *val = inv_icm45600_gyro_odr[2 * i]; 335 + *val2 = inv_icm45600_gyro_odr[2 * i + 1]; 336 + 337 + return IIO_VAL_INT_PLUS_MICRO; 338 + } 339 + 340 + static int _inv_icm45600_gyro_write_odr(struct iio_dev *indio_dev, int odr) 341 + { 342 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 343 + struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev); 344 + struct inv_sensors_timestamp *ts = &gyro_st->ts; 345 + struct inv_icm45600_sensor_conf conf = INV_ICM45600_SENSOR_CONF_KEEP_VALUES; 346 + int ret; 347 + 348 + conf.odr = odr; 349 + ret = inv_sensors_timestamp_update_odr(ts, inv_icm45600_odr_to_period(conf.odr), 350 + iio_buffer_enabled(indio_dev)); 351 + if (ret) 352 + return ret; 353 + 354 + if (st->conf.gyro.mode != INV_ICM45600_SENSOR_MODE_OFF) 355 + conf.mode = gyro_st->power_mode; 356 + 357 + ret = inv_icm45600_set_gyro_conf(st, &conf, NULL); 358 + if (ret) 359 + return ret; 360 + 361 + inv_icm45600_buffer_update_fifo_period(st); 362 + inv_icm45600_buffer_update_watermark(st); 363 + 364 + return 0; 365 + } 366 + 367 + static int inv_icm45600_gyro_write_odr(struct iio_dev *indio_dev, 368 + int val, int val2) 369 + { 370 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 371 + struct device *dev = regmap_get_device(st->map); 372 + unsigned int idx; 373 + int odr; 374 + int ret; 375 + 376 + for (idx = 0; idx < ARRAY_SIZE(inv_icm45600_gyro_odr); idx += 2) { 377 + if (val == inv_icm45600_gyro_odr[idx] && 378 + val2 == inv_icm45600_gyro_odr[idx + 1]) 379 + break; 380 + } 381 + if (idx >= ARRAY_SIZE(inv_icm45600_gyro_odr)) 382 + return -EINVAL; 383 + 384 + odr = inv_icm45600_gyro_odr_conv[idx / 2]; 385 + 386 + ret = pm_runtime_resume_and_get(dev); 387 + if (ret) 388 + return ret; 389 + 390 + scoped_guard(mutex, &st->lock) 391 + ret = _inv_icm45600_gyro_write_odr(indio_dev, odr); 392 + 393 + pm_runtime_put_autosuspend(dev); 394 + 395 + return ret; 396 + } 397 + 398 + /* 399 + * Calibration bias values, IIO range format int + nano. 400 + * Value is limited to +/-62.5dps coded on 14 bits signed. Step is 7.5mdps. 401 + */ 402 + static int inv_icm45600_gyro_calibbias[] = { 403 + -1, 90830336, /* min: -1.090830336 rad/s */ 404 + 0, 133158, /* step: 0.000133158 rad/s */ 405 + 1, 90697178, /* max: 1.090697178 rad/s */ 406 + }; 407 + 408 + static int inv_icm45600_gyro_read_offset(struct inv_icm45600_state *st, 409 + struct iio_chan_spec const *chan, 410 + int *val, int *val2) 411 + { 412 + struct device *dev = regmap_get_device(st->map); 413 + s64 val64; 414 + s32 bias; 415 + unsigned int reg; 416 + s16 offset; 417 + int ret; 418 + 419 + if (chan->type != IIO_ANGL_VEL) 420 + return -EINVAL; 421 + 422 + switch (chan->channel2) { 423 + case IIO_MOD_X: 424 + reg = INV_ICM45600_IPREG_SYS1_REG_42; 425 + break; 426 + case IIO_MOD_Y: 427 + reg = INV_ICM45600_IPREG_SYS1_REG_56; 428 + break; 429 + case IIO_MOD_Z: 430 + reg = INV_ICM45600_IPREG_SYS1_REG_70; 431 + break; 432 + default: 433 + return -EINVAL; 434 + } 435 + 436 + ret = pm_runtime_resume_and_get(dev); 437 + if (ret) 438 + return ret; 439 + 440 + scoped_guard(mutex, &st->lock) 441 + ret = regmap_bulk_read(st->map, reg, &st->buffer.u16, sizeof(st->buffer.u16)); 442 + 443 + pm_runtime_put_autosuspend(dev); 444 + if (ret) 445 + return ret; 446 + 447 + offset = le16_to_cpup(&st->buffer.u16) & INV_ICM45600_GYRO_OFFUSER_MASK; 448 + /* 14 bits signed value */ 449 + offset = sign_extend32(offset, 13); 450 + 451 + /* 452 + * convert raw offset to dps then to rad/s 453 + * 14 bits signed raw max 62.5 to dps: 625 / 81920 454 + * dps to rad: Pi / 180 455 + * result in nano (1000000000) 456 + * (offset * 625 * Pi * 1000000000) / (81920 * 180) 457 + */ 458 + val64 = (s64)offset * 625LL * 3141592653LL; 459 + /* for rounding, add + or - divisor (81920 * 180) divided by 2 */ 460 + if (val64 >= 0) 461 + val64 += 81920 * 180 / 2; 462 + else 463 + val64 -= 81920 * 180 / 2; 464 + bias = div_s64(val64, 81920 * 180); 465 + *val = bias / 1000000000L; 466 + *val2 = bias % 1000000000L; 467 + 468 + return IIO_VAL_INT_PLUS_NANO; 469 + } 470 + 471 + static int inv_icm45600_gyro_write_offset(struct inv_icm45600_state *st, 472 + struct iio_chan_spec const *chan, 473 + int val, int val2) 474 + { 475 + struct device *dev = regmap_get_device(st->map); 476 + s64 val64, min, max; 477 + unsigned int reg; 478 + s16 offset; 479 + int ret; 480 + 481 + if (chan->type != IIO_ANGL_VEL) 482 + return -EINVAL; 483 + 484 + switch (chan->channel2) { 485 + case IIO_MOD_X: 486 + reg = INV_ICM45600_IPREG_SYS1_REG_42; 487 + break; 488 + case IIO_MOD_Y: 489 + reg = INV_ICM45600_IPREG_SYS1_REG_56; 490 + break; 491 + case IIO_MOD_Z: 492 + reg = INV_ICM45600_IPREG_SYS1_REG_70; 493 + break; 494 + default: 495 + return -EINVAL; 496 + } 497 + 498 + /* inv_icm45600_gyro_calibbias: min - step - max in nano */ 499 + min = (s64)inv_icm45600_gyro_calibbias[0] * 1000000000LL - 500 + (s64)inv_icm45600_gyro_calibbias[1]; 501 + max = (s64)inv_icm45600_gyro_calibbias[4] * 1000000000LL + 502 + (s64)inv_icm45600_gyro_calibbias[5]; 503 + val64 = (s64)val * 1000000000LL; 504 + if (val >= 0) 505 + val64 += (s64)val2; 506 + else 507 + val64 -= (s64)val2; 508 + if (val64 < min || val64 > max) 509 + return -EINVAL; 510 + 511 + /* 512 + * convert rad/s to dps then to raw value 513 + * rad to dps: 180 / Pi 514 + * dps to raw 14 bits signed, max 62.5: 8192 / 62.5 515 + * val in nano (1000000000) 516 + * val * 180 * 8192 / (Pi * 1000000000 * 62.5) 517 + */ 518 + val64 = val64 * 180LL * 8192; 519 + /* for rounding, add + or - divisor (314159265 * 625) divided by 2 */ 520 + if (val64 >= 0) 521 + val64 += 314159265LL * 625LL / 2LL; 522 + else 523 + val64 -= 314159265LL * 625LL / 2LL; 524 + offset = div64_s64(val64, 314159265LL * 625LL); 525 + 526 + /* clamp value limited to 14 bits signed */ 527 + offset = clamp(offset, -8192, 8191); 528 + 529 + st->buffer.u16 = cpu_to_le16(offset & INV_ICM45600_GYRO_OFFUSER_MASK); 530 + 531 + ret = pm_runtime_resume_and_get(dev); 532 + if (ret) 533 + return ret; 534 + 535 + scoped_guard(mutex, &st->lock) 536 + ret = regmap_bulk_write(st->map, reg, &st->buffer.u16, sizeof(st->buffer.u16)); 537 + 538 + pm_runtime_put_autosuspend(dev); 539 + return ret; 540 + } 541 + 542 + static int inv_icm45600_gyro_read_raw(struct iio_dev *indio_dev, 543 + struct iio_chan_spec const *chan, 544 + int *val, int *val2, long mask) 545 + { 546 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 547 + int ret; 548 + 549 + switch (chan->type) { 550 + case IIO_ANGL_VEL: 551 + break; 552 + case IIO_TEMP: 553 + return inv_icm45600_temp_read_raw(indio_dev, chan, val, val2, mask); 554 + default: 555 + return -EINVAL; 556 + } 557 + 558 + switch (mask) { 559 + case IIO_CHAN_INFO_RAW: 560 + if (!iio_device_claim_direct(indio_dev)) 561 + return -EBUSY; 562 + ret = inv_icm45600_gyro_read_sensor(indio_dev, chan, val); 563 + iio_device_release_direct(indio_dev); 564 + if (ret) 565 + return ret; 566 + return IIO_VAL_INT; 567 + case IIO_CHAN_INFO_SCALE: 568 + return inv_icm45600_gyro_read_scale(indio_dev, val, val2); 569 + case IIO_CHAN_INFO_SAMP_FREQ: 570 + return inv_icm45600_gyro_read_odr(st, val, val2); 571 + case IIO_CHAN_INFO_CALIBBIAS: 572 + return inv_icm45600_gyro_read_offset(st, chan, val, val2); 573 + default: 574 + return -EINVAL; 575 + } 576 + } 577 + 578 + static int inv_icm45600_gyro_read_avail(struct iio_dev *indio_dev, 579 + struct iio_chan_spec const *chan, 580 + const int **vals, 581 + int *type, int *length, long mask) 582 + { 583 + struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev); 584 + 585 + if (chan->type != IIO_ANGL_VEL) 586 + return -EINVAL; 587 + 588 + switch (mask) { 589 + case IIO_CHAN_INFO_SCALE: 590 + *vals = gyro_st->scales; 591 + *type = IIO_VAL_INT_PLUS_NANO; 592 + *length = gyro_st->scales_len; 593 + return IIO_AVAIL_LIST; 594 + case IIO_CHAN_INFO_SAMP_FREQ: 595 + *vals = inv_icm45600_gyro_odr; 596 + *type = IIO_VAL_INT_PLUS_MICRO; 597 + *length = ARRAY_SIZE(inv_icm45600_gyro_odr); 598 + return IIO_AVAIL_LIST; 599 + case IIO_CHAN_INFO_CALIBBIAS: 600 + *vals = inv_icm45600_gyro_calibbias; 601 + *type = IIO_VAL_INT_PLUS_NANO; 602 + return IIO_AVAIL_RANGE; 603 + default: 604 + return -EINVAL; 605 + } 606 + } 607 + 608 + static int inv_icm45600_gyro_write_raw(struct iio_dev *indio_dev, 609 + struct iio_chan_spec const *chan, 610 + int val, int val2, long mask) 611 + { 612 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 613 + int ret; 614 + 615 + if (chan->type != IIO_ANGL_VEL) 616 + return -EINVAL; 617 + 618 + switch (mask) { 619 + case IIO_CHAN_INFO_SCALE: 620 + if (!iio_device_claim_direct(indio_dev)) 621 + return -EBUSY; 622 + ret = inv_icm45600_gyro_write_scale(indio_dev, val, val2); 623 + iio_device_release_direct(indio_dev); 624 + return ret; 625 + case IIO_CHAN_INFO_SAMP_FREQ: 626 + return inv_icm45600_gyro_write_odr(indio_dev, val, val2); 627 + case IIO_CHAN_INFO_CALIBBIAS: 628 + if (!iio_device_claim_direct(indio_dev)) 629 + return -EBUSY; 630 + ret = inv_icm45600_gyro_write_offset(st, chan, val, val2); 631 + iio_device_release_direct(indio_dev); 632 + return ret; 633 + default: 634 + return -EINVAL; 635 + } 636 + } 637 + 638 + static int inv_icm45600_gyro_write_raw_get_fmt(struct iio_dev *indio_dev, 639 + struct iio_chan_spec const *chan, 640 + long mask) 641 + { 642 + if (chan->type != IIO_ANGL_VEL) 643 + return -EINVAL; 644 + 645 + switch (mask) { 646 + case IIO_CHAN_INFO_SCALE: 647 + return IIO_VAL_INT_PLUS_NANO; 648 + case IIO_CHAN_INFO_SAMP_FREQ: 649 + return IIO_VAL_INT_PLUS_MICRO; 650 + case IIO_CHAN_INFO_CALIBBIAS: 651 + return IIO_VAL_INT_PLUS_NANO; 652 + default: 653 + return -EINVAL; 654 + } 655 + } 656 + 657 + static int inv_icm45600_gyro_hwfifo_set_watermark(struct iio_dev *indio_dev, 658 + unsigned int val) 659 + { 660 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 661 + 662 + guard(mutex)(&st->lock); 663 + 664 + st->fifo.watermark.gyro = val; 665 + return inv_icm45600_buffer_update_watermark(st); 666 + } 667 + 668 + static int inv_icm45600_gyro_hwfifo_flush(struct iio_dev *indio_dev, 669 + unsigned int count) 670 + { 671 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 672 + int ret; 673 + 674 + if (count == 0) 675 + return 0; 676 + 677 + guard(mutex)(&st->lock); 678 + 679 + ret = inv_icm45600_buffer_hwfifo_flush(st, count); 680 + if (ret) 681 + return ret; 682 + 683 + return st->fifo.nb.gyro; 684 + } 685 + 686 + static const struct iio_info inv_icm45600_gyro_info = { 687 + .read_raw = inv_icm45600_gyro_read_raw, 688 + .read_avail = inv_icm45600_gyro_read_avail, 689 + .write_raw = inv_icm45600_gyro_write_raw, 690 + .write_raw_get_fmt = inv_icm45600_gyro_write_raw_get_fmt, 691 + .debugfs_reg_access = inv_icm45600_debugfs_reg, 692 + .update_scan_mode = inv_icm45600_gyro_update_scan_mode, 693 + .hwfifo_set_watermark = inv_icm45600_gyro_hwfifo_set_watermark, 694 + .hwfifo_flush_to_buffer = inv_icm45600_gyro_hwfifo_flush, 695 + }; 696 + 697 + struct iio_dev *inv_icm45600_gyro_init(struct inv_icm45600_state *st) 698 + { 699 + struct device *dev = regmap_get_device(st->map); 700 + struct inv_icm45600_sensor_state *gyro_st; 701 + struct inv_sensors_timestamp_chip ts_chip; 702 + struct iio_dev *indio_dev; 703 + const char *name; 704 + int ret; 705 + 706 + name = devm_kasprintf(dev, GFP_KERNEL, "%s-gyro", st->chip_info->name); 707 + if (!name) 708 + return ERR_PTR(-ENOMEM); 709 + 710 + indio_dev = devm_iio_device_alloc(dev, sizeof(*gyro_st)); 711 + if (!indio_dev) 712 + return ERR_PTR(-ENOMEM); 713 + gyro_st = iio_priv(indio_dev); 714 + 715 + gyro_st->scales = st->chip_info->gyro_scales; 716 + gyro_st->scales_len = st->chip_info->gyro_scales_len * 2; 717 + 718 + /* low-noise by default at init */ 719 + gyro_st->power_mode = INV_ICM45600_SENSOR_MODE_LOW_NOISE; 720 + 721 + /* 722 + * clock period is 32kHz (31250ns) 723 + * jitter is +/- 2% (20 per mille) 724 + */ 725 + ts_chip.clock_period = 31250; 726 + ts_chip.jitter = 20; 727 + ts_chip.init_period = inv_icm45600_odr_to_period(st->conf.gyro.odr); 728 + inv_sensors_timestamp_init(&gyro_st->ts, &ts_chip); 729 + 730 + iio_device_set_drvdata(indio_dev, st); 731 + indio_dev->name = name; 732 + indio_dev->info = &inv_icm45600_gyro_info; 733 + indio_dev->modes = INDIO_DIRECT_MODE; 734 + indio_dev->channels = inv_icm45600_gyro_channels; 735 + indio_dev->num_channels = ARRAY_SIZE(inv_icm45600_gyro_channels); 736 + indio_dev->available_scan_masks = inv_icm45600_gyro_scan_masks; 737 + indio_dev->setup_ops = &inv_icm45600_buffer_ops; 738 + 739 + ret = devm_iio_kfifo_buffer_setup(dev, indio_dev, 740 + &inv_icm45600_buffer_ops); 741 + if (ret) 742 + return ERR_PTR(ret); 743 + 744 + ret = devm_iio_device_register(dev, indio_dev); 745 + if (ret) 746 + return ERR_PTR(ret); 747 + 748 + return indio_dev; 749 + } 750 + 751 + int inv_icm45600_gyro_parse_fifo(struct iio_dev *indio_dev) 752 + { 753 + struct inv_icm45600_state *st = iio_device_get_drvdata(indio_dev); 754 + struct inv_icm45600_sensor_state *gyro_st = iio_priv(indio_dev); 755 + struct inv_sensors_timestamp *ts = &gyro_st->ts; 756 + ssize_t i, size; 757 + unsigned int no; 758 + 759 + /* parse all fifo packets */ 760 + for (i = 0, no = 0; i < st->fifo.count; i += size, ++no) { 761 + struct inv_icm45600_gyro_buffer buffer = { }; 762 + const struct inv_icm45600_fifo_sensor_data *accel, *gyro; 763 + const __le16 *timestamp; 764 + const s8 *temp; 765 + unsigned int odr; 766 + s64 ts_val; 767 + 768 + size = inv_icm45600_fifo_decode_packet(&st->fifo.data[i], 769 + &accel, &gyro, &temp, &timestamp, &odr); 770 + /* quit if error or FIFO is empty */ 771 + if (size <= 0) 772 + return size; 773 + 774 + /* skip packet if no gyro data or data is invalid */ 775 + if (gyro == NULL || !inv_icm45600_fifo_is_data_valid(gyro)) 776 + continue; 777 + 778 + /* update odr */ 779 + if (odr & INV_ICM45600_SENSOR_GYRO) 780 + inv_sensors_timestamp_apply_odr(ts, st->fifo.period, 781 + st->fifo.nb.total, no); 782 + 783 + memcpy(&buffer.gyro, gyro, sizeof(buffer.gyro)); 784 + /* convert 8 bits FIFO temperature in high resolution format */ 785 + buffer.temp = temp ? (*temp * 64) : 0; 786 + ts_val = inv_sensors_timestamp_pop(ts); 787 + iio_push_to_buffers_with_ts(indio_dev, &buffer, sizeof(buffer), ts_val); 788 + } 789 + 790 + return 0; 791 + }
+98
drivers/iio/imu/inv_icm45600/inv_icm45600_i2c.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* Copyright (C) 2025 InvenSense, Inc. */ 3 + 4 + #include <linux/device.h> 5 + #include <linux/err.h> 6 + #include <linux/i2c.h> 7 + #include <linux/module.h> 8 + #include <linux/mod_devicetable.h> 9 + #include <linux/regmap.h> 10 + 11 + #include "inv_icm45600.h" 12 + 13 + static const struct regmap_config inv_icm45600_regmap_config = { 14 + .reg_bits = 8, 15 + .val_bits = 8, 16 + }; 17 + 18 + static int inv_icm45600_probe(struct i2c_client *client) 19 + { 20 + const struct inv_icm45600_chip_info *chip_info; 21 + struct regmap *regmap; 22 + 23 + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) 24 + return -ENODEV; 25 + 26 + chip_info = device_get_match_data(&client->dev); 27 + if (!chip_info) 28 + return -ENODEV; 29 + 30 + regmap = devm_regmap_init_i2c(client, &inv_icm45600_regmap_config); 31 + if (IS_ERR(regmap)) 32 + return PTR_ERR(regmap); 33 + 34 + return inv_icm45600_core_probe(regmap, chip_info, true, NULL); 35 + } 36 + 37 + /* 38 + * The device id table is used to identify which device is 39 + * supported by this driver. 40 + */ 41 + static const struct i2c_device_id inv_icm45600_id[] = { 42 + { "icm45605", (kernel_ulong_t)&inv_icm45605_chip_info }, 43 + { "icm45606", (kernel_ulong_t)&inv_icm45606_chip_info }, 44 + { "icm45608", (kernel_ulong_t)&inv_icm45608_chip_info }, 45 + { "icm45634", (kernel_ulong_t)&inv_icm45634_chip_info }, 46 + { "icm45686", (kernel_ulong_t)&inv_icm45686_chip_info }, 47 + { "icm45687", (kernel_ulong_t)&inv_icm45687_chip_info }, 48 + { "icm45688p", (kernel_ulong_t)&inv_icm45688p_chip_info }, 49 + { "icm45689", (kernel_ulong_t)&inv_icm45689_chip_info }, 50 + { } 51 + }; 52 + MODULE_DEVICE_TABLE(i2c, inv_icm45600_id); 53 + 54 + static const struct of_device_id inv_icm45600_of_matches[] = { 55 + { 56 + .compatible = "invensense,icm45605", 57 + .data = &inv_icm45605_chip_info, 58 + }, { 59 + .compatible = "invensense,icm45606", 60 + .data = &inv_icm45606_chip_info, 61 + }, { 62 + .compatible = "invensense,icm45608", 63 + .data = &inv_icm45608_chip_info, 64 + }, { 65 + .compatible = "invensense,icm45634", 66 + .data = &inv_icm45634_chip_info, 67 + }, { 68 + .compatible = "invensense,icm45686", 69 + .data = &inv_icm45686_chip_info, 70 + }, { 71 + .compatible = "invensense,icm45687", 72 + .data = &inv_icm45687_chip_info, 73 + }, { 74 + .compatible = "invensense,icm45688p", 75 + .data = &inv_icm45688p_chip_info, 76 + }, { 77 + .compatible = "invensense,icm45689", 78 + .data = &inv_icm45689_chip_info, 79 + }, 80 + { } 81 + }; 82 + MODULE_DEVICE_TABLE(of, inv_icm45600_of_matches); 83 + 84 + static struct i2c_driver inv_icm45600_driver = { 85 + .driver = { 86 + .name = "inv-icm45600-i2c", 87 + .of_match_table = inv_icm45600_of_matches, 88 + .pm = pm_ptr(&inv_icm45600_pm_ops), 89 + }, 90 + .id_table = inv_icm45600_id, 91 + .probe = inv_icm45600_probe, 92 + }; 93 + module_i2c_driver(inv_icm45600_driver); 94 + 95 + MODULE_AUTHOR("InvenSense, Inc."); 96 + MODULE_DESCRIPTION("InvenSense ICM-456xx I2C driver"); 97 + MODULE_LICENSE("GPL"); 98 + MODULE_IMPORT_NS("IIO_ICM45600");
+79
drivers/iio/imu/inv_icm45600/inv_icm45600_i3c.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* Copyright (C) 2025 InvenSense, Inc. */ 3 + 4 + #include <linux/err.h> 5 + #include <linux/mod_devicetable.h> 6 + #include <linux/module.h> 7 + #include <linux/regmap.h> 8 + 9 + #include <linux/i3c/device.h> 10 + #include <linux/i3c/master.h> 11 + 12 + #include "inv_icm45600.h" 13 + 14 + static const struct regmap_config inv_icm45600_regmap_config = { 15 + .reg_bits = 8, 16 + .val_bits = 8, 17 + }; 18 + 19 + static const struct i3c_device_id inv_icm45600_i3c_ids[] = { 20 + I3C_DEVICE_EXTRA_INFO(0x0235, 0x0000, 0x0011, (void *)NULL), 21 + I3C_DEVICE_EXTRA_INFO(0x0235, 0x0000, 0x0084, (void *)NULL), 22 + { /* sentinel */ } 23 + }; 24 + MODULE_DEVICE_TABLE(i3c, inv_icm45600_i3c_ids); 25 + 26 + static const struct inv_icm45600_chip_info *i3c_chip_info[] = { 27 + &inv_icm45605_chip_info, 28 + &inv_icm45606_chip_info, 29 + &inv_icm45608_chip_info, 30 + &inv_icm45634_chip_info, 31 + &inv_icm45686_chip_info, 32 + &inv_icm45687_chip_info, 33 + &inv_icm45688p_chip_info, 34 + &inv_icm45689_chip_info, 35 + }; 36 + 37 + static int inv_icm45600_i3c_probe(struct i3c_device *i3cdev) 38 + { 39 + int ret; 40 + unsigned int whoami; 41 + struct regmap *regmap; 42 + const int nb_chip = ARRAY_SIZE(i3c_chip_info); 43 + int chip; 44 + 45 + regmap = devm_regmap_init_i3c(i3cdev, &inv_icm45600_regmap_config); 46 + if (IS_ERR(regmap)) 47 + return dev_err_probe(&i3cdev->dev, PTR_ERR(regmap), 48 + "Failed to register i3c regmap %ld\n", PTR_ERR(regmap)); 49 + 50 + ret = regmap_read(regmap, INV_ICM45600_REG_WHOAMI, &whoami); 51 + if (ret) 52 + return dev_err_probe(&i3cdev->dev, ret, "Failed to read part id %d\n", whoami); 53 + 54 + for (chip = 0; chip < nb_chip; chip++) { 55 + if (whoami == i3c_chip_info[chip]->whoami) 56 + break; 57 + } 58 + 59 + if (chip == nb_chip) 60 + return dev_err_probe(&i3cdev->dev, -ENODEV, 61 + "Failed to match part id %d\n", whoami); 62 + 63 + return inv_icm45600_core_probe(regmap, i3c_chip_info[chip], false, NULL); 64 + } 65 + 66 + static struct i3c_driver inv_icm45600_driver = { 67 + .driver = { 68 + .name = "inv_icm45600_i3c", 69 + .pm = pm_sleep_ptr(&inv_icm45600_pm_ops), 70 + }, 71 + .probe = inv_icm45600_i3c_probe, 72 + .id_table = inv_icm45600_i3c_ids, 73 + }; 74 + module_i3c_driver(inv_icm45600_driver); 75 + 76 + MODULE_AUTHOR("Remi Buisson <remi.buisson@tdk.com>"); 77 + MODULE_DESCRIPTION("InvenSense ICM-456xx i3c driver"); 78 + MODULE_LICENSE("GPL"); 79 + MODULE_IMPORT_NS("IIO_ICM45600");
+108
drivers/iio/imu/inv_icm45600/inv_icm45600_spi.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* Copyright (C) 2025 InvenSense, Inc. */ 3 + 4 + #include <linux/bitfield.h> 5 + #include <linux/device.h> 6 + #include <linux/err.h> 7 + #include <linux/module.h> 8 + #include <linux/mod_devicetable.h> 9 + #include <linux/regmap.h> 10 + 11 + #include <linux/spi/spi.h> 12 + 13 + #include "inv_icm45600.h" 14 + 15 + static const struct regmap_config inv_icm45600_regmap_config = { 16 + .reg_bits = 8, 17 + .val_bits = 8, 18 + }; 19 + 20 + static int inv_icm45600_spi_bus_setup(struct inv_icm45600_state *st) 21 + { 22 + /* Set slew rates for SPI. */ 23 + return regmap_update_bits(st->map, INV_ICM45600_REG_DRIVE_CONFIG0, 24 + INV_ICM45600_DRIVE_CONFIG0_SPI_MASK, 25 + FIELD_PREP(INV_ICM45600_DRIVE_CONFIG0_SPI_MASK, 26 + INV_ICM45600_SPI_SLEW_RATE_5NS)); 27 + } 28 + 29 + static int inv_icm45600_probe(struct spi_device *spi) 30 + { 31 + const struct inv_icm45600_chip_info *chip_info; 32 + struct regmap *regmap; 33 + 34 + chip_info = spi_get_device_match_data(spi); 35 + if (!chip_info) 36 + return -ENODEV; 37 + 38 + /* Use SPI specific regmap. */ 39 + regmap = devm_regmap_init_spi(spi, &inv_icm45600_regmap_config); 40 + if (IS_ERR(regmap)) 41 + return PTR_ERR(regmap); 42 + 43 + return inv_icm45600_core_probe(regmap, chip_info, true, 44 + inv_icm45600_spi_bus_setup); 45 + } 46 + 47 + /* 48 + * The device id table is used to identify which device is 49 + * supported by this driver. 50 + */ 51 + static const struct spi_device_id inv_icm45600_id[] = { 52 + { "icm45605", (kernel_ulong_t)&inv_icm45605_chip_info }, 53 + { "icm45606", (kernel_ulong_t)&inv_icm45606_chip_info }, 54 + { "icm45608", (kernel_ulong_t)&inv_icm45608_chip_info }, 55 + { "icm45634", (kernel_ulong_t)&inv_icm45634_chip_info }, 56 + { "icm45686", (kernel_ulong_t)&inv_icm45686_chip_info }, 57 + { "icm45687", (kernel_ulong_t)&inv_icm45687_chip_info }, 58 + { "icm45688p", (kernel_ulong_t)&inv_icm45688p_chip_info }, 59 + { "icm45689", (kernel_ulong_t)&inv_icm45689_chip_info }, 60 + { } 61 + }; 62 + MODULE_DEVICE_TABLE(spi, inv_icm45600_id); 63 + 64 + static const struct of_device_id inv_icm45600_of_matches[] = { 65 + { 66 + .compatible = "invensense,icm45605", 67 + .data = &inv_icm45605_chip_info, 68 + }, { 69 + .compatible = "invensense,icm45606", 70 + .data = &inv_icm45606_chip_info, 71 + }, { 72 + .compatible = "invensense,icm45608", 73 + .data = &inv_icm45608_chip_info, 74 + }, { 75 + .compatible = "invensense,icm45634", 76 + .data = &inv_icm45634_chip_info, 77 + }, { 78 + .compatible = "invensense,icm45686", 79 + .data = &inv_icm45686_chip_info, 80 + }, { 81 + .compatible = "invensense,icm45687", 82 + .data = &inv_icm45687_chip_info, 83 + }, { 84 + .compatible = "invensense,icm45688p", 85 + .data = &inv_icm45688p_chip_info, 86 + }, { 87 + .compatible = "invensense,icm45689", 88 + .data = &inv_icm45689_chip_info, 89 + }, 90 + { } 91 + }; 92 + MODULE_DEVICE_TABLE(of, inv_icm45600_of_matches); 93 + 94 + static struct spi_driver inv_icm45600_driver = { 95 + .driver = { 96 + .name = "inv-icm45600-spi", 97 + .of_match_table = inv_icm45600_of_matches, 98 + .pm = pm_ptr(&inv_icm45600_pm_ops), 99 + }, 100 + .id_table = inv_icm45600_id, 101 + .probe = inv_icm45600_probe, 102 + }; 103 + module_spi_driver(inv_icm45600_driver); 104 + 105 + MODULE_AUTHOR("InvenSense, Inc."); 106 + MODULE_DESCRIPTION("InvenSense ICM-456xx SPI driver"); 107 + MODULE_LICENSE("GPL"); 108 + MODULE_IMPORT_NS("IIO_ICM45600");
+33
drivers/iio/imu/smi330/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # 3 + # SMI330 IMU driver 4 + # 5 + 6 + config SMI330 7 + tristate 8 + select IIO_BUFFER 9 + select IIO_TRIGGERED_BUFFER 10 + 11 + config SMI330_I2C 12 + tristate "Bosch SMI330 I2C driver" 13 + depends on I2C 14 + select SMI330 15 + select REGMAP_I2C 16 + help 17 + Enable support for the Bosch SMI330 6-Axis IMU connected to I2C 18 + interface. 19 + 20 + This driver can also be built as a module. If so, the module will be 21 + called smi330_i2c. 22 + 23 + config SMI330_SPI 24 + tristate "Bosch SMI330 SPI driver" 25 + depends on SPI 26 + select SMI330 27 + select REGMAP_SPI 28 + help 29 + Enable support for the Bosch SMI330 6-Axis IMU connected to SPI 30 + interface. 31 + 32 + This driver can also be built as a module. If so, the module will be 33 + called smi330_spi.
+7
drivers/iio/imu/smi330/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + # 3 + # Makefile for Bosch SMI330 IMU 4 + # 5 + obj-$(CONFIG_SMI330) += smi330_core.o 6 + obj-$(CONFIG_SMI330_I2C) += smi330_i2c.o 7 + obj-$(CONFIG_SMI330_SPI) += smi330_spi.o
+25
drivers/iio/imu/smi330/smi330.h
··· 1 + /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ 2 + /* 3 + * Copyright (c) 2025 Robert Bosch GmbH. 4 + */ 5 + #ifndef _SMI330_H 6 + #define _SMI330_H 7 + 8 + #include <linux/iio/iio.h> 9 + 10 + enum { 11 + SMI330_SCAN_ACCEL_X, 12 + SMI330_SCAN_ACCEL_Y, 13 + SMI330_SCAN_ACCEL_Z, 14 + SMI330_SCAN_GYRO_X, 15 + SMI330_SCAN_GYRO_Y, 16 + SMI330_SCAN_GYRO_Z, 17 + SMI330_SCAN_TIMESTAMP, 18 + SMI330_SCAN_LEN = SMI330_SCAN_TIMESTAMP, 19 + }; 20 + 21 + extern const struct regmap_config smi330_regmap_config; 22 + 23 + int smi330_core_probe(struct device *dev, struct regmap *regmap); 24 + 25 + #endif /* _SMI330_H */
+918
drivers/iio/imu/smi330/smi330_core.c
··· 1 + // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 + /* 3 + * Copyright (c) 2025 Robert Bosch GmbH. 4 + */ 5 + #include <linux/bitfield.h> 6 + #include <linux/delay.h> 7 + #include <linux/interrupt.h> 8 + #include <linux/irq.h> 9 + #include <linux/module.h> 10 + #include <linux/property.h> 11 + #include <linux/regmap.h> 12 + #include <linux/string.h> 13 + #include <linux/units.h> 14 + 15 + #include <linux/iio/buffer.h> 16 + #include <linux/iio/iio.h> 17 + #include <linux/iio/trigger.h> 18 + #include <linux/iio/trigger_consumer.h> 19 + #include <linux/iio/triggered_buffer.h> 20 + 21 + #include "smi330.h" 22 + 23 + /* Register map */ 24 + #define SMI330_CHIP_ID_REG 0x00 25 + #define SMI330_ERR_REG 0x01 26 + #define SMI330_STATUS_REG 0x02 27 + #define SMI330_ACCEL_X_REG 0x03 28 + #define SMI330_GYRO_X_REG 0x06 29 + #define SMI330_TEMP_REG 0x09 30 + #define SMI330_INT1_STATUS_REG 0x0D 31 + #define SMI330_ACCEL_CFG_REG 0x20 32 + #define SMI330_GYRO_CFG_REG 0x21 33 + #define SMI330_IO_INT_CTRL_REG 0x38 34 + #define SMI330_INT_CONF_REG 0x39 35 + #define SMI330_INT_MAP1_REG 0x3A 36 + #define SMI330_INT_MAP2_REG 0x3B 37 + #define SMI330_CMD_REG 0x7E 38 + 39 + /* Register mask */ 40 + #define SMI330_CHIP_ID_MASK GENMASK(7, 0) 41 + #define SMI330_ERR_FATAL_MASK BIT(0) 42 + #define SMI330_ERR_ACC_CONF_MASK BIT(5) 43 + #define SMI330_ERR_GYR_CONF_MASK BIT(6) 44 + #define SMI330_STATUS_POR_MASK BIT(0) 45 + #define SMI330_INT_STATUS_ACC_GYR_DRDY_MASK GENMASK(13, 12) 46 + #define SMI330_CFG_ODR_MASK GENMASK(3, 0) 47 + #define SMI330_CFG_RANGE_MASK GENMASK(6, 4) 48 + #define SMI330_CFG_BW_MASK BIT(7) 49 + #define SMI330_CFG_AVG_NUM_MASK GENMASK(10, 8) 50 + #define SMI330_CFG_MODE_MASK GENMASK(14, 12) 51 + #define SMI330_IO_INT_CTRL_INT1_MASK GENMASK(2, 0) 52 + #define SMI330_IO_INT_CTRL_INT2_MASK GENMASK(10, 8) 53 + #define SMI330_INT_CONF_LATCH_MASK BIT(0) 54 + #define SMI330_INT_MAP2_ACC_DRDY_MASK GENMASK(11, 10) 55 + #define SMI330_INT_MAP2_GYR_DRDY_MASK GENMASK(9, 8) 56 + 57 + /* Register values */ 58 + #define SMI330_IO_INT_CTRL_LVL BIT(0) 59 + #define SMI330_IO_INT_CTRL_OD BIT(1) 60 + #define SMI330_IO_INT_CTRL_EN BIT(2) 61 + #define SMI330_CMD_SOFT_RESET 0xDEAF 62 + 63 + /* T°C = (temp / 512) + 23 */ 64 + #define SMI330_TEMP_OFFSET 11776 /* 23 * 512 */ 65 + #define SMI330_TEMP_SCALE 1953125 /* (1 / 512) * 1e9 */ 66 + 67 + #define SMI330_CHIP_ID 0x42 68 + #define SMI330_SOFT_RESET_DELAY 2000 69 + 70 + /* Non-constant mask variant of FIELD_GET() and FIELD_PREP() */ 71 + #define smi330_field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1)) 72 + #define smi330_field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask)) 73 + 74 + #define SMI330_ACCEL_CHANNEL(_axis) { \ 75 + .type = IIO_ACCEL, \ 76 + .modified = 1, \ 77 + .channel2 = IIO_MOD_##_axis, \ 78 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 79 + .info_mask_shared_by_type = \ 80 + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ 81 + BIT(IIO_CHAN_INFO_SCALE) | \ 82 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | \ 83 + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ 84 + .info_mask_shared_by_type_available = \ 85 + BIT(IIO_CHAN_INFO_SCALE) | \ 86 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | \ 87 + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ 88 + .info_mask_shared_by_dir_available = \ 89 + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 90 + .scan_index = SMI330_SCAN_ACCEL_##_axis, \ 91 + .scan_type = { \ 92 + .sign = 's', \ 93 + .realbits = 16, \ 94 + .storagebits = 16, \ 95 + .endianness = IIO_LE, \ 96 + }, \ 97 + } 98 + 99 + #define SMI330_GYRO_CHANNEL(_axis) { \ 100 + .type = IIO_ANGL_VEL, \ 101 + .modified = 1, \ 102 + .channel2 = IIO_MOD_##_axis, \ 103 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 104 + .info_mask_shared_by_type = \ 105 + BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ 106 + BIT(IIO_CHAN_INFO_SCALE) | \ 107 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | \ 108 + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ 109 + .info_mask_shared_by_type_available = \ 110 + BIT(IIO_CHAN_INFO_SCALE) | \ 111 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | \ 112 + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ 113 + .info_mask_shared_by_dir_available = \ 114 + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 115 + .scan_index = SMI330_SCAN_GYRO_##_axis, \ 116 + .scan_type = { \ 117 + .sign = 's', \ 118 + .realbits = 16, \ 119 + .storagebits = 16, \ 120 + .endianness = IIO_LE, \ 121 + }, \ 122 + } 123 + 124 + #define SMI330_TEMP_CHANNEL(_index) { \ 125 + .type = IIO_TEMP, \ 126 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 127 + BIT(IIO_CHAN_INFO_OFFSET) | \ 128 + BIT(IIO_CHAN_INFO_SCALE), \ 129 + .scan_index = _index, \ 130 + .scan_type = { \ 131 + .sign = 's', \ 132 + .realbits = 16, \ 133 + .storagebits = 16, \ 134 + .endianness = IIO_LE, \ 135 + }, \ 136 + } 137 + 138 + enum smi330_accel_range { 139 + SMI330_ACCEL_RANGE_2G = 0x00, 140 + SMI330_ACCEL_RANGE_4G = 0x01, 141 + SMI330_ACCEL_RANGE_8G = 0x02, 142 + SMI330_ACCEL_RANGE_16G = 0x03 143 + }; 144 + 145 + enum smi330_gyro_range { 146 + SMI330_GYRO_RANGE_125 = 0x0, 147 + SMI330_GYRO_RANGE_250 = 0x01, 148 + SMI330_GYRO_RANGE_500 = 0x02 149 + }; 150 + 151 + enum smi330_odr { 152 + SMI330_ODR_12_5_HZ = 0x05, 153 + SMI330_ODR_25_HZ = 0x06, 154 + SMI330_ODR_50_HZ = 0x07, 155 + SMI330_ODR_100_HZ = 0x08, 156 + SMI330_ODR_200_HZ = 0x09, 157 + SMI330_ODR_400_HZ = 0x0A, 158 + SMI330_ODR_800_HZ = 0x0B, 159 + SMI330_ODR_1600_HZ = 0x0C, 160 + SMI330_ODR_3200_HZ = 0x0D, 161 + SMI330_ODR_6400_HZ = 0x0E 162 + }; 163 + 164 + enum smi330_avg_num { 165 + SMI330_AVG_NUM_1 = 0x00, 166 + SMI330_AVG_NUM_2 = 0x01, 167 + SMI330_AVG_NUM_4 = 0x02, 168 + SMI330_AVG_NUM_8 = 0x03, 169 + SMI330_AVG_NUM_16 = 0x04, 170 + SMI330_AVG_NUM_32 = 0x05, 171 + SMI330_AVG_NUM_64 = 0x06 172 + }; 173 + 174 + enum smi330_mode { 175 + SMI330_MODE_SUSPEND = 0x00, 176 + SMI330_MODE_GYRO_DRIVE = 0x01, 177 + SMI330_MODE_LOW_POWER = 0x03, 178 + SMI330_MODE_NORMAL = 0x04, 179 + SMI330_MODE_HIGH_PERF = 0x07 180 + }; 181 + 182 + enum smi330_bw { 183 + SMI330_BW_2 = 0x00, /* ODR/2 */ 184 + SMI330_BW_4 = 0x01 /* ODR/4 */ 185 + }; 186 + 187 + enum smi330_operation_mode { 188 + SMI330_POLLING, 189 + SMI330_DATA_READY, 190 + }; 191 + 192 + enum smi330_sensor { 193 + SMI330_ACCEL, 194 + SMI330_GYRO, 195 + }; 196 + 197 + enum smi330_sensor_conf_select { 198 + SMI330_ODR, 199 + SMI330_RANGE, 200 + SMI330_BW, 201 + SMI330_AVG_NUM, 202 + }; 203 + 204 + enum smi330_int_out { 205 + SMI330_INT_DISABLED, 206 + SMI330_INT_1, 207 + SMI330_INT_2, 208 + }; 209 + 210 + struct smi330_attributes { 211 + int *reg_vals; 212 + int *vals; 213 + int len; 214 + int type; 215 + int mask; 216 + }; 217 + 218 + struct smi330_cfg { 219 + enum smi330_operation_mode op_mode; 220 + enum smi330_int_out data_irq; 221 + }; 222 + 223 + struct smi330_data { 224 + struct regmap *regmap; 225 + struct smi330_cfg cfg; 226 + struct iio_trigger *trig; 227 + IIO_DECLARE_BUFFER_WITH_TS(__le16, buf, SMI330_SCAN_LEN); 228 + }; 229 + 230 + const struct regmap_config smi330_regmap_config = { 231 + .reg_bits = 8, 232 + .val_bits = 16, 233 + .val_format_endian = REGMAP_ENDIAN_LITTLE, 234 + }; 235 + EXPORT_SYMBOL_NS_GPL(smi330_regmap_config, "IIO_SMI330"); 236 + 237 + static const struct iio_chan_spec smi330_channels[] = { 238 + SMI330_ACCEL_CHANNEL(X), 239 + SMI330_ACCEL_CHANNEL(Y), 240 + SMI330_ACCEL_CHANNEL(Z), 241 + SMI330_GYRO_CHANNEL(X), 242 + SMI330_GYRO_CHANNEL(Y), 243 + SMI330_GYRO_CHANNEL(Z), 244 + SMI330_TEMP_CHANNEL(-1), /* No buffer support */ 245 + IIO_CHAN_SOFT_TIMESTAMP(SMI330_SCAN_TIMESTAMP), 246 + }; 247 + 248 + static const unsigned long smi330_avail_scan_masks[] = { 249 + (BIT(SMI330_SCAN_ACCEL_X) | BIT(SMI330_SCAN_ACCEL_Y) | 250 + BIT(SMI330_SCAN_ACCEL_Z) | BIT(SMI330_SCAN_GYRO_X) | 251 + BIT(SMI330_SCAN_GYRO_Y) | BIT(SMI330_SCAN_GYRO_Z)), 252 + 0 253 + }; 254 + 255 + static const struct smi330_attributes smi330_accel_scale_attr = { 256 + .reg_vals = (int[]){ SMI330_ACCEL_RANGE_2G, SMI330_ACCEL_RANGE_4G, 257 + SMI330_ACCEL_RANGE_8G, SMI330_ACCEL_RANGE_16G }, 258 + .vals = (int[]){ 0, 61035, 0, 122070, 0, 244140, 0, 488281 }, 259 + .len = 8, 260 + .type = IIO_VAL_INT_PLUS_NANO, 261 + .mask = SMI330_CFG_RANGE_MASK 262 + }; 263 + 264 + static const struct smi330_attributes smi330_gyro_scale_attr = { 265 + .reg_vals = (int[]){ SMI330_GYRO_RANGE_125, SMI330_GYRO_RANGE_250, 266 + SMI330_GYRO_RANGE_500 }, 267 + .vals = (int[]){ 0, 3814697, 0, 7629395, 0, 15258789 }, 268 + .len = 6, 269 + .type = IIO_VAL_INT_PLUS_NANO, 270 + .mask = SMI330_CFG_RANGE_MASK 271 + }; 272 + 273 + static const struct smi330_attributes smi330_average_attr = { 274 + .reg_vals = (int[]){ SMI330_AVG_NUM_1, SMI330_AVG_NUM_2, 275 + SMI330_AVG_NUM_4, SMI330_AVG_NUM_8, 276 + SMI330_AVG_NUM_16, SMI330_AVG_NUM_32, 277 + SMI330_AVG_NUM_64 }, 278 + .vals = (int[]){ 1, 2, 4, 8, 16, 32, 64 }, 279 + .len = 7, 280 + .type = IIO_VAL_INT, 281 + .mask = SMI330_CFG_AVG_NUM_MASK 282 + }; 283 + 284 + static const struct smi330_attributes smi330_bandwidth_attr = { 285 + .reg_vals = (int[]){ SMI330_BW_2, SMI330_BW_4 }, 286 + .vals = (int[]){ 2, 4 }, 287 + .len = 2, 288 + .type = IIO_VAL_INT, 289 + .mask = SMI330_CFG_BW_MASK 290 + }; 291 + 292 + static const struct smi330_attributes smi330_odr_attr = { 293 + .reg_vals = (int[]){ SMI330_ODR_12_5_HZ, SMI330_ODR_25_HZ, 294 + SMI330_ODR_50_HZ, SMI330_ODR_100_HZ, 295 + SMI330_ODR_200_HZ, SMI330_ODR_400_HZ, 296 + SMI330_ODR_800_HZ, SMI330_ODR_1600_HZ, 297 + SMI330_ODR_3200_HZ, SMI330_ODR_6400_HZ }, 298 + .vals = (int[]){ 12, 25, 50, 100, 200, 400, 800, 1600, 3200, 6400 }, 299 + .len = 10, 300 + .type = IIO_VAL_INT, 301 + .mask = SMI330_CFG_ODR_MASK 302 + }; 303 + 304 + static int smi330_get_attributes(enum smi330_sensor_conf_select config, 305 + enum smi330_sensor sensor, 306 + const struct smi330_attributes **attr) 307 + { 308 + switch (config) { 309 + case SMI330_ODR: 310 + *attr = &smi330_odr_attr; 311 + return 0; 312 + case SMI330_RANGE: 313 + if (sensor == SMI330_ACCEL) 314 + *attr = &smi330_accel_scale_attr; 315 + else 316 + *attr = &smi330_gyro_scale_attr; 317 + return 0; 318 + case SMI330_BW: 319 + *attr = &smi330_bandwidth_attr; 320 + return 0; 321 + case SMI330_AVG_NUM: 322 + *attr = &smi330_average_attr; 323 + return 0; 324 + default: 325 + return -EINVAL; 326 + } 327 + } 328 + 329 + static int smi330_get_config_reg(enum smi330_sensor sensor, int *reg) 330 + { 331 + switch (sensor) { 332 + case SMI330_ACCEL: 333 + *reg = SMI330_ACCEL_CFG_REG; 334 + return 0; 335 + case SMI330_GYRO: 336 + *reg = SMI330_GYRO_CFG_REG; 337 + return 0; 338 + default: 339 + return -EINVAL; 340 + } 341 + } 342 + 343 + static int smi330_get_sensor_config(struct smi330_data *data, 344 + enum smi330_sensor sensor, 345 + enum smi330_sensor_conf_select config, 346 + int *value) 347 + 348 + { 349 + int ret, reg, reg_val, i; 350 + const struct smi330_attributes *attr; 351 + 352 + ret = smi330_get_config_reg(sensor, &reg); 353 + if (ret) 354 + return ret; 355 + 356 + ret = regmap_read(data->regmap, reg, &reg_val); 357 + if (ret) 358 + return ret; 359 + 360 + ret = smi330_get_attributes(config, sensor, &attr); 361 + if (ret) 362 + return ret; 363 + 364 + reg_val = smi330_field_get(attr->mask, reg_val); 365 + 366 + if (attr->type == IIO_VAL_INT) { 367 + for (i = 0; i < attr->len; i++) { 368 + if (attr->reg_vals[i] == reg_val) { 369 + *value = attr->vals[i]; 370 + return 0; 371 + } 372 + } 373 + } else { 374 + for (i = 0; i < attr->len / 2; i++) { 375 + if (attr->reg_vals[i] == reg_val) { 376 + *value = attr->vals[2 * i + 1]; 377 + return 0; 378 + } 379 + } 380 + } 381 + 382 + return -EINVAL; 383 + } 384 + 385 + static int smi330_set_sensor_config(struct smi330_data *data, 386 + enum smi330_sensor sensor, 387 + enum smi330_sensor_conf_select config, 388 + int value) 389 + { 390 + int ret, i, reg, reg_val, error; 391 + const struct smi330_attributes *attr; 392 + 393 + ret = smi330_get_attributes(config, sensor, &attr); 394 + if (ret) 395 + return ret; 396 + 397 + for (i = 0; i < attr->len; i++) { 398 + if (attr->vals[i] == value) { 399 + if (attr->type == IIO_VAL_INT) 400 + reg_val = attr->reg_vals[i]; 401 + else 402 + reg_val = attr->reg_vals[i / 2]; 403 + break; 404 + } 405 + } 406 + if (i == attr->len) 407 + return -EINVAL; 408 + 409 + ret = smi330_get_config_reg(sensor, &reg); 410 + if (ret) 411 + return ret; 412 + 413 + reg_val = smi330_field_prep(attr->mask, reg_val); 414 + ret = regmap_update_bits(data->regmap, reg, attr->mask, reg_val); 415 + if (ret) 416 + return ret; 417 + 418 + ret = regmap_read(data->regmap, SMI330_ERR_REG, &error); 419 + if (ret) 420 + return ret; 421 + 422 + if (FIELD_GET(SMI330_ERR_ACC_CONF_MASK, error) || 423 + FIELD_GET(SMI330_ERR_GYR_CONF_MASK, error)) 424 + return -EIO; 425 + 426 + return 0; 427 + } 428 + 429 + static int smi330_get_data(struct smi330_data *data, int chan_type, int axis, 430 + int *val) 431 + { 432 + u8 reg; 433 + int ret, sample; 434 + 435 + switch (chan_type) { 436 + case IIO_ACCEL: 437 + reg = SMI330_ACCEL_X_REG + (axis - IIO_MOD_X); 438 + break; 439 + case IIO_ANGL_VEL: 440 + reg = SMI330_GYRO_X_REG + (axis - IIO_MOD_X); 441 + break; 442 + case IIO_TEMP: 443 + reg = SMI330_TEMP_REG; 444 + break; 445 + default: 446 + return -EINVAL; 447 + } 448 + 449 + ret = regmap_read(data->regmap, reg, &sample); 450 + if (ret) 451 + return ret; 452 + 453 + *val = sign_extend32(sample, 15); 454 + 455 + return 0; 456 + } 457 + 458 + static int smi330_read_avail(struct iio_dev *indio_dev, 459 + struct iio_chan_spec const *chan, const int **vals, 460 + int *type, int *length, long mask) 461 + { 462 + switch (mask) { 463 + case IIO_CHAN_INFO_SCALE: 464 + if (chan->type == IIO_ACCEL) { 465 + *vals = smi330_accel_scale_attr.vals; 466 + *length = smi330_accel_scale_attr.len; 467 + *type = smi330_accel_scale_attr.type; 468 + } else { 469 + *vals = smi330_gyro_scale_attr.vals; 470 + *length = smi330_gyro_scale_attr.len; 471 + *type = smi330_gyro_scale_attr.type; 472 + } 473 + return IIO_AVAIL_LIST; 474 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 475 + *vals = smi330_average_attr.vals; 476 + *length = smi330_average_attr.len; 477 + *type = smi330_average_attr.type; 478 + *type = IIO_VAL_INT; 479 + return IIO_AVAIL_LIST; 480 + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 481 + *vals = smi330_bandwidth_attr.vals; 482 + *length = smi330_bandwidth_attr.len; 483 + *type = smi330_bandwidth_attr.type; 484 + return IIO_AVAIL_LIST; 485 + case IIO_CHAN_INFO_SAMP_FREQ: 486 + *vals = smi330_odr_attr.vals; 487 + *length = smi330_odr_attr.len; 488 + *type = smi330_odr_attr.type; 489 + return IIO_AVAIL_LIST; 490 + default: 491 + return -EINVAL; 492 + } 493 + } 494 + 495 + static int smi330_read_raw(struct iio_dev *indio_dev, 496 + struct iio_chan_spec const *chan, int *val, 497 + int *val2, long mask) 498 + { 499 + int ret; 500 + struct smi330_data *data = iio_priv(indio_dev); 501 + enum smi330_sensor sensor; 502 + 503 + /* valid for all channel types */ 504 + switch (mask) { 505 + case IIO_CHAN_INFO_RAW: 506 + if (!iio_device_claim_direct(indio_dev)) 507 + return -EBUSY; 508 + ret = smi330_get_data(data, chan->type, chan->channel2, val); 509 + iio_device_release_direct(indio_dev); 510 + return ret ? ret : IIO_VAL_INT; 511 + default: 512 + break; 513 + } 514 + 515 + switch (chan->type) { 516 + case IIO_ACCEL: 517 + sensor = SMI330_ACCEL; 518 + break; 519 + case IIO_ANGL_VEL: 520 + sensor = SMI330_GYRO; 521 + break; 522 + case IIO_TEMP: 523 + switch (mask) { 524 + case IIO_CHAN_INFO_SCALE: 525 + *val = SMI330_TEMP_SCALE / GIGA; 526 + *val2 = SMI330_TEMP_SCALE % GIGA; 527 + return IIO_VAL_INT_PLUS_NANO; 528 + case IIO_CHAN_INFO_OFFSET: 529 + *val = SMI330_TEMP_OFFSET; 530 + return IIO_VAL_INT; 531 + default: 532 + return -EINVAL; 533 + } 534 + default: 535 + return -EINVAL; 536 + } 537 + 538 + /* valid for acc and gyro channels */ 539 + switch (mask) { 540 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 541 + ret = smi330_get_sensor_config(data, sensor, SMI330_AVG_NUM, 542 + val); 543 + return ret ? ret : IIO_VAL_INT; 544 + 545 + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 546 + ret = smi330_get_sensor_config(data, sensor, SMI330_BW, val); 547 + return ret ? ret : IIO_VAL_INT; 548 + 549 + case IIO_CHAN_INFO_SAMP_FREQ: 550 + ret = smi330_get_sensor_config(data, sensor, SMI330_ODR, val); 551 + return ret ? ret : IIO_VAL_INT; 552 + 553 + case IIO_CHAN_INFO_SCALE: 554 + *val = 0; 555 + ret = smi330_get_sensor_config(data, sensor, SMI330_RANGE, 556 + val2); 557 + return ret ? ret : IIO_VAL_INT_PLUS_NANO; 558 + 559 + default: 560 + return -EINVAL; 561 + } 562 + } 563 + 564 + static int smi330_write_raw(struct iio_dev *indio_dev, 565 + struct iio_chan_spec const *chan, int val, int val2, 566 + long mask) 567 + { 568 + struct smi330_data *data = iio_priv(indio_dev); 569 + enum smi330_sensor sensor; 570 + 571 + switch (chan->type) { 572 + case IIO_ACCEL: 573 + sensor = SMI330_ACCEL; 574 + break; 575 + case IIO_ANGL_VEL: 576 + sensor = SMI330_GYRO; 577 + break; 578 + default: 579 + return -EINVAL; 580 + } 581 + 582 + switch (mask) { 583 + case IIO_CHAN_INFO_SCALE: 584 + return smi330_set_sensor_config(data, sensor, SMI330_RANGE, 585 + val2); 586 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 587 + return smi330_set_sensor_config(data, sensor, SMI330_AVG_NUM, 588 + val); 589 + case IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY: 590 + return smi330_set_sensor_config(data, sensor, SMI330_BW, val); 591 + case IIO_CHAN_INFO_SAMP_FREQ: 592 + return smi330_set_sensor_config(data, sensor, SMI330_ODR, val); 593 + default: 594 + return -EINVAL; 595 + } 596 + } 597 + 598 + static int smi330_write_raw_get_fmt(struct iio_dev *indio_dev, 599 + struct iio_chan_spec const *chan, long info) 600 + { 601 + switch (info) { 602 + case IIO_CHAN_INFO_SCALE: 603 + return IIO_VAL_INT_PLUS_NANO; 604 + default: 605 + return IIO_VAL_INT_PLUS_MICRO; 606 + } 607 + } 608 + 609 + static int smi330_soft_reset(struct smi330_data *data) 610 + { 611 + int ret, dummy_byte; 612 + 613 + ret = regmap_write(data->regmap, SMI330_CMD_REG, SMI330_CMD_SOFT_RESET); 614 + if (ret) 615 + return ret; 616 + fsleep(SMI330_SOFT_RESET_DELAY); 617 + 618 + /* Performing a dummy read after a soft-reset */ 619 + regmap_read(data->regmap, SMI330_CHIP_ID_REG, &dummy_byte); 620 + 621 + return 0; 622 + } 623 + 624 + static irqreturn_t smi330_trigger_handler(int irq, void *p) 625 + { 626 + int ret; 627 + struct iio_poll_func *pf = p; 628 + struct iio_dev *indio_dev = pf->indio_dev; 629 + struct smi330_data *data = iio_priv(indio_dev); 630 + 631 + ret = regmap_bulk_read(data->regmap, SMI330_ACCEL_X_REG, data->buf, 632 + SMI330_SCAN_LEN); 633 + if (ret) 634 + goto out; 635 + 636 + iio_push_to_buffers_with_timestamp(indio_dev, data->buf, pf->timestamp); 637 + 638 + out: 639 + iio_trigger_notify_done(indio_dev->trig); 640 + 641 + return IRQ_HANDLED; 642 + } 643 + 644 + static irqreturn_t smi330_irq_thread_handler(int irq, void *indio_dev_) 645 + { 646 + int ret, int_stat; 647 + s16 int_status[2] = { 0 }; 648 + struct iio_dev *indio_dev = indio_dev_; 649 + struct smi330_data *data = iio_priv(indio_dev); 650 + 651 + ret = regmap_bulk_read(data->regmap, SMI330_INT1_STATUS_REG, int_status, 2); 652 + if (ret) 653 + return IRQ_NONE; 654 + 655 + int_stat = int_status[0] | int_status[1]; 656 + 657 + if (FIELD_GET(SMI330_INT_STATUS_ACC_GYR_DRDY_MASK, int_stat)) { 658 + indio_dev->pollfunc->timestamp = iio_get_time_ns(indio_dev); 659 + iio_trigger_poll_nested(data->trig); 660 + } 661 + 662 + return IRQ_HANDLED; 663 + } 664 + 665 + static int smi330_set_int_pin_config(struct smi330_data *data, 666 + enum smi330_int_out irq_num, 667 + bool active_high, bool open_drain, 668 + bool latch) 669 + { 670 + int ret, val; 671 + 672 + val = active_high ? SMI330_IO_INT_CTRL_LVL : 0; 673 + val |= open_drain ? SMI330_IO_INT_CTRL_OD : 0; 674 + val |= SMI330_IO_INT_CTRL_EN; 675 + 676 + switch (irq_num) { 677 + case SMI330_INT_1: 678 + val = FIELD_PREP(SMI330_IO_INT_CTRL_INT1_MASK, val); 679 + ret = regmap_update_bits(data->regmap, SMI330_IO_INT_CTRL_REG, 680 + SMI330_IO_INT_CTRL_INT1_MASK, val); 681 + if (ret) 682 + return ret; 683 + break; 684 + case SMI330_INT_2: 685 + val = FIELD_PREP(SMI330_IO_INT_CTRL_INT2_MASK, val); 686 + ret = regmap_update_bits(data->regmap, SMI330_IO_INT_CTRL_REG, 687 + SMI330_IO_INT_CTRL_INT2_MASK, val); 688 + if (ret) 689 + return ret; 690 + break; 691 + default: 692 + return -EINVAL; 693 + } 694 + 695 + return regmap_update_bits(data->regmap, SMI330_INT_CONF_REG, 696 + SMI330_INT_CONF_LATCH_MASK, 697 + FIELD_PREP(SMI330_INT_CONF_LATCH_MASK, 698 + latch)); 699 + } 700 + 701 + static int smi330_setup_irq(struct device *dev, struct iio_dev *indio_dev, 702 + int irq, enum smi330_int_out irq_num) 703 + { 704 + int ret, irq_type; 705 + bool open_drain, active_high, latch; 706 + struct smi330_data *data = iio_priv(indio_dev); 707 + struct irq_data *desc; 708 + 709 + desc = irq_get_irq_data(irq); 710 + if (!desc) 711 + return -EINVAL; 712 + 713 + irq_type = irqd_get_trigger_type(desc); 714 + switch (irq_type) { 715 + case IRQF_TRIGGER_RISING: 716 + latch = false; 717 + active_high = true; 718 + break; 719 + case IRQF_TRIGGER_HIGH: 720 + latch = true; 721 + active_high = true; 722 + break; 723 + case IRQF_TRIGGER_FALLING: 724 + latch = false; 725 + active_high = false; 726 + break; 727 + case IRQF_TRIGGER_LOW: 728 + latch = true; 729 + active_high = false; 730 + break; 731 + default: 732 + return -EINVAL; 733 + } 734 + 735 + open_drain = device_property_read_bool(dev, "drive-open-drain"); 736 + 737 + ret = smi330_set_int_pin_config(data, irq_num, active_high, open_drain, 738 + latch); 739 + if (ret) 740 + return ret; 741 + 742 + return devm_request_threaded_irq(dev, irq, NULL, 743 + smi330_irq_thread_handler, 744 + irq_type | IRQF_ONESHOT, 745 + indio_dev->name, indio_dev); 746 + } 747 + 748 + static int smi330_register_irq(struct device *dev, struct iio_dev *indio_dev) 749 + { 750 + int ret, irq; 751 + struct smi330_data *data = iio_priv(indio_dev); 752 + struct fwnode_handle *fwnode; 753 + 754 + fwnode = dev_fwnode(dev); 755 + if (!fwnode) 756 + return -ENODEV; 757 + 758 + data->cfg.data_irq = SMI330_INT_DISABLED; 759 + 760 + irq = fwnode_irq_get_byname(fwnode, "INT1"); 761 + if (irq > 0) { 762 + ret = smi330_setup_irq(dev, indio_dev, irq, SMI330_INT_1); 763 + if (ret) 764 + return ret; 765 + data->cfg.data_irq = SMI330_INT_1; 766 + } else { 767 + irq = fwnode_irq_get_byname(fwnode, "INT2"); 768 + if (irq > 0) { 769 + ret = smi330_setup_irq(dev, indio_dev, irq, 770 + SMI330_INT_2); 771 + if (ret) 772 + return ret; 773 + data->cfg.data_irq = SMI330_INT_2; 774 + } 775 + } 776 + 777 + return 0; 778 + } 779 + 780 + static int smi330_set_drdy_trigger_state(struct iio_trigger *trig, bool enable) 781 + { 782 + int val; 783 + struct smi330_data *data = iio_trigger_get_drvdata(trig); 784 + 785 + if (enable) 786 + data->cfg.op_mode = SMI330_DATA_READY; 787 + else 788 + data->cfg.op_mode = SMI330_POLLING; 789 + 790 + val = FIELD_PREP(SMI330_INT_MAP2_ACC_DRDY_MASK, 791 + enable ? data->cfg.data_irq : 0); 792 + val |= FIELD_PREP(SMI330_INT_MAP2_GYR_DRDY_MASK, 793 + enable ? data->cfg.data_irq : 0); 794 + return regmap_update_bits(data->regmap, SMI330_INT_MAP2_REG, 795 + SMI330_INT_MAP2_ACC_DRDY_MASK | 796 + SMI330_INT_MAP2_GYR_DRDY_MASK, 797 + val); 798 + } 799 + 800 + static const struct iio_trigger_ops smi330_trigger_ops = { 801 + .set_trigger_state = &smi330_set_drdy_trigger_state, 802 + }; 803 + 804 + static struct iio_info smi330_info = { 805 + .read_avail = smi330_read_avail, 806 + .read_raw = smi330_read_raw, 807 + .write_raw = smi330_write_raw, 808 + .write_raw_get_fmt = smi330_write_raw_get_fmt, 809 + }; 810 + 811 + static int smi330_dev_init(struct smi330_data *data) 812 + { 813 + int ret, chip_id, val, mode; 814 + struct device *dev = regmap_get_device(data->regmap); 815 + 816 + ret = regmap_read(data->regmap, SMI330_CHIP_ID_REG, &chip_id); 817 + if (ret) 818 + return ret; 819 + 820 + chip_id = FIELD_GET(SMI330_CHIP_ID_MASK, chip_id); 821 + if (chip_id != SMI330_CHIP_ID) 822 + dev_info(dev, "Unknown chip id: 0x%04x\n", chip_id); 823 + 824 + ret = regmap_read(data->regmap, SMI330_ERR_REG, &val); 825 + if (ret) 826 + return ret; 827 + if (FIELD_GET(SMI330_ERR_FATAL_MASK, val)) 828 + return -ENODEV; 829 + 830 + ret = regmap_read(data->regmap, SMI330_STATUS_REG, &val); 831 + if (ret) 832 + return ret; 833 + if (FIELD_GET(SMI330_STATUS_POR_MASK, val) == 0) 834 + return -ENODEV; 835 + 836 + mode = FIELD_PREP(SMI330_CFG_MODE_MASK, SMI330_MODE_NORMAL); 837 + 838 + ret = regmap_update_bits(data->regmap, SMI330_ACCEL_CFG_REG, 839 + SMI330_CFG_MODE_MASK, mode); 840 + if (ret) 841 + return ret; 842 + 843 + return regmap_update_bits(data->regmap, SMI330_GYRO_CFG_REG, 844 + SMI330_CFG_MODE_MASK, mode); 845 + } 846 + 847 + int smi330_core_probe(struct device *dev, struct regmap *regmap) 848 + { 849 + int ret; 850 + struct iio_dev *indio_dev; 851 + struct smi330_data *data; 852 + 853 + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 854 + if (!indio_dev) 855 + return -ENOMEM; 856 + 857 + data = iio_priv(indio_dev); 858 + data->regmap = regmap; 859 + 860 + ret = smi330_soft_reset(data); 861 + if (ret) 862 + return dev_err_probe(dev, ret, "Soft reset failed\n"); 863 + 864 + indio_dev->channels = smi330_channels; 865 + indio_dev->num_channels = ARRAY_SIZE(smi330_channels); 866 + indio_dev->available_scan_masks = smi330_avail_scan_masks; 867 + indio_dev->name = "smi330"; 868 + indio_dev->modes = INDIO_DIRECT_MODE; 869 + indio_dev->info = &smi330_info; 870 + 871 + data->cfg.op_mode = SMI330_POLLING; 872 + 873 + ret = smi330_dev_init(data); 874 + if (ret) 875 + return dev_err_probe(dev, ret, "Init failed\n"); 876 + 877 + ret = smi330_register_irq(dev, indio_dev); 878 + if (ret) 879 + return dev_err_probe(dev, ret, "Register IRQ failed\n"); 880 + 881 + if (data->cfg.data_irq != SMI330_INT_DISABLED) { 882 + data->trig = devm_iio_trigger_alloc(dev, "%s-drdy-trigger", 883 + indio_dev->name); 884 + if (!data->trig) 885 + return -ENOMEM; 886 + 887 + data->trig->ops = &smi330_trigger_ops; 888 + iio_trigger_set_drvdata(data->trig, data); 889 + 890 + ret = devm_iio_trigger_register(dev, data->trig); 891 + if (ret) 892 + return dev_err_probe(dev, ret, 893 + "IIO register trigger failed\n"); 894 + 895 + /* Set default operation mode to data ready. */ 896 + indio_dev->trig = iio_trigger_get(data->trig); 897 + } 898 + 899 + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, 900 + iio_pollfunc_store_time, 901 + smi330_trigger_handler, NULL); 902 + if (ret) 903 + return dev_err_probe(dev, ret, "IIO buffer setup failed\n"); 904 + 905 + ret = devm_iio_device_register(dev, indio_dev); 906 + if (ret) 907 + return dev_err_probe(dev, ret, "Register IIO device failed\n"); 908 + 909 + return 0; 910 + } 911 + EXPORT_SYMBOL_NS_GPL(smi330_core_probe, "IIO_SMI330"); 912 + 913 + MODULE_AUTHOR("Stefan Gutmann <stefan.gutmann@de.bosch.com>"); 914 + MODULE_AUTHOR("Roman Huber <roman.huber@de.bosch.com>"); 915 + MODULE_AUTHOR("Filip Andrei <Andrei.Filip@ro.bosch.com>"); 916 + MODULE_AUTHOR("Drimbarean Avram Andrei <Avram-Andrei.Drimbarean@ro.bosch.com>"); 917 + MODULE_DESCRIPTION("Bosch SMI330 IMU driver"); 918 + MODULE_LICENSE("Dual BSD/GPL");
+133
drivers/iio/imu/smi330/smi330_i2c.c
··· 1 + // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 + /* 3 + * Copyright (c) 2025 Robert Bosch GmbH. 4 + */ 5 + #include <linux/i2c.h> 6 + #include <linux/mod_devicetable.h> 7 + #include <linux/module.h> 8 + #include <linux/regmap.h> 9 + 10 + #include "smi330.h" 11 + 12 + #define SMI330_NUM_DUMMY_BYTES 2 13 + #define SMI330_I2C_MAX_RX_BUFFER_SIZE \ 14 + (SMI330_NUM_DUMMY_BYTES + SMI330_SCAN_LEN * sizeof(s16)) 15 + 16 + struct smi330_i2c_priv { 17 + struct i2c_client *i2c; 18 + u8 rx_buffer[SMI330_I2C_MAX_RX_BUFFER_SIZE]; 19 + }; 20 + 21 + static int smi330_regmap_i2c_read(void *context, const void *reg_buf, 22 + size_t reg_size, void *val_buf, 23 + size_t val_size) 24 + { 25 + struct smi330_i2c_priv *priv = context; 26 + int ret; 27 + 28 + if (SMI330_NUM_DUMMY_BYTES + val_size > SMI330_I2C_MAX_RX_BUFFER_SIZE) 29 + return -EINVAL; 30 + 31 + /* 32 + * SMI330 I2C read frame: 33 + * <Slave address[6:0], RnW> <x, Register address[6:0]> 34 + * <Slave address[6:0], RnW> <Dummy[7:0]> <Dummy[7:0]> <Data_0[7:0]> <Data_1[15:8]>... 35 + * <Data_N[7:0]> <Data_N[15:8]> 36 + * Remark: Slave address is not considered part of the frame in the following definitions 37 + */ 38 + struct i2c_msg msgs[] = { 39 + { 40 + .addr = priv->i2c->addr, 41 + .flags = priv->i2c->flags, 42 + .len = reg_size, 43 + .buf = (u8 *)reg_buf, 44 + }, 45 + { 46 + .addr = priv->i2c->addr, 47 + .flags = priv->i2c->flags | I2C_M_RD, 48 + .len = SMI330_NUM_DUMMY_BYTES + val_size, 49 + .buf = priv->rx_buffer, 50 + }, 51 + }; 52 + 53 + ret = i2c_transfer(priv->i2c->adapter, msgs, ARRAY_SIZE(msgs)); 54 + if (ret < 0) 55 + return ret; 56 + 57 + memcpy(val_buf, priv->rx_buffer + SMI330_NUM_DUMMY_BYTES, val_size); 58 + 59 + return 0; 60 + } 61 + 62 + static int smi330_regmap_i2c_write(void *context, const void *data, 63 + size_t count) 64 + { 65 + struct smi330_i2c_priv *priv = context; 66 + u8 reg; 67 + 68 + /* 69 + * SMI330 I2C write frame: 70 + * <Slave address[6:0], RnW> <x, Register address[6:0]> <Data_0[7:0]> <Data_1[15:8]>... 71 + * <Data_N[7:0]> <Data_N[15:8]> 72 + * Remark: Slave address is not considered part of the frame in the following definitions 73 + */ 74 + reg = *(u8 *)data; 75 + return i2c_smbus_write_i2c_block_data(priv->i2c, reg, 76 + count - sizeof(u8), 77 + data + sizeof(u8)); 78 + } 79 + 80 + static const struct regmap_bus smi330_regmap_bus = { 81 + .read = smi330_regmap_i2c_read, 82 + .write = smi330_regmap_i2c_write, 83 + }; 84 + 85 + static int smi330_i2c_probe(struct i2c_client *i2c) 86 + { 87 + struct device *dev = &i2c->dev; 88 + struct smi330_i2c_priv *priv; 89 + struct regmap *regmap; 90 + 91 + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 92 + if (!priv) 93 + return -ENOMEM; 94 + 95 + priv->i2c = i2c; 96 + regmap = devm_regmap_init(dev, &smi330_regmap_bus, priv, 97 + &smi330_regmap_config); 98 + if (IS_ERR(regmap)) 99 + return dev_err_probe(dev, PTR_ERR(regmap), 100 + "Failed to initialize I2C Regmap\n"); 101 + 102 + return smi330_core_probe(dev, regmap); 103 + } 104 + 105 + static const struct i2c_device_id smi330_i2c_device_id[] = { 106 + { .name = "smi330" }, 107 + { } 108 + }; 109 + MODULE_DEVICE_TABLE(i2c, smi330_i2c_device_id); 110 + 111 + static const struct of_device_id smi330_of_match[] = { 112 + { .compatible = "bosch,smi330" }, 113 + { } 114 + }; 115 + MODULE_DEVICE_TABLE(of, smi330_of_match); 116 + 117 + static struct i2c_driver smi330_i2c_driver = { 118 + .probe = smi330_i2c_probe, 119 + .id_table = smi330_i2c_device_id, 120 + .driver = { 121 + .of_match_table = smi330_of_match, 122 + .name = "smi330_i2c", 123 + }, 124 + }; 125 + module_i2c_driver(smi330_i2c_driver); 126 + 127 + MODULE_AUTHOR("Stefan Gutmann <stefan.gutmann@de.bosch.com>"); 128 + MODULE_AUTHOR("Roman Huber <roman.huber@de.bosch.com>"); 129 + MODULE_AUTHOR("Filip Andrei <Andrei.Filip@ro.bosch.com>"); 130 + MODULE_AUTHOR("Drimbarean Avram Andrei <Avram-Andrei.Drimbarean@ro.bosch.com>"); 131 + MODULE_DESCRIPTION("Bosch SMI330 I2C driver"); 132 + MODULE_LICENSE("Dual BSD/GPL"); 133 + MODULE_IMPORT_NS("IIO_SMI330");
+85
drivers/iio/imu/smi330/smi330_spi.c
··· 1 + // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 2 + /* 3 + * Copyright (c) 2025 Robert Bosch GmbH. 4 + */ 5 + #include <linux/mod_devicetable.h> 6 + #include <linux/module.h> 7 + #include <linux/regmap.h> 8 + #include <linux/spi/spi.h> 9 + 10 + #include "smi330.h" 11 + 12 + static int smi330_regmap_spi_read(void *context, const void *reg_buf, 13 + size_t reg_size, void *val_buf, 14 + size_t val_size) 15 + { 16 + struct spi_device *spi = context; 17 + 18 + /* Insert pad byte for reading */ 19 + u8 reg[] = { *(u8 *)reg_buf, 0 }; 20 + 21 + if (reg_size + 1 != ARRAY_SIZE(reg)) { 22 + dev_err(&spi->dev, "Invalid register size %zu\n", reg_size); 23 + return -EINVAL; 24 + } 25 + 26 + return spi_write_then_read(spi, reg, ARRAY_SIZE(reg), val_buf, 27 + val_size); 28 + } 29 + 30 + static int smi330_regmap_spi_write(void *context, const void *data, 31 + size_t count) 32 + { 33 + struct spi_device *spi = context; 34 + 35 + return spi_write(spi, data, count); 36 + } 37 + 38 + static const struct regmap_bus smi330_regmap_bus = { 39 + .read = smi330_regmap_spi_read, 40 + .write = smi330_regmap_spi_write, 41 + .read_flag_mask = 0x80, 42 + }; 43 + 44 + static int smi330_spi_probe(struct spi_device *spi) 45 + { 46 + struct regmap *regmap; 47 + 48 + regmap = devm_regmap_init(&spi->dev, &smi330_regmap_bus, &spi->dev, 49 + &smi330_regmap_config); 50 + if (IS_ERR(regmap)) 51 + return dev_err_probe(&spi->dev, PTR_ERR(regmap), 52 + "Failed to initialize SPI Regmap\n"); 53 + 54 + return smi330_core_probe(&spi->dev, regmap); 55 + } 56 + 57 + static const struct spi_device_id smi330_spi_device_id[] = { 58 + { .name = "smi330" }, 59 + { } 60 + }; 61 + MODULE_DEVICE_TABLE(spi, smi330_spi_device_id); 62 + 63 + static const struct of_device_id smi330_of_match[] = { 64 + { .compatible = "bosch,smi330" }, 65 + { } 66 + }; 67 + MODULE_DEVICE_TABLE(of, smi330_of_match); 68 + 69 + static struct spi_driver smi330_spi_driver = { 70 + .probe = smi330_spi_probe, 71 + .id_table = smi330_spi_device_id, 72 + .driver = { 73 + .of_match_table = smi330_of_match, 74 + .name = "smi330_spi", 75 + }, 76 + }; 77 + module_spi_driver(smi330_spi_driver); 78 + 79 + MODULE_AUTHOR("Stefan Gutmann <stefan.gutmann@de.bosch.com>"); 80 + MODULE_AUTHOR("Roman Huber <roman.huber@de.bosch.com>"); 81 + MODULE_AUTHOR("Filip Andrei <Andrei.Filip@ro.bosch.com>"); 82 + MODULE_AUTHOR("Drimbarean Avram Andrei <Avram-Andrei.Drimbarean@ro.bosch.com>"); 83 + MODULE_DESCRIPTION("Bosch SMI330 SPI driver"); 84 + MODULE_LICENSE("Dual BSD/GPL"); 85 + MODULE_IMPORT_NS("IIO_SMI330");
+3 -1
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx.h
··· 365 365 * @id: Sensor identifier. 366 366 * @hw: Pointer to instance of struct st_lsm6dsx_hw. 367 367 * @gain: Configured sensor sensitivity. 368 - * @odr: Output data rate of the sensor [Hz]. 368 + * @odr: Output data rate of the sensor [mHz]. 369 + * hwfifo_odr_mHz: Batch data rate for hardware FIFO [mHz] 369 370 * @samples_to_discard: Number of samples to discard for filters settling time. 370 371 * @watermark: Sensor watermark level. 371 372 * @decimator: Sensor decimation factor. ··· 381 380 382 381 u32 gain; 383 382 u32 odr; 383 + u32 hwfifo_odr_mHz; 384 384 385 385 u16 samples_to_discard; 386 386 u16 watermark;
+63 -8
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c
··· 56 56 #include <linux/iio/kfifo_buf.h> 57 57 #include <linux/iio/iio.h> 58 58 #include <linux/iio/buffer.h> 59 + #include <linux/iio/sysfs.h> 59 60 #include <linux/regmap.h> 60 61 #include <linux/bitfield.h> 61 62 ··· 106 105 st_lsm6dsx_get_decimator_val(struct st_lsm6dsx_sensor *sensor, u32 max_odr) 107 106 { 108 107 const int max_size = ARRAY_SIZE(st_lsm6dsx_decimator_table); 109 - u32 decimator = max_odr / sensor->odr; 108 + u32 decimator = max_odr / sensor->hwfifo_odr_mHz; 110 109 int i; 111 110 112 111 if (decimator > 1) ··· 137 136 if (!(hw->enable_mask & BIT(sensor->id))) 138 137 continue; 139 138 140 - *max_odr = max_t(u32, *max_odr, sensor->odr); 141 - *min_odr = min_t(u32, *min_odr, sensor->odr); 139 + *max_odr = max(*max_odr, sensor->hwfifo_odr_mHz); 140 + *min_odr = min(*min_odr, sensor->hwfifo_odr_mHz); 142 141 } 143 142 } 144 143 145 144 static u8 st_lsm6dsx_get_sip(struct st_lsm6dsx_sensor *sensor, u32 min_odr) 146 145 { 147 - u8 sip = sensor->odr / min_odr; 146 + u8 sip = sensor->hwfifo_odr_mHz / min_odr; 148 147 149 148 return sip > 1 ? round_down(sip, 2) : sip; 150 149 } ··· 232 231 if (enable) { 233 232 int err; 234 233 235 - err = st_lsm6dsx_check_odr(sensor, sensor->odr, 234 + err = st_lsm6dsx_check_odr(sensor, sensor->hwfifo_odr_mHz, 236 235 &data); 237 236 if (err < 0) 238 237 return err; ··· 714 713 715 714 data = &hw->settings->samples_to_discard[sensor->id]; 716 715 for (i = 0; i < ST_LSM6DSX_ODR_LIST_SIZE; i++) { 717 - if (data->val[i].milli_hz == sensor->odr) { 716 + if (data->val[i].milli_hz == sensor->hwfifo_odr_mHz) { 718 717 sensor->samples_to_discard = data->val[i].samples; 719 718 return; 720 719 } ··· 800 799 .postdisable = st_lsm6dsx_buffer_postdisable, 801 800 }; 802 801 802 + static ssize_t st_lsm6dsx_hwfifo_odr_show(struct device *dev, 803 + struct device_attribute *attr, char *buf) 804 + { 805 + struct st_lsm6dsx_sensor *sensor = iio_priv(dev_to_iio_dev(dev)); 806 + 807 + return sysfs_emit(buf, "%d.%03d\n", sensor->hwfifo_odr_mHz / 1000, 808 + sensor->hwfifo_odr_mHz % 1000); 809 + } 810 + 811 + static ssize_t st_lsm6dsx_hwfifo_odr_store(struct device *dev, 812 + struct device_attribute *attr, 813 + const char *buf, size_t len) 814 + { 815 + struct iio_dev *iio_dev = dev_to_iio_dev(dev); 816 + struct st_lsm6dsx_sensor *sensor = iio_priv(iio_dev); 817 + int integer, milli; 818 + int ret; 819 + u32 hwfifo_odr; 820 + u8 data; 821 + 822 + if (!iio_device_claim_direct(iio_dev)) 823 + return -EBUSY; 824 + 825 + ret = iio_str_to_fixpoint(buf, 100, &integer, &milli); 826 + if (ret) 827 + goto out; 828 + 829 + hwfifo_odr = integer * 1000 + milli; 830 + ret = st_lsm6dsx_check_odr(sensor, hwfifo_odr, &data); 831 + if (ret < 0) 832 + goto out; 833 + 834 + hwfifo_odr = ret; 835 + 836 + /* the batch data rate must not exceed the sensor output data rate */ 837 + if (hwfifo_odr <= sensor->odr) 838 + sensor->hwfifo_odr_mHz = hwfifo_odr; 839 + else 840 + ret = -EINVAL; 841 + 842 + out: 843 + iio_device_release_direct(iio_dev); 844 + 845 + return ret < 0 ? ret : len; 846 + } 847 + 848 + static IIO_DEV_ATTR_SAMP_FREQ(0664, st_lsm6dsx_hwfifo_odr_show, st_lsm6dsx_hwfifo_odr_store); 849 + 850 + static const struct iio_dev_attr *st_lsm6dsx_buffer_attrs[] = { 851 + &iio_dev_attr_sampling_frequency, 852 + NULL 853 + }; 854 + 803 855 int st_lsm6dsx_fifo_setup(struct st_lsm6dsx_hw *hw) 804 856 { 805 857 int i, ret; ··· 861 807 if (!hw->iio_devs[i]) 862 808 continue; 863 809 864 - ret = devm_iio_kfifo_buffer_setup(hw->dev, hw->iio_devs[i], 865 - &st_lsm6dsx_buffer_ops); 810 + ret = devm_iio_kfifo_buffer_setup_ext(hw->dev, hw->iio_devs[i], 811 + &st_lsm6dsx_buffer_ops, 812 + st_lsm6dsx_buffer_attrs); 866 813 if (ret) 867 814 return ret; 868 815 }
+5 -2
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c
··· 1847 1847 1848 1848 val = val * 1000 + val2 / 1000; 1849 1849 val = st_lsm6dsx_check_odr(sensor, val, &data); 1850 - if (val < 0) 1850 + if (val < 0) { 1851 1851 err = val; 1852 - else 1852 + } else { 1853 1853 sensor->odr = val; 1854 + sensor->hwfifo_odr_mHz = val; 1855 + } 1854 1856 break; 1855 1857 } 1856 1858 default: ··· 2386 2384 sensor->id = id; 2387 2385 sensor->hw = hw; 2388 2386 sensor->odr = hw->settings->odr_table[id].odr_avl[0].milli_hz; 2387 + sensor->hwfifo_odr_mHz = sensor->odr; 2389 2388 sensor->gain = hw->settings->fs_table[id].fs_avl[0].gain; 2390 2389 sensor->watermark = 1; 2391 2390
+2
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_shub.c
··· 640 640 641 641 sensor->ext_info.slv_odr = val; 642 642 sensor->odr = odr; 643 + sensor->hwfifo_odr_mHz = odr; 643 644 return 0; 644 645 } 645 646 case IIO_CHAN_INFO_SCALE: ··· 747 746 sensor->id = id; 748 747 sensor->hw = hw; 749 748 sensor->odr = hw->settings->odr_table[ref_id].odr_avl[0].milli_hz; 749 + sensor->hwfifo_odr_mHz = sensor->odr; 750 750 sensor->ext_info.slv_odr = info->odr_table.odr_avl[0].milli_hz; 751 751 sensor->gain = info->fs_table.fs_avl[0].gain; 752 752 sensor->ext_info.settings = info;
+6 -2
drivers/iio/industrialio-backend.c
··· 702 702 * interface/data bus. Hence, the backend device needs to be aware of it so 703 703 * data can be correctly transferred. 704 704 * 705 - * Return: 705 + * RETURNS: 706 706 * 0 on success, negative error number on failure. 707 707 */ 708 708 int iio_backend_data_size_set(struct iio_backend *back, unsigned int size) ··· 717 717 /** 718 718 * iio_backend_oversampling_ratio_set - set the oversampling ratio 719 719 * @back: Backend device 720 + * @chan: Channel number 720 721 * @ratio: The oversampling ratio - value 1 corresponds to no oversampling. 721 722 * 722 - * Return: 723 + * RETURNS: 723 724 * 0 on success, negative error number on failure. 724 725 */ 725 726 int iio_backend_oversampling_ratio_set(struct iio_backend *back, ··· 1065 1064 /** 1066 1065 * iio_backend_get_priv - Get driver private data 1067 1066 * @back: Backend device 1067 + * 1068 + * RETURNS: 1069 + * Pointer to the driver private data associated with the backend. 1068 1070 */ 1069 1071 void *iio_backend_get_priv(const struct iio_backend *back) 1070 1072 {
+9 -3
drivers/iio/industrialio-buffer.c
··· 1563 1563 struct iio_buffer *buffer = priv->buffer; 1564 1564 struct dma_buf *dmabuf = attach->dmabuf; 1565 1565 1566 - dma_resv_lock(dmabuf->resv, NULL); 1567 - dma_buf_unmap_attachment(attach, priv->sgt, priv->dir); 1568 - dma_resv_unlock(dmabuf->resv); 1566 + dma_buf_unmap_attachment_unlocked(attach, priv->sgt, priv->dir); 1569 1567 1570 1568 buffer->access->detach_dmabuf(buffer, priv->block); 1571 1569 ··· 2370 2372 * iio_push_to_buffers() - push to a registered buffer. 2371 2373 * @indio_dev: iio_dev structure for device. 2372 2374 * @data: Full scan. 2375 + * 2376 + * Context: Any context. 2377 + * Return: 0 on success, negative error code on failure. 2373 2378 */ 2374 2379 int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data) 2375 2380 { ··· 2402 2401 * not require space for the timestamp, or 8 byte alignment of data. 2403 2402 * It does however require an allocation on first call and additional 2404 2403 * copies on all calls, so should be avoided if possible. 2404 + * 2405 + * Context: May sleep. 2406 + * Return: 0 on success, negative error code on failure. 2405 2407 */ 2406 2408 int iio_push_to_buffers_with_ts_unaligned(struct iio_dev *indio_dev, 2407 2409 const void *data, ··· 2412 2408 int64_t timestamp) 2413 2409 { 2414 2410 struct iio_dev_opaque *iio_dev_opaque = to_iio_dev_opaque(indio_dev); 2411 + 2412 + might_sleep(); 2415 2413 2416 2414 /* 2417 2415 * Conservative estimate - we can always safely copy the minimum
+11 -7
drivers/iio/industrialio-core.c
··· 1654 1654 1655 1655 iio_device_detach_buffers(indio_dev); 1656 1656 1657 + mutex_destroy(&iio_dev_opaque->info_exist_lock); 1658 + mutex_destroy(&iio_dev_opaque->mlock); 1659 + 1657 1660 lockdep_unregister_key(&iio_dev_opaque->mlock_key); 1658 1661 1659 1662 ida_free(&iio_ida, iio_dev_opaque->id); ··· 1697 1694 ACCESS_PRIVATE(indio_dev, priv) = (char *)iio_dev_opaque + 1698 1695 ALIGN(sizeof(*iio_dev_opaque), IIO_DMA_MINALIGN); 1699 1696 1700 - indio_dev->dev.parent = parent; 1701 - indio_dev->dev.type = &iio_device_type; 1702 - indio_dev->dev.bus = &iio_bus_type; 1703 - device_initialize(&indio_dev->dev); 1704 - mutex_init(&iio_dev_opaque->mlock); 1705 - mutex_init(&iio_dev_opaque->info_exist_lock); 1706 1697 INIT_LIST_HEAD(&iio_dev_opaque->channel_attr_list); 1707 1698 1708 1699 iio_dev_opaque->id = ida_alloc(&iio_ida, GFP_KERNEL); ··· 1717 1720 INIT_LIST_HEAD(&iio_dev_opaque->ioctl_handlers); 1718 1721 1719 1722 lockdep_register_key(&iio_dev_opaque->mlock_key); 1720 - lockdep_set_class(&iio_dev_opaque->mlock, &iio_dev_opaque->mlock_key); 1723 + 1724 + mutex_init_with_key(&iio_dev_opaque->mlock, &iio_dev_opaque->mlock_key); 1725 + mutex_init(&iio_dev_opaque->info_exist_lock); 1726 + 1727 + indio_dev->dev.parent = parent; 1728 + indio_dev->dev.type = &iio_device_type; 1729 + indio_dev->dev.bus = &iio_bus_type; 1730 + device_initialize(&indio_dev->dev); 1721 1731 1722 1732 return indio_dev; 1723 1733 }
+1 -1
drivers/iio/light/apds9306.c
··· 350 350 .volatile_table = &apds9306_volatile_table, 351 351 .precious_table = &apds9306_precious_table, 352 352 .max_register = APDS9306_ALS_THRES_VAR_REG, 353 - .cache_type = REGCACHE_RBTREE, 353 + .cache_type = REGCACHE_MAPLE, 354 354 }; 355 355 356 356 static const struct reg_field apds9306_rf_sw_reset =
+1 -1
drivers/iio/light/apds9960.c
··· 234 234 .reg_defaults = apds9960_reg_defaults, 235 235 .num_reg_defaults = ARRAY_SIZE(apds9960_reg_defaults), 236 236 .max_register = APDS9960_REG_GFIFO_DIR(RIGHT), 237 - .cache_type = REGCACHE_RBTREE, 237 + .cache_type = REGCACHE_MAPLE, 238 238 }; 239 239 240 240 static const struct iio_event_spec apds9960_pxs_event_spec[] = {
+4 -4
drivers/iio/light/ltr390.c
··· 160 160 { 161 161 struct device *dev = &data->client->dev; 162 162 int ret; 163 - u8 recieve_buffer[3]; 163 + u8 receive_buffer[3]; 164 164 165 - ret = regmap_bulk_read(data->regmap, register_address, recieve_buffer, 166 - sizeof(recieve_buffer)); 165 + ret = regmap_bulk_read(data->regmap, register_address, receive_buffer, 166 + sizeof(receive_buffer)); 167 167 if (ret) { 168 168 dev_err(dev, "failed to read measurement data"); 169 169 return ret; 170 170 } 171 171 172 - return get_unaligned_le24(recieve_buffer); 172 + return get_unaligned_le24(receive_buffer); 173 173 } 174 174 175 175 static int ltr390_set_mode(struct ltr390_data *data, enum ltr390_mode mode)
+1 -1
drivers/iio/light/veml3235.c
··· 154 154 .rd_table = &veml3235_readable_table, 155 155 .wr_table = &veml3235_writable_table, 156 156 .volatile_table = &veml3235_volatile_table, 157 - .cache_type = REGCACHE_RBTREE, 157 + .cache_type = REGCACHE_MAPLE, 158 158 }; 159 159 160 160 static int veml3235_get_it(struct veml3235_data *data, int *val, int *val2)
+1 -1
drivers/iio/position/hid-sensor-custom-intel-hinge.c
··· 176 176 { 177 177 struct hinge_state *st = iio_priv(indio_dev); 178 178 179 - return sprintf(label, "%s\n", st->labels[chan->channel]); 179 + return sysfs_emit(label, "%s\n", st->labels[chan->channel]); 180 180 } 181 181 182 182 static const struct iio_info hinge_info = {
+12
drivers/iio/pressure/Kconfig
··· 339 339 tristate 340 340 select REGMAP_SPI 341 341 342 + config ADP810 343 + tristate "Aosong adp810 differential pressure and temperature sensor" 344 + depends on I2C 345 + select CRC8 346 + help 347 + Say yes here to build adp810 differential pressure and temperature 348 + sensor driver. ADP810 can measure pressure range up to 500Pa. 349 + It supports an I2C interface for data communication. 350 + 351 + To compile this driver as a module, choose M here: the module will 352 + be called adp810 353 + 342 354 endmenu
+4 -4
drivers/iio/pressure/Makefile
··· 5 5 6 6 # When adding new entries keep the list in alphabetical order 7 7 obj-$(CONFIG_ABP060MG) += abp060mg.o 8 + obj-$(CONFIG_ADP810) += adp810.o 8 9 obj-$(CONFIG_ROHM_BM1390) += rohm-bm1390.o 9 10 obj-$(CONFIG_BMP280) += bmp280.o 10 11 bmp280-objs := bmp280-core.o bmp280-regmap.o ··· 16 15 obj-$(CONFIG_IIO_CROS_EC_BARO) += cros_ec_baro.o 17 16 obj-$(CONFIG_HID_SENSOR_PRESS) += hid-sensor-press.o 18 17 obj-$(CONFIG_HP03) += hp03.o 18 + obj-$(CONFIG_HP206C) += hp206c.o 19 19 obj-$(CONFIG_HSC030PA) += hsc030pa.o 20 20 obj-$(CONFIG_HSC030PA_I2C) += hsc030pa_i2c.o 21 21 obj-$(CONFIG_HSC030PA_SPI) += hsc030pa_spi.o ··· 36 34 obj-$(CONFIG_IIO_ST_PRESS) += st_pressure.o 37 35 st_pressure-y := st_pressure_core.o 38 36 st_pressure-$(CONFIG_IIO_BUFFER) += st_pressure_buffer.o 37 + obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o 38 + obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o 39 39 obj-$(CONFIG_T5403) += t5403.o 40 - obj-$(CONFIG_HP206C) += hp206c.o 41 40 obj-$(CONFIG_ZPA2326) += zpa2326.o 42 41 obj-$(CONFIG_ZPA2326_I2C) += zpa2326_i2c.o 43 42 obj-$(CONFIG_ZPA2326_SPI) += zpa2326_spi.o 44 - 45 - obj-$(CONFIG_IIO_ST_PRESS_I2C) += st_pressure_i2c.o 46 - obj-$(CONFIG_IIO_ST_PRESS_SPI) += st_pressure_spi.o
+225
drivers/iio/pressure/adp810.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (c) 2025 Akhilesh Patil <akhilesh@ee.iitb.ac.in> 4 + * 5 + * Driver for adp810 pressure and temperature sensor 6 + * Datasheet: 7 + * https://aosong.com/userfiles/files/media/Datasheet%20ADP810-Digital.pdf 8 + */ 9 + 10 + #include <linux/array_size.h> 11 + #include <linux/cleanup.h> 12 + #include <linux/crc8.h> 13 + #include <linux/delay.h> 14 + #include <linux/device.h> 15 + #include <linux/dev_printk.h> 16 + #include <linux/errno.h> 17 + #include <linux/i2c.h> 18 + #include <linux/module.h> 19 + #include <linux/mod_devicetable.h> 20 + #include <linux/mutex.h> 21 + #include <linux/types.h> 22 + #include <linux/unaligned.h> 23 + 24 + #include <linux/iio/iio.h> 25 + #include <linux/iio/types.h> 26 + 27 + /* 28 + * Refer section 5.4 checksum calculation from datasheet. 29 + * This sensor uses CRC polynomial x^8 + x^5 + x^4 + 1 (0x31) 30 + */ 31 + #define ADP810_CRC8_POLYNOMIAL 0x31 32 + 33 + DECLARE_CRC8_TABLE(crc_table); 34 + 35 + /* 36 + * Buffer declaration which holds 9 bytes of measurement data read 37 + * from the sensor. Use __packed to avoid any paddings, as data sent 38 + * from the sensor is strictly contiguous 9 bytes. 39 + */ 40 + struct adp810_read_buf { 41 + __be16 dp; 42 + u8 dp_crc; 43 + __be16 tmp; 44 + u8 tmp_crc; 45 + __be16 sf; 46 + u8 sf_crc; 47 + } __packed; 48 + 49 + struct adp810_data { 50 + struct i2c_client *client; 51 + /* Use lock to synchronize access to device during read sequence */ 52 + struct mutex lock; 53 + }; 54 + 55 + static int adp810_measure(struct adp810_data *data, struct adp810_read_buf *buf) 56 + { 57 + struct i2c_client *client = data->client; 58 + struct device *dev = &client->dev; 59 + int ret; 60 + u8 trig_cmd[2] = {0x37, 0x2d}; 61 + 62 + /* Send trigger command to the sensor for measurement */ 63 + ret = i2c_master_send(client, trig_cmd, sizeof(trig_cmd)); 64 + if (ret < 0) { 65 + dev_err(dev, "Error sending trigger command\n"); 66 + return ret; 67 + } 68 + if (ret != sizeof(trig_cmd)) 69 + return -EIO; 70 + 71 + /* 72 + * Wait for the sensor to acquire data. As per datasheet section 5.3.1, 73 + * at least 10ms delay before reading from the sensor is recommended. 74 + * Here, we wait for 20ms to have some safe margin on the top 75 + * of recommendation and to compensate for any possible variations. 76 + */ 77 + msleep(20); 78 + 79 + /* Read sensor values */ 80 + ret = i2c_master_recv(client, (char *)buf, sizeof(*buf)); 81 + if (ret < 0) { 82 + dev_err(dev, "Error reading from sensor\n"); 83 + return ret; 84 + } 85 + if (ret != sizeof(*buf)) 86 + return -EIO; 87 + 88 + /* CRC checks */ 89 + crc8_populate_msb(crc_table, ADP810_CRC8_POLYNOMIAL); 90 + if (buf->dp_crc != crc8(crc_table, (u8 *)&buf->dp, 0x2, CRC8_INIT_VALUE)) { 91 + dev_err(dev, "CRC error for pressure\n"); 92 + return -EIO; 93 + } 94 + 95 + if (buf->tmp_crc != crc8(crc_table, (u8 *)&buf->tmp, 0x2, CRC8_INIT_VALUE)) { 96 + dev_err(dev, "CRC error for temperature\n"); 97 + return -EIO; 98 + } 99 + 100 + if (buf->sf_crc != crc8(crc_table, (u8 *)&buf->sf, 0x2, CRC8_INIT_VALUE)) { 101 + dev_err(dev, "CRC error for scale\n"); 102 + return -EIO; 103 + } 104 + 105 + return 0; 106 + } 107 + 108 + static int adp810_read_raw(struct iio_dev *indio_dev, 109 + struct iio_chan_spec const *chan, 110 + int *val, int *val2, long mask) 111 + { 112 + struct adp810_data *data = iio_priv(indio_dev); 113 + struct device *dev = &data->client->dev; 114 + struct adp810_read_buf buf = { }; 115 + int ret; 116 + 117 + scoped_guard(mutex, &data->lock) { 118 + ret = adp810_measure(data, &buf); 119 + if (ret) { 120 + dev_err(dev, "Failed to read from device\n"); 121 + return ret; 122 + } 123 + } 124 + 125 + switch (mask) { 126 + case IIO_CHAN_INFO_RAW: 127 + switch (chan->type) { 128 + case IIO_PRESSURE: 129 + *val = get_unaligned_be16(&buf.dp); 130 + return IIO_VAL_INT; 131 + case IIO_TEMP: 132 + *val = get_unaligned_be16(&buf.tmp); 133 + return IIO_VAL_INT; 134 + default: 135 + return -EINVAL; 136 + } 137 + case IIO_CHAN_INFO_SCALE: 138 + switch (chan->type) { 139 + case IIO_PRESSURE: 140 + *val = get_unaligned_be16(&buf.sf); 141 + return IIO_VAL_INT; 142 + case IIO_TEMP: 143 + *val = 200; 144 + return IIO_VAL_INT; 145 + default: 146 + return -EINVAL; 147 + } 148 + default: 149 + return -EINVAL; 150 + } 151 + } 152 + 153 + static const struct iio_info adp810_info = { 154 + .read_raw = adp810_read_raw, 155 + }; 156 + 157 + static const struct iio_chan_spec adp810_channels[] = { 158 + { 159 + .type = IIO_PRESSURE, 160 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 161 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), 162 + }, 163 + { 164 + .type = IIO_TEMP, 165 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 166 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), 167 + }, 168 + }; 169 + 170 + static int adp810_probe(struct i2c_client *client) 171 + { 172 + struct device *dev = &client->dev; 173 + struct iio_dev *indio_dev; 174 + struct adp810_data *data; 175 + int ret; 176 + 177 + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 178 + if (!indio_dev) 179 + return -ENOMEM; 180 + 181 + data = iio_priv(indio_dev); 182 + data->client = client; 183 + 184 + ret = devm_mutex_init(dev, &data->lock); 185 + if (ret) 186 + return ret; 187 + 188 + indio_dev->name = "adp810"; 189 + indio_dev->channels = adp810_channels; 190 + indio_dev->num_channels = ARRAY_SIZE(adp810_channels); 191 + indio_dev->info = &adp810_info; 192 + indio_dev->modes = INDIO_DIRECT_MODE; 193 + 194 + ret = devm_iio_device_register(dev, indio_dev); 195 + if (ret) 196 + return dev_err_probe(dev, ret, "Failed to register IIO device\n"); 197 + 198 + return 0; 199 + } 200 + 201 + static const struct i2c_device_id adp810_id_table[] = { 202 + { "adp810" }, 203 + { } 204 + }; 205 + MODULE_DEVICE_TABLE(i2c, adp810_id_table); 206 + 207 + static const struct of_device_id adp810_of_table[] = { 208 + { .compatible = "aosong,adp810" }, 209 + { } 210 + }; 211 + MODULE_DEVICE_TABLE(of, adp810_of_table); 212 + 213 + static struct i2c_driver adp810_driver = { 214 + .driver = { 215 + .name = "adp810", 216 + .of_match_table = adp810_of_table, 217 + }, 218 + .probe = adp810_probe, 219 + .id_table = adp810_id_table, 220 + }; 221 + module_i2c_driver(adp810_driver); 222 + 223 + MODULE_AUTHOR("Akhilesh Patil <akhilesh@ee.iitb.ac.in>"); 224 + MODULE_DESCRIPTION("Driver for Aosong ADP810 sensor"); 225 + MODULE_LICENSE("GPL");
+507 -44
drivers/iio/pressure/mpl3115.c
··· 7 7 * (7-bit I2C slave address 0x60) 8 8 * 9 9 * TODO: FIFO buffer, altimeter mode, oversampling, continuous mode, 10 - * interrupts, user offset correction, raw mode 10 + * user offset correction, raw mode 11 11 */ 12 12 13 - #include <linux/module.h> 13 + #include <linux/bitfield.h> 14 + #include <linux/cleanup.h> 15 + #include <linux/delay.h> 14 16 #include <linux/i2c.h> 17 + #include <linux/limits.h> 18 + #include <linux/module.h> 19 + #include <linux/property.h> 20 + #include <linux/unaligned.h> 21 + 22 + #include <linux/iio/buffer.h> 23 + #include <linux/iio/events.h> 15 24 #include <linux/iio/iio.h> 16 25 #include <linux/iio/sysfs.h> 17 - #include <linux/iio/trigger_consumer.h> 18 - #include <linux/iio/buffer.h> 19 26 #include <linux/iio/triggered_buffer.h> 20 - #include <linux/delay.h> 27 + #include <linux/iio/trigger_consumer.h> 28 + #include <linux/iio/trigger.h> 21 29 22 30 #define MPL3115_STATUS 0x00 23 31 #define MPL3115_OUT_PRESS 0x01 /* MSB first, 20 bit */ 24 32 #define MPL3115_OUT_TEMP 0x04 /* MSB first, 12 bit */ 25 33 #define MPL3115_WHO_AM_I 0x0c 34 + #define MPL3115_INT_SOURCE 0x12 35 + #define MPL3115_PT_DATA_CFG 0x13 36 + #define MPL3115_PRESS_TGT 0x16 /* MSB first, 16 bit */ 37 + #define MPL3115_TEMP_TGT 0x18 26 38 #define MPL3115_CTRL_REG1 0x26 39 + #define MPL3115_CTRL_REG2 0x27 40 + #define MPL3115_CTRL_REG3 0x28 41 + #define MPL3115_CTRL_REG4 0x29 42 + #define MPL3115_CTRL_REG5 0x2a 27 43 28 44 #define MPL3115_DEVICE_ID 0xc4 29 45 30 46 #define MPL3115_STATUS_PRESS_RDY BIT(2) 31 47 #define MPL3115_STATUS_TEMP_RDY BIT(1) 32 48 33 - #define MPL3115_CTRL_RESET BIT(2) /* software reset */ 34 - #define MPL3115_CTRL_OST BIT(1) /* initiate measurement */ 35 - #define MPL3115_CTRL_ACTIVE BIT(0) /* continuous measurement */ 36 - #define MPL3115_CTRL_OS_258MS (BIT(5) | BIT(4)) /* 64x oversampling */ 49 + #define MPL3115_INT_SRC_DRDY BIT(7) 50 + #define MPL3115_INT_SRC_PTH BIT(3) 51 + #define MPL3115_INT_SRC_TTH BIT(2) 52 + 53 + #define MPL3115_PT_DATA_EVENT_ALL GENMASK(2, 0) 54 + 55 + #define MPL3115_CTRL1_RESET BIT(2) /* software reset */ 56 + #define MPL3115_CTRL1_OST BIT(1) /* initiate measurement */ 57 + #define MPL3115_CTRL1_ACTIVE BIT(0) /* continuous measurement */ 58 + #define MPL3115_CTRL1_OS_258MS GENMASK(5, 4) /* 64x oversampling */ 59 + 60 + #define MPL3115_CTRL2_ST GENMASK(3, 0) 61 + 62 + #define MPL3115_CTRL3_IPOL1 BIT(5) 63 + #define MPL3115_CTRL3_IPOL2 BIT(1) 64 + 65 + #define MPL3115_CTRL4_INT_EN_DRDY BIT(7) 66 + #define MPL3115_CTRL4_INT_EN_PTH BIT(3) 67 + #define MPL3115_CTRL4_INT_EN_TTH BIT(2) 68 + 69 + #define MPL3115_CTRL5_INT_CFG_DRDY BIT(7) 70 + 71 + static const unsigned int mpl3115_samp_freq_table[][2] = { 72 + { 1, 0 }, 73 + { 0, 500000 }, 74 + { 0, 250000 }, 75 + { 0, 125000 }, 76 + { 0, 62500 }, 77 + { 0, 31250 }, 78 + { 0, 15625 }, 79 + { 0, 7812 }, 80 + { 0, 3906 }, 81 + { 0, 1953 }, 82 + { 0, 976 }, 83 + { 0, 488 }, 84 + { 0, 244 }, 85 + { 0, 122 }, 86 + { 0, 61 }, 87 + { 0, 30 }, 88 + }; 37 89 38 90 struct mpl3115_data { 39 91 struct i2c_client *client; 92 + struct iio_trigger *drdy_trig; 40 93 struct mutex lock; 41 94 u8 ctrl_reg1; 95 + u8 ctrl_reg4; 96 + }; 97 + 98 + enum mpl3115_irq_pin { 99 + MPL3115_IRQ_INT1, 100 + MPL3115_IRQ_INT2, 42 101 }; 43 102 44 103 static int mpl3115_request(struct mpl3115_data *data) ··· 106 47 107 48 /* trigger measurement */ 108 49 ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, 109 - data->ctrl_reg1 | MPL3115_CTRL_OST); 50 + data->ctrl_reg1 | MPL3115_CTRL1_OST); 110 51 if (ret < 0) 111 52 return ret; 112 53 ··· 115 56 if (ret < 0) 116 57 return ret; 117 58 /* wait for data ready, i.e. OST cleared */ 118 - if (!(ret & MPL3115_CTRL_OST)) 59 + if (!(ret & MPL3115_CTRL1_OST)) 119 60 break; 120 61 msleep(20); 121 62 } ··· 135 76 136 77 switch (chan->type) { 137 78 case IIO_PRESSURE: { /* in 0.25 pascal / LSB */ 138 - __be32 tmp = 0; 79 + u8 press_be24[3]; 139 80 140 81 guard(mutex)(&data->lock); 141 82 ret = mpl3115_request(data); ··· 144 85 145 86 ret = i2c_smbus_read_i2c_block_data(data->client, 146 87 MPL3115_OUT_PRESS, 147 - 3, (u8 *) &tmp); 88 + sizeof(press_be24), 89 + press_be24); 148 90 if (ret < 0) 149 91 return ret; 150 92 151 - *val = be32_to_cpu(tmp) >> chan->scan_type.shift; 93 + /* 94 + * The pressure channel shift is applied in the case where the 95 + * data (24-bit big endian) is read into a 32-bit buffer. Here 96 + * the data is stored in a 24-bit buffer, so the shift is 4. 97 + */ 98 + *val = get_unaligned_be24(press_be24) >> 4; 152 99 return IIO_VAL_INT; 153 100 } 154 101 case IIO_TEMP: { /* in 0.0625 celsius / LSB */ ··· 209 144 default: 210 145 return -EINVAL; 211 146 } 147 + case IIO_CHAN_INFO_SAMP_FREQ: 148 + ret = i2c_smbus_read_byte_data(data->client, MPL3115_CTRL_REG2); 149 + if (ret < 0) 150 + return ret; 151 + 152 + ret = FIELD_GET(MPL3115_CTRL2_ST, ret); 153 + 154 + *val = mpl3115_samp_freq_table[ret][0]; 155 + *val2 = mpl3115_samp_freq_table[ret][1]; 156 + return IIO_VAL_INT_PLUS_MICRO; 212 157 } 213 158 return -EINVAL; 159 + } 160 + 161 + static int mpl3115_read_avail(struct iio_dev *indio_dev, 162 + struct iio_chan_spec const *chan, 163 + const int **vals, int *type, int *length, 164 + long mask) 165 + { 166 + if (mask != IIO_CHAN_INFO_SAMP_FREQ) 167 + return -EINVAL; 168 + 169 + *type = IIO_VAL_INT_PLUS_MICRO; 170 + *length = ARRAY_SIZE(mpl3115_samp_freq_table) * 2; 171 + *vals = (int *)mpl3115_samp_freq_table; 172 + return IIO_AVAIL_LIST; 173 + } 174 + 175 + static int mpl3115_write_raw(struct iio_dev *indio_dev, 176 + const struct iio_chan_spec *chan, 177 + int val, int val2, long mask) 178 + { 179 + struct mpl3115_data *data = iio_priv(indio_dev); 180 + int i, ret; 181 + 182 + if (mask != IIO_CHAN_INFO_SAMP_FREQ) 183 + return -EINVAL; 184 + 185 + for (i = 0; i < ARRAY_SIZE(mpl3115_samp_freq_table); i++) 186 + if (val == mpl3115_samp_freq_table[i][0] && 187 + val2 == mpl3115_samp_freq_table[i][1]) 188 + break; 189 + 190 + if (i == ARRAY_SIZE(mpl3115_samp_freq_table)) 191 + return -EINVAL; 192 + 193 + if (!iio_device_claim_direct(indio_dev)) 194 + return -EBUSY; 195 + 196 + ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG2, 197 + FIELD_PREP(MPL3115_CTRL2_ST, i)); 198 + iio_device_release_direct(indio_dev); 199 + return ret; 200 + } 201 + 202 + static int mpl3115_fill_trig_buffer(struct iio_dev *indio_dev, u8 *buffer) 203 + { 204 + struct mpl3115_data *data = iio_priv(indio_dev); 205 + int ret, pos = 0; 206 + 207 + if (!(data->ctrl_reg1 & MPL3115_CTRL1_ACTIVE)) { 208 + ret = mpl3115_request(data); 209 + if (ret < 0) 210 + return ret; 211 + } 212 + 213 + if (test_bit(0, indio_dev->active_scan_mask)) { 214 + ret = i2c_smbus_read_i2c_block_data(data->client, 215 + MPL3115_OUT_PRESS, 3, &buffer[pos]); 216 + if (ret < 0) 217 + return ret; 218 + pos += 4; 219 + } 220 + 221 + if (test_bit(1, indio_dev->active_scan_mask)) { 222 + ret = i2c_smbus_read_i2c_block_data(data->client, 223 + MPL3115_OUT_TEMP, 2, &buffer[pos]); 224 + if (ret < 0) 225 + return ret; 226 + } 227 + 228 + return 0; 214 229 } 215 230 216 231 static irqreturn_t mpl3115_trigger_handler(int irq, void *p) ··· 306 161 * use a simple structure definition to express this data layout. 307 162 */ 308 163 u8 buffer[16] __aligned(8) = { }; 309 - int ret, pos = 0; 164 + int ret; 310 165 311 166 mutex_lock(&data->lock); 312 - ret = mpl3115_request(data); 313 - if (ret < 0) { 314 - mutex_unlock(&data->lock); 315 - goto done; 316 - } 317 - 318 - if (test_bit(0, indio_dev->active_scan_mask)) { 319 - ret = i2c_smbus_read_i2c_block_data(data->client, 320 - MPL3115_OUT_PRESS, 3, &buffer[pos]); 321 - if (ret < 0) { 322 - mutex_unlock(&data->lock); 323 - goto done; 324 - } 325 - pos += 4; 326 - } 327 - 328 - if (test_bit(1, indio_dev->active_scan_mask)) { 329 - ret = i2c_smbus_read_i2c_block_data(data->client, 330 - MPL3115_OUT_TEMP, 2, &buffer[pos]); 331 - if (ret < 0) { 332 - mutex_unlock(&data->lock); 333 - goto done; 334 - } 335 - } 167 + ret = mpl3115_fill_trig_buffer(indio_dev, buffer); 336 168 mutex_unlock(&data->lock); 169 + if (ret) 170 + goto done; 337 171 338 172 iio_push_to_buffers_with_ts(indio_dev, buffer, sizeof(buffer), 339 173 iio_get_time_ns(indio_dev)); ··· 322 198 return IRQ_HANDLED; 323 199 } 324 200 201 + static const struct iio_event_spec mpl3115_temp_press_event[] = { 202 + { 203 + .type = IIO_EV_TYPE_THRESH, 204 + .dir = IIO_EV_DIR_RISING, 205 + .mask_separate = BIT(IIO_EV_INFO_ENABLE) | 206 + BIT(IIO_EV_INFO_VALUE), 207 + }, 208 + }; 209 + 325 210 static const struct iio_chan_spec mpl3115_channels[] = { 326 211 { 327 212 .type = IIO_PRESSURE, 328 213 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 329 214 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), 215 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), 216 + .info_mask_shared_by_all_available = 217 + BIT(IIO_CHAN_INFO_SAMP_FREQ), 330 218 .scan_index = 0, 331 219 .scan_type = { 332 220 .sign = 'u', ··· 346 210 .storagebits = 32, 347 211 .shift = 12, 348 212 .endianness = IIO_BE, 349 - } 213 + }, 214 + .event_spec = mpl3115_temp_press_event, 215 + .num_event_specs = ARRAY_SIZE(mpl3115_temp_press_event), 350 216 }, 351 217 { 352 218 .type = IIO_TEMP, 353 219 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 354 220 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), 221 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), 222 + .info_mask_shared_by_all_available = 223 + BIT(IIO_CHAN_INFO_SAMP_FREQ), 355 224 .scan_index = 1, 356 225 .scan_type = { 357 226 .sign = 's', ··· 364 223 .storagebits = 16, 365 224 .shift = 4, 366 225 .endianness = IIO_BE, 367 - } 226 + }, 227 + .event_spec = mpl3115_temp_press_event, 228 + .num_event_specs = ARRAY_SIZE(mpl3115_temp_press_event), 368 229 }, 369 230 IIO_CHAN_SOFT_TIMESTAMP(2), 370 231 }; 371 232 233 + static irqreturn_t mpl3115_interrupt_handler(int irq, void *private) 234 + { 235 + struct iio_dev *indio_dev = private; 236 + struct mpl3115_data *data = iio_priv(indio_dev); 237 + int ret; 238 + u8 val_press[3]; 239 + __be16 val_temp; 240 + 241 + ret = i2c_smbus_read_byte_data(data->client, MPL3115_INT_SOURCE); 242 + if (ret < 0) 243 + return IRQ_HANDLED; 244 + 245 + if (!(ret & (MPL3115_INT_SRC_TTH | MPL3115_INT_SRC_PTH | 246 + MPL3115_INT_SRC_DRDY))) 247 + return IRQ_NONE; 248 + 249 + if (ret & MPL3115_INT_SRC_DRDY) 250 + iio_trigger_poll_nested(data->drdy_trig); 251 + 252 + if (ret & MPL3115_INT_SRC_PTH) { 253 + iio_push_event(indio_dev, 254 + IIO_UNMOD_EVENT_CODE(IIO_PRESSURE, 0, 255 + IIO_EV_TYPE_THRESH, 256 + IIO_EV_DIR_RISING), 257 + iio_get_time_ns(indio_dev)); 258 + 259 + /* Reset the SRC_PTH bit in INT_SOURCE */ 260 + i2c_smbus_read_i2c_block_data(data->client, 261 + MPL3115_OUT_PRESS, 262 + sizeof(val_press), val_press); 263 + } 264 + 265 + if (ret & MPL3115_INT_SRC_TTH) { 266 + iio_push_event(indio_dev, 267 + IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, 268 + IIO_EV_TYPE_THRESH, 269 + IIO_EV_DIR_RISING), 270 + iio_get_time_ns(indio_dev)); 271 + 272 + /* Reset the SRC_TTH bit in INT_SOURCE */ 273 + i2c_smbus_read_i2c_block_data(data->client, 274 + MPL3115_OUT_TEMP, 275 + sizeof(val_temp), 276 + (u8 *)&val_temp); 277 + } 278 + 279 + return IRQ_HANDLED; 280 + } 281 + 282 + static int mpl3115_config_interrupt(struct mpl3115_data *data, 283 + u8 ctrl_reg1, u8 ctrl_reg4) 284 + { 285 + int ret; 286 + 287 + ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, 288 + ctrl_reg1); 289 + if (ret < 0) 290 + return ret; 291 + 292 + ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG4, 293 + ctrl_reg4); 294 + if (ret < 0) 295 + goto reg1_cleanup; 296 + 297 + data->ctrl_reg1 = ctrl_reg1; 298 + data->ctrl_reg4 = ctrl_reg4; 299 + 300 + return 0; 301 + 302 + reg1_cleanup: 303 + i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, 304 + data->ctrl_reg1); 305 + return ret; 306 + } 307 + 308 + static int mpl3115_set_trigger_state(struct iio_trigger *trig, bool state) 309 + { 310 + struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); 311 + struct mpl3115_data *data = iio_priv(indio_dev); 312 + u8 ctrl_reg1, ctrl_reg4; 313 + 314 + guard(mutex)(&data->lock); 315 + 316 + ctrl_reg1 = data->ctrl_reg1; 317 + ctrl_reg4 = data->ctrl_reg4; 318 + 319 + if (state) { 320 + ctrl_reg1 |= MPL3115_CTRL1_ACTIVE; 321 + ctrl_reg4 |= MPL3115_CTRL4_INT_EN_DRDY; 322 + } else { 323 + ctrl_reg4 &= ~MPL3115_CTRL4_INT_EN_DRDY; 324 + 325 + if (!ctrl_reg4) 326 + ctrl_reg1 &= ~MPL3115_CTRL1_ACTIVE; 327 + } 328 + 329 + return mpl3115_config_interrupt(data, ctrl_reg1, ctrl_reg4); 330 + } 331 + 332 + static const struct iio_trigger_ops mpl3115_trigger_ops = { 333 + .set_trigger_state = mpl3115_set_trigger_state, 334 + }; 335 + 336 + static int mpl3115_read_event_config(struct iio_dev *indio_dev, 337 + const struct iio_chan_spec *chan, 338 + enum iio_event_type type, 339 + enum iio_event_direction dir) 340 + { 341 + struct mpl3115_data *data = iio_priv(indio_dev); 342 + 343 + if (chan->type == IIO_PRESSURE) 344 + return !!(data->ctrl_reg4 & MPL3115_CTRL4_INT_EN_PTH); 345 + 346 + if (chan->type == IIO_TEMP) 347 + return !!(data->ctrl_reg4 & MPL3115_CTRL4_INT_EN_TTH); 348 + 349 + return -EINVAL; 350 + } 351 + 352 + static int mpl3115_write_event_config(struct iio_dev *indio_dev, 353 + const struct iio_chan_spec *chan, 354 + enum iio_event_type type, 355 + enum iio_event_direction dir, 356 + bool state) 357 + { 358 + struct mpl3115_data *data = iio_priv(indio_dev); 359 + u8 int_en_mask; 360 + u8 ctrl_reg1, ctrl_reg4; 361 + 362 + switch (chan->type) { 363 + case IIO_PRESSURE: 364 + int_en_mask = MPL3115_CTRL4_INT_EN_PTH; 365 + break; 366 + case IIO_TEMP: 367 + int_en_mask = MPL3115_CTRL4_INT_EN_TTH; 368 + break; 369 + default: 370 + return -EINVAL; 371 + } 372 + 373 + guard(mutex)(&data->lock); 374 + 375 + ctrl_reg1 = data->ctrl_reg1; 376 + ctrl_reg4 = data->ctrl_reg4; 377 + 378 + if (state) { 379 + ctrl_reg1 |= MPL3115_CTRL1_ACTIVE; 380 + ctrl_reg4 |= int_en_mask; 381 + } else { 382 + ctrl_reg4 &= ~int_en_mask; 383 + 384 + if (!ctrl_reg4) 385 + ctrl_reg1 &= ~MPL3115_CTRL1_ACTIVE; 386 + } 387 + 388 + return mpl3115_config_interrupt(data, ctrl_reg1, ctrl_reg4); 389 + } 390 + 391 + static int mpl3115_read_thresh(struct iio_dev *indio_dev, 392 + const struct iio_chan_spec *chan, 393 + enum iio_event_type type, 394 + enum iio_event_direction dir, 395 + enum iio_event_info info, 396 + int *val, int *val2) 397 + { 398 + struct mpl3115_data *data = iio_priv(indio_dev); 399 + int ret; 400 + __be16 press_tgt; 401 + 402 + if (info != IIO_EV_INFO_VALUE) 403 + return -EINVAL; 404 + 405 + switch (chan->type) { 406 + case IIO_PRESSURE: 407 + ret = i2c_smbus_read_i2c_block_data(data->client, 408 + MPL3115_PRESS_TGT, 409 + sizeof(press_tgt), 410 + (u8 *)&press_tgt); 411 + if (ret < 0) 412 + return ret; 413 + 414 + /* 415 + * Target value for the pressure is 16-bit unsigned value, 416 + * expressed in 2 Pa units 417 + */ 418 + *val = be16_to_cpu(press_tgt) << 1; 419 + 420 + return IIO_VAL_INT; 421 + case IIO_TEMP: 422 + ret = i2c_smbus_read_byte_data(data->client, MPL3115_TEMP_TGT); 423 + if (ret < 0) 424 + return ret; 425 + 426 + /* Target value for the temperature is 8-bit 2's complement */ 427 + *val = sign_extend32(ret, 7); 428 + 429 + return IIO_VAL_INT; 430 + default: 431 + return -EINVAL; 432 + } 433 + } 434 + 435 + static int mpl3115_write_thresh(struct iio_dev *indio_dev, 436 + const struct iio_chan_spec *chan, 437 + enum iio_event_type type, 438 + enum iio_event_direction dir, 439 + enum iio_event_info info, 440 + int val, int val2) 441 + { 442 + struct mpl3115_data *data = iio_priv(indio_dev); 443 + __be16 press_tgt; 444 + 445 + if (info != IIO_EV_INFO_VALUE) 446 + return -EINVAL; 447 + 448 + switch (chan->type) { 449 + case IIO_PRESSURE: 450 + val >>= 1; 451 + 452 + if (val < 0 || val > U16_MAX) 453 + return -EINVAL; 454 + 455 + press_tgt = cpu_to_be16(val); 456 + 457 + return i2c_smbus_write_i2c_block_data(data->client, 458 + MPL3115_PRESS_TGT, 459 + sizeof(press_tgt), 460 + (u8 *)&press_tgt); 461 + case IIO_TEMP: 462 + if (val < S8_MIN || val > S8_MAX) 463 + return -EINVAL; 464 + 465 + return i2c_smbus_write_byte_data(data->client, 466 + MPL3115_TEMP_TGT, val); 467 + default: 468 + return -EINVAL; 469 + } 470 + } 471 + 372 472 static const struct iio_info mpl3115_info = { 373 473 .read_raw = &mpl3115_read_raw, 474 + .read_avail = &mpl3115_read_avail, 475 + .write_raw = &mpl3115_write_raw, 476 + .read_event_config = mpl3115_read_event_config, 477 + .write_event_config = mpl3115_write_event_config, 478 + .read_event_value = mpl3115_read_thresh, 479 + .write_event_value = mpl3115_write_thresh, 374 480 }; 481 + 482 + static int mpl3115_trigger_probe(struct mpl3115_data *data, 483 + struct iio_dev *indio_dev) 484 + { 485 + struct fwnode_handle *fwnode = dev_fwnode(&data->client->dev); 486 + int ret, irq, irq_type, irq_pin = MPL3115_IRQ_INT1; 487 + 488 + irq = fwnode_irq_get_byname(fwnode, "INT1"); 489 + if (irq < 0) { 490 + irq = fwnode_irq_get_byname(fwnode, "INT2"); 491 + if (irq < 0) 492 + return 0; 493 + 494 + irq_pin = MPL3115_IRQ_INT2; 495 + } 496 + 497 + irq_type = irq_get_trigger_type(irq); 498 + if (irq_type != IRQF_TRIGGER_RISING && irq_type != IRQF_TRIGGER_FALLING) 499 + return -EINVAL; 500 + 501 + ret = i2c_smbus_write_byte_data(data->client, MPL3115_PT_DATA_CFG, 502 + MPL3115_PT_DATA_EVENT_ALL); 503 + if (ret < 0) 504 + return ret; 505 + 506 + if (irq_pin == MPL3115_IRQ_INT1) { 507 + ret = i2c_smbus_write_byte_data(data->client, 508 + MPL3115_CTRL_REG5, 509 + MPL3115_CTRL5_INT_CFG_DRDY); 510 + if (ret) 511 + return ret; 512 + 513 + if (irq_type == IRQF_TRIGGER_RISING) { 514 + ret = i2c_smbus_write_byte_data(data->client, 515 + MPL3115_CTRL_REG3, 516 + MPL3115_CTRL3_IPOL1); 517 + if (ret) 518 + return ret; 519 + } 520 + } else if (irq_type == IRQF_TRIGGER_RISING) { 521 + ret = i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG3, 522 + MPL3115_CTRL3_IPOL2); 523 + if (ret) 524 + return ret; 525 + } 526 + 527 + data->drdy_trig = devm_iio_trigger_alloc(&data->client->dev, 528 + "%s-dev%d", 529 + indio_dev->name, 530 + iio_device_id(indio_dev)); 531 + if (!data->drdy_trig) 532 + return -ENOMEM; 533 + 534 + data->drdy_trig->ops = &mpl3115_trigger_ops; 535 + iio_trigger_set_drvdata(data->drdy_trig, indio_dev); 536 + 537 + ret = devm_request_threaded_irq(&data->client->dev, irq, NULL, 538 + mpl3115_interrupt_handler, 539 + IRQF_ONESHOT, 540 + "mpl3115_irq", indio_dev); 541 + if (ret) 542 + return ret; 543 + 544 + ret = devm_iio_trigger_register(&data->client->dev, data->drdy_trig); 545 + if (ret) 546 + return ret; 547 + 548 + indio_dev->trig = iio_trigger_get(data->drdy_trig); 549 + 550 + return 0; 551 + } 375 552 376 553 static int mpl3115_probe(struct i2c_client *client) 377 554 { ··· 721 262 722 263 /* software reset, I2C transfer is aborted (fails) */ 723 264 i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1, 724 - MPL3115_CTRL_RESET); 265 + MPL3115_CTRL1_RESET); 725 266 msleep(50); 726 267 727 - data->ctrl_reg1 = MPL3115_CTRL_OS_258MS; 268 + data->ctrl_reg1 = MPL3115_CTRL1_OS_258MS; 728 269 ret = i2c_smbus_write_byte_data(client, MPL3115_CTRL_REG1, 729 270 data->ctrl_reg1); 730 271 if (ret < 0) 272 + return ret; 273 + 274 + ret = mpl3115_trigger_probe(data, indio_dev); 275 + if (ret) 731 276 return ret; 732 277 733 278 ret = iio_triggered_buffer_setup(indio_dev, NULL, ··· 752 289 static int mpl3115_standby(struct mpl3115_data *data) 753 290 { 754 291 return i2c_smbus_write_byte_data(data->client, MPL3115_CTRL_REG1, 755 - data->ctrl_reg1 & ~MPL3115_CTRL_ACTIVE); 292 + data->ctrl_reg1 & ~MPL3115_CTRL1_ACTIVE); 756 293 } 757 294 758 295 static void mpl3115_remove(struct i2c_client *client)
+15 -15
drivers/iio/resolver/ad2s1210.c
··· 1132 1132 { 1133 1133 if (chan->type == IIO_ANGL) { 1134 1134 if (chan->channel == 0) 1135 - return sprintf(label, "position\n"); 1135 + return sysfs_emit(label, "position\n"); 1136 1136 if (chan->channel == 1) 1137 - return sprintf(label, "tracking error\n"); 1137 + return sysfs_emit(label, "tracking error\n"); 1138 1138 } 1139 1139 if (chan->type == IIO_ANGL_VEL) 1140 - return sprintf(label, "velocity\n"); 1140 + return sysfs_emit(label, "velocity\n"); 1141 1141 if (chan->type == IIO_PHASE) 1142 - return sprintf(label, "synthetic reference\n"); 1142 + return sysfs_emit(label, "synthetic reference\n"); 1143 1143 if (chan->type == IIO_ALTVOLTAGE) { 1144 1144 if (chan->output) 1145 - return sprintf(label, "excitation\n"); 1145 + return sysfs_emit(label, "excitation\n"); 1146 1146 if (chan->channel == 0) 1147 - return sprintf(label, "monitor signal\n"); 1147 + return sysfs_emit(label, "monitor signal\n"); 1148 1148 if (chan->channel == 1) 1149 - return sprintf(label, "cosine\n"); 1149 + return sysfs_emit(label, "cosine\n"); 1150 1150 if (chan->channel == 2) 1151 - return sprintf(label, "sine\n"); 1151 + return sysfs_emit(label, "sine\n"); 1152 1152 } 1153 1153 1154 1154 return -EINVAL; ··· 1239 1239 char *label) 1240 1240 { 1241 1241 if (chan->type == IIO_ANGL) 1242 - return sprintf(label, "LOT\n"); 1242 + return sysfs_emit(label, "LOT\n"); 1243 1243 if (chan->type == IIO_ANGL_VEL) 1244 - return sprintf(label, "max tracking rate\n"); 1244 + return sysfs_emit(label, "max tracking rate\n"); 1245 1245 if (chan->type == IIO_PHASE) 1246 - return sprintf(label, "phase lock\n"); 1246 + return sysfs_emit(label, "phase lock\n"); 1247 1247 if (chan->type == IIO_ALTVOLTAGE) { 1248 1248 if (chan->channel == 0) { 1249 1249 if (type == IIO_EV_TYPE_THRESH && 1250 1250 dir == IIO_EV_DIR_FALLING) 1251 - return sprintf(label, "LOS\n"); 1251 + return sysfs_emit(label, "LOS\n"); 1252 1252 if (type == IIO_EV_TYPE_THRESH && 1253 1253 dir == IIO_EV_DIR_RISING) 1254 - return sprintf(label, "DOS overrange\n"); 1254 + return sysfs_emit(label, "DOS overrange\n"); 1255 1255 if (type == IIO_EV_TYPE_MAG) 1256 - return sprintf(label, "DOS mismatch\n"); 1256 + return sysfs_emit(label, "DOS mismatch\n"); 1257 1257 } 1258 1258 if (chan->channel == 1 || chan->channel == 2) 1259 - return sprintf(label, "clipped\n"); 1259 + return sysfs_emit(label, "clipped\n"); 1260 1260 } 1261 1261 1262 1262 return -EINVAL;
+51 -51
drivers/staging/iio/addac/adt7316.c
··· 216 216 struct iio_dev *dev_info = dev_to_iio_dev(dev); 217 217 struct adt7316_chip_info *chip = iio_priv(dev_info); 218 218 219 - return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_EN)); 219 + return sysfs_emit(buf, "%d\n", !!(chip->config1 & ADT7316_EN)); 220 220 } 221 221 222 222 static ssize_t _adt7316_store_enabled(struct adt7316_chip_info *chip, ··· 274 274 if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX) 275 275 return -EPERM; 276 276 277 - return sprintf(buf, "%d\n", !!(chip->config1 & ADT7516_SEL_EX_TEMP)); 277 + return sysfs_emit(buf, "%d\n", !!(chip->config1 & ADT7516_SEL_EX_TEMP)); 278 278 } 279 279 280 280 static ssize_t adt7316_store_select_ex_temp(struct device *dev, ··· 316 316 struct adt7316_chip_info *chip = iio_priv(dev_info); 317 317 318 318 if (chip->config2 & ADT7316_AD_SINGLE_CH_MODE) 319 - return sprintf(buf, "single_channel\n"); 319 + return sysfs_emit(buf, "single_channel\n"); 320 320 321 - return sprintf(buf, "round_robin\n"); 321 + return sysfs_emit(buf, "round_robin\n"); 322 322 } 323 323 324 324 static ssize_t adt7316_store_mode(struct device *dev, ··· 353 353 struct device_attribute *attr, 354 354 char *buf) 355 355 { 356 - return sprintf(buf, "single_channel\nround_robin\n"); 356 + return sysfs_emit(buf, "single_channel\nround_robin\n"); 357 357 } 358 358 359 359 static IIO_DEVICE_ATTR(all_modes, 0444, adt7316_show_all_modes, NULL, 0); ··· 370 370 371 371 switch (chip->config2 & ADT7516_AD_SINGLE_CH_MASK) { 372 372 case ADT7316_AD_SINGLE_CH_VDD: 373 - return sprintf(buf, "0 - VDD\n"); 373 + return sysfs_emit(buf, "0 - VDD\n"); 374 374 case ADT7316_AD_SINGLE_CH_IN: 375 - return sprintf(buf, "1 - Internal Temperature\n"); 375 + return sysfs_emit(buf, "1 - Internal Temperature\n"); 376 376 case ADT7316_AD_SINGLE_CH_EX: 377 377 if (((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) && 378 378 (chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) 379 - return sprintf(buf, "2 - AIN1\n"); 379 + return sysfs_emit(buf, "2 - AIN1\n"); 380 380 381 - return sprintf(buf, "2 - External Temperature\n"); 381 + return sysfs_emit(buf, "2 - External Temperature\n"); 382 382 case ADT7516_AD_SINGLE_CH_AIN2: 383 383 if ((chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) 384 - return sprintf(buf, "3 - AIN2\n"); 384 + return sysfs_emit(buf, "3 - AIN2\n"); 385 385 386 - return sprintf(buf, "N/A\n"); 386 + return sysfs_emit(buf, "N/A\n"); 387 387 case ADT7516_AD_SINGLE_CH_AIN3: 388 388 if (chip->config1 & ADT7516_SEL_AIN3) 389 - return sprintf(buf, "4 - AIN3\n"); 389 + return sysfs_emit(buf, "4 - AIN3\n"); 390 390 391 - return sprintf(buf, "N/A\n"); 391 + return sysfs_emit(buf, "N/A\n"); 392 392 case ADT7516_AD_SINGLE_CH_AIN4: 393 - return sprintf(buf, "5 - AIN4\n"); 393 + return sysfs_emit(buf, "5 - AIN4\n"); 394 394 default: 395 - return sprintf(buf, "N/A\n"); 395 + return sysfs_emit(buf, "N/A\n"); 396 396 } 397 397 } 398 398 ··· 453 453 return -EPERM; 454 454 455 455 if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) 456 - return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n" 456 + return sysfs_emit(buf, "0 - VDD\n1 - Internal Temperature\n" 457 457 "2 - External Temperature or AIN1\n" 458 458 "3 - AIN2\n4 - AIN3\n5 - AIN4\n"); 459 - return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n" 459 + return sysfs_emit(buf, "0 - VDD\n1 - Internal Temperature\n" 460 460 "2 - External Temperature\n"); 461 461 } 462 462 ··· 470 470 struct iio_dev *dev_info = dev_to_iio_dev(dev); 471 471 struct adt7316_chip_info *chip = iio_priv(dev_info); 472 472 473 - return sprintf(buf, "%d\n", 473 + return sysfs_emit(buf, "%d\n", 474 474 !!(chip->config2 & ADT7316_DISABLE_AVERAGING)); 475 475 } 476 476 ··· 509 509 struct iio_dev *dev_info = dev_to_iio_dev(dev); 510 510 struct adt7316_chip_info *chip = iio_priv(dev_info); 511 511 512 - return sprintf(buf, "%d\n", 512 + return sysfs_emit(buf, "%d\n", 513 513 !!(chip->config2 & ADT7316_EN_SMBUS_TIMEOUT)); 514 514 } 515 515 ··· 548 548 struct iio_dev *dev_info = dev_to_iio_dev(dev); 549 549 struct adt7316_chip_info *chip = iio_priv(dev_info); 550 550 551 - return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_PD)); 551 + return sysfs_emit(buf, "%d\n", !!(chip->config1 & ADT7316_PD)); 552 552 } 553 553 554 554 static ssize_t adt7316_store_powerdown(struct device *dev, ··· 586 586 struct iio_dev *dev_info = dev_to_iio_dev(dev); 587 587 struct adt7316_chip_info *chip = iio_priv(dev_info); 588 588 589 - return sprintf(buf, "%d\n", !!(chip->config3 & ADT7316_ADCLK_22_5)); 589 + return sysfs_emit(buf, "%d\n", !!(chip->config3 & ADT7316_ADCLK_22_5)); 590 590 } 591 591 592 592 static ssize_t adt7316_store_fast_ad_clock(struct device *dev, ··· 626 626 627 627 if (chip->config3 & ADT7316_DA_HIGH_RESOLUTION) { 628 628 if (chip->id != ID_ADT7318 && chip->id != ID_ADT7519) 629 - return sprintf(buf, "1 (10 bits)\n"); 629 + return sysfs_emit(buf, "1 (10 bits)\n"); 630 630 } 631 631 632 - return sprintf(buf, "0 (8 bits)\n"); 632 + return sysfs_emit(buf, "0 (8 bits)\n"); 633 633 } 634 634 635 635 static ssize_t adt7316_store_da_high_resolution(struct device *dev, ··· 673 673 if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX) 674 674 return -EPERM; 675 675 676 - return sprintf(buf, "%d\n", 676 + return sysfs_emit(buf, "%d\n", 677 677 !!(chip->config3 & ADT7516_AIN_IN_VREF)); 678 678 } 679 679 ··· 716 716 struct iio_dev *dev_info = dev_to_iio_dev(dev); 717 717 struct adt7316_chip_info *chip = iio_priv(dev_info); 718 718 719 - return sprintf(buf, "%d\n", 719 + return sysfs_emit(buf, "%d\n", 720 720 !!(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)); 721 721 } 722 722 ··· 755 755 struct iio_dev *dev_info = dev_to_iio_dev(dev); 756 756 struct adt7316_chip_info *chip = iio_priv(dev_info); 757 757 758 - return sprintf(buf, "%d\n", 758 + return sysfs_emit(buf, "%d\n", 759 759 !!(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB)); 760 760 } 761 761 ··· 794 794 struct iio_dev *dev_info = dev_to_iio_dev(dev); 795 795 struct adt7316_chip_info *chip = iio_priv(dev_info); 796 796 797 - return sprintf(buf, "0x%x\n", 797 + return sysfs_emit(buf, "0x%x\n", 798 798 chip->dac_config & ADT7316_DA_2VREF_CH_MASK); 799 799 } 800 800 ··· 838 838 struct adt7316_chip_info *chip = iio_priv(dev_info); 839 839 840 840 if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDAC)) 841 - return sprintf(buf, "manual\n"); 841 + return sysfs_emit(buf, "manual\n"); 842 842 843 843 switch (chip->dac_config & ADT7316_DA_EN_MODE_MASK) { 844 844 case ADT7316_DA_EN_MODE_SINGLE: 845 - return sprintf(buf, 845 + return sysfs_emit(buf, 846 846 "0 - auto at any MSB DAC writing\n"); 847 847 case ADT7316_DA_EN_MODE_AB_CD: 848 - return sprintf(buf, 848 + return sysfs_emit(buf, 849 849 "1 - auto at MSB DAC AB and CD writing\n"); 850 850 case ADT7316_DA_EN_MODE_ABCD: 851 - return sprintf(buf, 851 + return sysfs_emit(buf, 852 852 "2 - auto at MSB DAC ABCD writing\n"); 853 853 default: /* ADT7316_DA_EN_MODE_LDAC */ 854 - return sprintf(buf, "3 - manual\n"); 854 + return sysfs_emit(buf, "3 - manual\n"); 855 855 } 856 856 } 857 857 ··· 898 898 struct adt7316_chip_info *chip = iio_priv(dev_info); 899 899 900 900 if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDAC) 901 - return sprintf(buf, "0 - auto at any MSB DAC writing\n" 901 + return sysfs_emit(buf, "0 - auto at any MSB DAC writing\n" 902 902 "1 - auto at MSB DAC AB and CD writing\n" 903 903 "2 - auto at MSB DAC ABCD writing\n" 904 904 "3 - manual\n"); 905 - return sprintf(buf, "manual\n"); 905 + return sysfs_emit(buf, "manual\n"); 906 906 } 907 907 908 908 static IIO_DEVICE_ATTR(all_DAC_update_modes, 0444, ··· 955 955 struct iio_dev *dev_info = dev_to_iio_dev(dev); 956 956 struct adt7316_chip_info *chip = iio_priv(dev_info); 957 957 958 - return sprintf(buf, "%d\n", 958 + return sysfs_emit(buf, "%d\n", 959 959 !!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_AB)); 960 960 } 961 961 ··· 994 994 struct iio_dev *dev_info = dev_to_iio_dev(dev); 995 995 struct adt7316_chip_info *chip = iio_priv(dev_info); 996 996 997 - return sprintf(buf, "%d\n", 997 + return sysfs_emit(buf, "%d\n", 998 998 !!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_CD)); 999 999 } 1000 1000 ··· 1034 1034 struct adt7316_chip_info *chip = iio_priv(dev_info); 1035 1035 1036 1036 if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) 1037 - return sprintf(buf, "0x%x\n", 1037 + return sysfs_emit(buf, "0x%x\n", 1038 1038 (chip->ldac_config & ADT7516_DAC_IN_VREF_MASK) >> 1039 1039 ADT7516_DAC_IN_VREF_OFFSET); 1040 - return sprintf(buf, "%d\n", 1040 + return sysfs_emit(buf, "%d\n", 1041 1041 !!(chip->ldac_config & ADT7316_DAC_IN_VREF)); 1042 1042 } 1043 1043 ··· 1128 1128 1129 1129 data = msb << ADT7316_T_VALUE_FLOAT_OFFSET; 1130 1130 data |= (lsb & ADT7316_LSB_VDD_MASK) >> ADT7316_LSB_VDD_OFFSET; 1131 - return sprintf(buf, "%d\n", data); 1131 + return sysfs_emit(buf, "%d\n", data); 1132 1132 default: /* ex_temp and ain */ 1133 1133 ret = chip->bus.read(chip->bus.client, 1134 1134 ADT7316_LSB_EX_TEMP_AIN, &lsb); ··· 1146 1146 (ADT7316_MSB_EX_TEMP - ADT7316_AD_MSB_DATA_BASE)))); 1147 1147 1148 1148 if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) 1149 - return sprintf(buf, "%d\n", data); 1149 + return sysfs_emit(buf, "%d\n", data); 1150 1150 1151 1151 break; 1152 1152 } ··· 1157 1157 sign = '-'; 1158 1158 } 1159 1159 1160 - return sprintf(buf, "%c%d.%.2d\n", sign, 1160 + return sysfs_emit(buf, "%c%d.%.2d\n", sign, 1161 1161 (data >> ADT7316_T_VALUE_FLOAT_OFFSET), 1162 1162 (data & ADT7316_T_VALUE_FLOAT_MASK) * 25); 1163 1163 } ··· 1247 1247 if (val & 0x80) 1248 1248 data -= 256; 1249 1249 1250 - return sprintf(buf, "%d\n", data); 1250 + return sysfs_emit(buf, "%d\n", data); 1251 1251 } 1252 1252 1253 1253 static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip, ··· 1415 1415 data = lsb >> ADT7316_DA_10_BIT_LSB_SHIFT; 1416 1416 data |= msb << offset; 1417 1417 1418 - return sprintf(buf, "%d\n", data); 1418 + return sysfs_emit(buf, "%d\n", data); 1419 1419 } 1420 1420 1421 1421 static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip, ··· 1568 1568 if (ret) 1569 1569 return -EIO; 1570 1570 1571 - return sprintf(buf, "%d\n", id); 1571 + return sysfs_emit(buf, "%d\n", id); 1572 1572 } 1573 1573 1574 1574 static IIO_DEVICE_ATTR(device_id, 0444, adt7316_show_device_id, NULL, 0); ··· 1586 1586 if (ret) 1587 1587 return -EIO; 1588 1588 1589 - return sprintf(buf, "%d\n", id); 1589 + return sysfs_emit(buf, "%d\n", id); 1590 1590 } 1591 1591 1592 1592 static IIO_DEVICE_ATTR(manufactorer_id, 0444, ··· 1605 1605 if (ret) 1606 1606 return -EIO; 1607 1607 1608 - return sprintf(buf, "%d\n", rev); 1608 + return sysfs_emit(buf, "%d\n", rev); 1609 1609 } 1610 1610 1611 1611 static IIO_DEVICE_ATTR(device_rev, 0444, adt7316_show_device_rev, NULL, 0); ··· 1624 1624 return -EIO; 1625 1625 1626 1626 if (stat) 1627 - return sprintf(buf, "spi\n"); 1627 + return sysfs_emit(buf, "spi\n"); 1628 1628 1629 - return sprintf(buf, "i2c\n"); 1629 + return sysfs_emit(buf, "i2c\n"); 1630 1630 } 1631 1631 1632 1632 static IIO_DEVICE_ATTR(bus_type, 0444, adt7316_show_bus_type, NULL, 0); ··· 1836 1836 struct iio_dev *dev_info = dev_to_iio_dev(dev); 1837 1837 struct adt7316_chip_info *chip = iio_priv(dev_info); 1838 1838 1839 - return sprintf(buf, "0x%x\n", chip->int_mask); 1839 + return sysfs_emit(buf, "0x%x\n", chip->int_mask); 1840 1840 } 1841 1841 1842 1842 /* ··· 1910 1910 data -= 256; 1911 1911 } 1912 1912 1913 - return sprintf(buf, "%d\n", data); 1913 + return sysfs_emit(buf, "%d\n", data); 1914 1914 } 1915 1915 1916 1916 static inline ssize_t adt7316_set_ad_bound(struct device *dev, ··· 1961 1961 struct iio_dev *dev_info = dev_to_iio_dev(dev); 1962 1962 struct adt7316_chip_info *chip = iio_priv(dev_info); 1963 1963 1964 - return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_INT_EN)); 1964 + return sysfs_emit(buf, "%d\n", !!(chip->config1 & ADT7316_INT_EN)); 1965 1965 } 1966 1966 1967 1967 static ssize_t adt7316_set_int_enabled(struct device *dev,
+1 -2
drivers/staging/iio/frequency/ad9834.c
··· 21 21 22 22 #include <linux/iio/iio.h> 23 23 #include <linux/iio/sysfs.h> 24 - #include "dds.h" 25 24 26 - #include "ad9834.h" 25 + #include "dds.h" 27 26 28 27 /* Registers */ 29 28
-10
drivers/staging/iio/frequency/ad9834.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0 */ 2 - /* 3 - * AD9833/AD9834/AD9837/AD9838 SPI DDS driver 4 - * 5 - * Copyright 2010-2011 Analog Devices Inc. 6 - */ 7 - #ifndef IIO_DDS_AD9834_H_ 8 - #define IIO_DDS_AD9834_H_ 9 - 10 - #endif /* IIO_DDS_AD9834_H_ */
+14 -13
include/linux/iio/adc/qcom-vadc-common.h
··· 83 83 /** 84 84 * enum vadc_scale_fn_type - Scaling function to convert ADC code to 85 85 * physical scaled units for the channel. 86 - * SCALE_DEFAULT: Default scaling to convert raw adc code to voltage (uV). 87 - * SCALE_THERM_100K_PULLUP: Returns temperature in millidegC. 86 + * @SCALE_DEFAULT: Default scaling to convert raw adc code to voltage (uV). 87 + * @SCALE_THERM_100K_PULLUP: Returns temperature in millidegC. 88 88 * Uses a mapping table with 100K pullup. 89 - * SCALE_PMIC_THERM: Returns result in milli degree's Centigrade. 90 - * SCALE_XOTHERM: Returns XO thermistor voltage in millidegC. 91 - * SCALE_PMI_CHG_TEMP: Conversion for PMI CHG temp 92 - * SCALE_HW_CALIB_DEFAULT: Default scaling to convert raw adc code to 89 + * @SCALE_PMIC_THERM: Returns result in milli degree's Centigrade. 90 + * @SCALE_XOTHERM: Returns XO thermistor voltage in millidegC. 91 + * @SCALE_PMI_CHG_TEMP: Conversion for PMI CHG temp 92 + * @SCALE_HW_CALIB_DEFAULT: Default scaling to convert raw adc code to 93 93 * voltage (uV) with hardware applied offset/slope values to adc code. 94 - * SCALE_HW_CALIB_THERM_100K_PULLUP: Returns temperature in millidegC using 94 + * @SCALE_HW_CALIB_THERM_100K_PULLUP: Returns temperature in millidegC using 95 95 * lookup table. The hardware applies offset/slope to adc code. 96 - * SCALE_HW_CALIB_XOTHERM: Returns XO thermistor voltage in millidegC using 96 + * @SCALE_HW_CALIB_XOTHERM: Returns XO thermistor voltage in millidegC using 97 97 * 100k pullup. The hardware applies offset/slope to adc code. 98 - * SCALE_HW_CALIB_THERM_100K_PU_PM7: Returns temperature in millidegC using 98 + * @SCALE_HW_CALIB_THERM_100K_PU_PM7: Returns temperature in millidegC using 99 99 * lookup table for PMIC7. The hardware applies offset/slope to adc code. 100 - * SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade. 100 + * @SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade. 101 101 * The hardware applies offset/slope to adc code. 102 - * SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade. 102 + * @SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade. 103 103 * The hardware applies offset/slope to adc code. This is for PMIC7. 104 - * SCALE_HW_CALIB_PM5_CHG_TEMP: Returns result in millidegrees for PMIC5 104 + * @SCALE_HW_CALIB_PM5_CHG_TEMP: Returns result in millidegrees for PMIC5 105 105 * charger temperature. 106 - * SCALE_HW_CALIB_PM5_SMB_TEMP: Returns result in millidegrees for PMIC5 106 + * @SCALE_HW_CALIB_PM5_SMB_TEMP: Returns result in millidegrees for PMIC5 107 107 * SMB1390 temperature. 108 108 */ 109 109 enum vadc_scale_fn_type { ··· 120 120 SCALE_HW_CALIB_PMIC_THERM_PM7, 121 121 SCALE_HW_CALIB_PM5_CHG_TEMP, 122 122 SCALE_HW_CALIB_PM5_SMB_TEMP, 123 + /* private: */ 123 124 SCALE_HW_CALIB_INVALID, 124 125 }; 125 126
+17 -5
include/linux/iio/buffer.h
··· 26 26 * @data: sample data 27 27 * @timestamp: timestamp for the sample data 28 28 * 29 - * Pushes data to the IIO device's buffers. If timestamps are enabled for the 30 - * device the function will store the supplied timestamp as the last element in 31 - * the sample data buffer before pushing it to the device buffers. The sample 32 - * data buffer needs to be large enough to hold the additional timestamp 33 - * (usually the buffer should be indio->scan_bytes bytes large). 29 + * DEPRECATED: Use iio_push_to_buffers_with_ts() instead. 34 30 * 35 31 * Returns 0 on success, a negative error code otherwise. 36 32 */ ··· 41 45 return iio_push_to_buffers(indio_dev, data); 42 46 } 43 47 48 + /** 49 + * iio_push_to_buffers_with_ts() - push data and timestamp to buffers 50 + * @indio_dev: iio_dev structure for device. 51 + * @data: Pointer to sample data buffer. 52 + * @data_total_len: The size of @data in bytes. 53 + * @timestamp: Timestamp for the sample data. 54 + * 55 + * Pushes data to the IIO device's buffers. If timestamps are enabled for the 56 + * device the function will store the supplied timestamp as the last element in 57 + * the sample data buffer before pushing it to the device buffers. The sample 58 + * data buffer needs to be large enough to hold the additional timestamp 59 + * (usually the buffer should be at least indio->scan_bytes bytes large). 60 + * 61 + * Context: Any context. 62 + * Return: 0 on success, a negative error code otherwise. 63 + */ 44 64 static inline int iio_push_to_buffers_with_ts(struct iio_dev *indio_dev, 45 65 void *data, size_t data_total_len, 46 66 s64 timestamp)
+2 -1
include/linux/iio/buffer_impl.h
··· 24 24 25 25 /** 26 26 * struct iio_buffer_access_funcs - access functions for buffers. 27 - * @store_to: actually store stuff to the buffer 27 + * @store_to: actually store stuff to the buffer - must be safe to 28 + * call from any context (e.g. must not sleep). 28 29 * @read: try to get a specified number of bytes (must exist) 29 30 * @data_available: indicates how much data is available for reading from 30 31 * the buffer.
+2 -1
include/linux/iio/consumer.h
··· 131 131 /** 132 132 * iio_channel_get_all_cb() - register callback for triggered capture 133 133 * @dev: Pointer to client device. 134 - * @cb: Callback function. 134 + * @cb: Callback function. Must be safe to call from any context 135 + * (e.g. must not sleep). 135 136 * @private: Private data passed to callback. 136 137 * 137 138 * NB right now we have no ability to mux data from multiple devices.
+36 -9
include/linux/iio/imu/adis.h
··· 57 57 * @enable_irq: Hook for ADIS devices that have a special IRQ enable/disable 58 58 * @unmasked_drdy: True for devices that cannot mask/unmask the data ready pin 59 59 * @has_paging: True if ADIS device has paged registers 60 + * @has_fifo: True if ADIS device has a hardware FIFO 60 61 * @burst_reg_cmd: Register command that triggers burst 61 62 * @burst_len: Burst size in the SPI RX buffer. If @burst_max_len is defined, 62 63 * this should be the minimum size supported by the device. ··· 137 136 const struct adis_data *data; 138 137 unsigned int burst_extra_len; 139 138 const struct adis_ops *ops; 140 - /** 139 + /* 141 140 * The state_lock is meant to be used during operations that require 142 141 * a sequence of SPI R/W in order to protect the SPI transfer 143 142 * information (fields 'xfer', 'msg' & 'current_page') between ··· 167 166 * adis_reset() - Reset the device 168 167 * @adis: The adis device 169 168 * 170 - * Returns 0 on success, a negative error code otherwise 169 + * Returns: %0 on success, a negative error code otherwise 171 170 */ 172 171 static inline int adis_reset(struct adis *adis) 173 172 { ··· 184 183 * __adis_write_reg_8() - Write single byte to a register (unlocked) 185 184 * @adis: The adis device 186 185 * @reg: The address of the register to be written 187 - * @value: The value to write 186 + * @val: The value to write 187 + * 188 + * Returns: %0 on success, a negative error code otherwise 188 189 */ 189 190 static inline int __adis_write_reg_8(struct adis *adis, unsigned int reg, 190 191 u8 val) ··· 198 195 * __adis_write_reg_16() - Write 2 bytes to a pair of registers (unlocked) 199 196 * @adis: The adis device 200 197 * @reg: The address of the lower of the two registers 201 - * @value: Value to be written 198 + * @val: Value to be written 199 + * 200 + * Returns: %0 on success, a negative error code otherwise 202 201 */ 203 202 static inline int __adis_write_reg_16(struct adis *adis, unsigned int reg, 204 203 u16 val) ··· 212 207 * __adis_write_reg_32() - write 4 bytes to four registers (unlocked) 213 208 * @adis: The adis device 214 209 * @reg: The address of the lower of the four register 215 - * @value: Value to be written 210 + * @val: Value to be written 211 + * 212 + * Returns: %0 on success, a negative error code otherwise 216 213 */ 217 214 static inline int __adis_write_reg_32(struct adis *adis, unsigned int reg, 218 215 u32 val) ··· 227 220 * @adis: The adis device 228 221 * @reg: The address of the lower of the two registers 229 222 * @val: The value read back from the device 223 + * 224 + * Returns: %0 on success, a negative error code otherwise 230 225 */ 231 226 static inline int __adis_read_reg_16(struct adis *adis, unsigned int reg, 232 227 u16 *val) ··· 248 239 * @adis: The adis device 249 240 * @reg: The address of the lower of the two registers 250 241 * @val: The value read back from the device 242 + * 243 + * Returns: %0 on success, a negative error code otherwise 251 244 */ 252 245 static inline int __adis_read_reg_32(struct adis *adis, unsigned int reg, 253 246 u32 *val) ··· 268 257 * adis_write_reg() - write N bytes to register 269 258 * @adis: The adis device 270 259 * @reg: The address of the lower of the two registers 271 - * @value: The value to write to device (up to 4 bytes) 260 + * @val: The value to write to device (up to 4 bytes) 272 261 * @size: The size of the @value (in bytes) 262 + * 263 + * Returns: %0 on success, a negative error code otherwise 273 264 */ 274 265 static inline int adis_write_reg(struct adis *adis, unsigned int reg, 275 266 unsigned int val, unsigned int size) ··· 286 273 * @reg: The address of the lower of the two registers 287 274 * @val: The value read back from the device 288 275 * @size: The size of the @val buffer 276 + * 277 + * Returns: %0 on success, a negative error code otherwise 289 278 */ 290 279 static int adis_read_reg(struct adis *adis, unsigned int reg, 291 280 unsigned int *val, unsigned int size) ··· 300 285 * adis_write_reg_8() - Write single byte to a register 301 286 * @adis: The adis device 302 287 * @reg: The address of the register to be written 303 - * @value: The value to write 288 + * @val: The value to write 289 + * 290 + * Returns: %0 on success, a negative error code otherwise 304 291 */ 305 292 static inline int adis_write_reg_8(struct adis *adis, unsigned int reg, 306 293 u8 val) ··· 314 297 * adis_write_reg_16() - Write 2 bytes to a pair of registers 315 298 * @adis: The adis device 316 299 * @reg: The address of the lower of the two registers 317 - * @value: Value to be written 300 + * @val: Value to be written 301 + * 302 + * Returns: %0 on success, a negative error code otherwise 318 303 */ 319 304 static inline int adis_write_reg_16(struct adis *adis, unsigned int reg, 320 305 u16 val) ··· 328 309 * adis_write_reg_32() - write 4 bytes to four registers 329 310 * @adis: The adis device 330 311 * @reg: The address of the lower of the four register 331 - * @value: Value to be written 312 + * @val: Value to be written 313 + * 314 + * Returns: %0 on success, a negative error code otherwise 332 315 */ 333 316 static inline int adis_write_reg_32(struct adis *adis, unsigned int reg, 334 317 u32 val) ··· 343 322 * @adis: The adis device 344 323 * @reg: The address of the lower of the two registers 345 324 * @val: The value read back from the device 325 + * 326 + * Returns: %0 on success, a negative error code otherwise 346 327 */ 347 328 static inline int adis_read_reg_16(struct adis *adis, unsigned int reg, 348 329 u16 *val) ··· 364 341 * @adis: The adis device 365 342 * @reg: The address of the lower of the two registers 366 343 * @val: The value read back from the device 344 + * 345 + * Returns: %0 on success, a negative error code otherwise 367 346 */ 368 347 static inline int adis_read_reg_32(struct adis *adis, unsigned int reg, 369 348 u32 *val) ··· 391 366 * @size: Size of the register to update 392 367 * 393 368 * Updates the desired bits of @reg in accordance with @mask and @val. 369 + * 370 + * Returns: %0 on success, a negative error code otherwise 394 371 */ 395 372 static inline int adis_update_bits_base(struct adis *adis, unsigned int reg, 396 373 const u32 mask, const u32 val, u8 size)