IIO: 1st set of device support, features and cleanup for 7.4

2 merges
 - v7.3-rc4 to get a x86 build fix needed by the ad9910 driver.
 - devm_notifier_chain_register to pick up the IIO specific users of this
   new infrastructure.
 
 New device support
 ------------------
 
 Major refactors or new drivers needed:
 
 adi,ad3530r
 - Support for the AD5710R and AD5711R 8 channel IDAC / VDAC parts.
   Needed substantial driver rework to support channel type controls.
 adi,ad5529r
 - New driver for this 16 channel DAC with 12 and 16 bit variants.
 adi,ad7768
 - New driver for the 8 (AD7768) and 4 (AD7768-4) channel variants of this
   24-bit simultaneous sampling ADC family. They are very different from
   the 1 channel variant that has as separate driver.
 adi,ad9910
 - New driver for this DDS (Direct Digital Synthesizer). This was a large
   undertaking is it is a complex chip requiring quite a lot of new IIO ABI.
   Delayed from last cycle by an x86 bug that was fixed in rc4.
 adi,ade9000
 - Add support for the ADE9078 polyphase energy metering device.
   Required significant changes to introduce multiple part support into
   this driver.
 adi,adis16201
 - Add support for the ADIS16203 device, replacing the driver in staging.
 axiado,saradc
 - New driver for the SARADC found on the AX3000 and ADX3005 SoCs.
 liteon,ltr501
 - Add support for the LTR-329ALS-01 ambient light sensor. Included
   various bits of driver modernization.
 microchip,mcp48fev02
 - Split previously I2C specific mcp47feb02 into core and I2C specific
   parts.
 - Add an SPI specific part for the many parts in the MCP48FxBy1/2/4/8
   series of SPI DACS 24 different part numbers covering:
   - 8, 10 and 12 bit resolutions
   - 1, 2, 4, and 8 channels
   - EEPROM and no non volatile storage variants.
 - Substantial driver modification and cleanup was needed prior to the new
   support.
 maxim,max40080
 - New driver for this current-sense amplifier with integrated ADC.
 renesas,rzg2l_adc
 - Support the RZ/G3L ADC 1 that is dedicate to the on-chip thermal
   sensor unit. The thermal parts of this support will be going through
   that tree.
 sensortek,stk3310
 - Add support for the STK36C61 Ambient Light, proximity and RGB color
   sensor. Handling had to be added for RGB elements and the driver in
   general had to be made ready for support multiple parts.
 ti,ads1100
 - Add support for the ADS1110 with faster data rate and 2.048V reference.
 ti,ads112c04
 - New driver to support this 16bit sigma-delta ADC.
 vishay,veml6031x00
 - New driver for this ambient light sensor that was built in in stages.
 - Add triggered buffer data capture.
 - Add support for events and triggers.
 - Enable mysterious 'internal calibration' setting.
 
 Minor additions such as IDs, compatibles or device specific data.
 
 adi,ad3530r
 - Support the AD3536R which is low resolution equivalent of the already
   supported AD3532R.
 adi,ad4080
 - Support the AD4885 - only needed chip specific data.
 aosong,am2315
 - Add support for the AM2320, fully compatible wth the AM2315.
 invensense,icm42600
 - Minor tweaks + addition of compatible for the ICM42630 IMU.
 mediatek,mt2701-adc
 - Compatible for the MT6572
 rockchip,saradc
 - Support the RV1106.
 
 Features
 --------
 
 IIO Core
 - Add a helper to discover if timestamps are enabled.  In a few cases
   (typically when there is batching involved) we may have to refuse
   to start the buffer if timestamps are enabled.  Provided a helper
   to allow that to be queried.
 IIO backend
 - CRC support.
 infineon,dps310
 - Add triggered buffer support.
 linear,ltc2497
 - Add 2x conversion speed mode.
 - Add the internal temperature channel.
 renesas,r9a09g077
 - Add missing DMA properties to DT and enable use of DMA
 - Expose the sampling frequency as per channel attributes.
 ti,ad1015
 - Add per channel labels from DT support.
 ti,ads112c14
 - Add dataready trigger using continuous mode if only one channel is
   enabled.
 - Add burnout current control including new IIO ABI.
 - Add filter control.
 - Add new ABI for settling time.
 
 Cleanup and minor or late breaking fixes
 ----------------------------------------
 
 Only calling out the more significant changes or ones that were carried
 on out on several drivers.
 
 multiple drivers
 - Add sanity check for spi_device_get_match_data() returning NULL due
   to use of driver_override.
 - Add some useful __counted_by_ptr markings.
 - Add some missing MODULE_DEVICE_TABLE() calls.
 - Use dmaenginge_get_dma_device() instead of chan->device->dev
 - A few precursor cleanups for planed devm_ object allocators.
 - Disable autosuspend on exit.  Note there is work ongoing to make
   this unnecessary.
 - Header reorders and IWYU being applied to what was included.
 - Use devm_blocking_notifier_chain_register() to replace open coded
   equivalent.
 - Ensure some clk related structures are always fully initialized.
 - Use the size checked iio_push_to_buffers_with_ts() replacement for
   iio_push_to_buffers_with_timestamp().
 - Avoid shadowing various error codes from store() callbacks.
 adi,axi-adc
 - Fix missing mutex_init()
 adi,ad4080
 - Ensure autoincrement is set for multi register reads.
 adi,ad5758
 - Fix wrong offset calculation
 - Reject out of range values rather than truncating values.
 - Make sure buffer used for bulk acceses is DMA safe.
 adi,ad7816
 - Local lock to protect state by serializing accesses. A few extra locations
   were added much later in the cycle.
 - Stop using non DMA safe buffers by using spi_write_then_read()
   to ensure the data was bounce buffered.
 adi,adxl367
 - Ensure interrupt mapping is resolved before device setup reducing work
   done before potential deferral.
 - Support INT2 pin.
 asahi-kasei,ak8975
 - Use BIT() and GENMASK() to improve readability of defines.
 - Add an enum for scan mask elements.
 - Switch to devm_ for all resources.
 avago,apds9306
 - Fix the default sampling frequency.
 awinc,aw96103
 - Fix an early return that stopped all channels being checked.
 broadcom,iproc-adc
 - General modernization and conversion to devm managed cleanup.
 - Use dev_err_probe(), local dev pointer and drop some duplicate error
   messages.
 capella,cm32181
 - Add device specific dt-binding as trivial-devices doesn't provide
   vdd-supply or interrupt properties.
 freescale,mma8452
 - Modernize driver via guard(), IIO specific cleanup helpers and
   bulk regulator handling.
 infineon,dps310
 - Add context analysis lock markings.
 - Single local acquire / release per raw read.
 - Replace opencoded get_unaligned_be24().
 - Fix incorrect CFG_REG bit definitions.
 invensense,icm42600
 - Ensure ODR is updated when switching power mode to paper over a hardware
   bug.
 - Fix detecting ODR change in invalid data packets.
 - Optimize high frequency data readback by not bothering to read the
   FIFO count when the watermark is known to have been passed.
 - Various other minor fixes.
 isil,isl29028
 - Fix a runtime pm reference leak.
 liteon,ltr501
 - Make the dt-binding property proximit-near-level only available
   on parts that support it.
 kionix,kx022a
 - Use as structure to make the channel layout explicit and use that for
   all cases (previously there were two similar buffers).
 pulsed-light,lidar-lite-v2
 - Move binding from trivial-devices to it's own file as there are power
   enable and mode control pins that needs describing.
 renesas,r9a09g077
 - Drop some interrupt descriptions for interrupts that aren't connected to
   the interrupt controller.
 - Avoid direct reads when buffer enabled.
 - Store the device PA and IRQ in state ready for the DMA support.
 st,hts221
 - Fix a potential division by zero if calibration data corrupted.
 - Allow an unknown Who Am I value to support fallback dt-compatibles.
 - Replace opencoded oversampling_ration_available handling with read_avail
   callback.
 st,stm32-adc
 - Fix up some wrong minimum sample times.
 ti,ads1100
 - Fix readings after datarate change by ensuring a long enough wait for
   a new sample.
 ti,tmp117
 - Fix case where cached state was updated before we know if the write
   to the device succeeds.
 vishay,veml3328
 - Reshape the scale array to improve readability as it is made up
   of value pairs.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAmq9ST4RHGppYzIzQGtl
 cm5lbC5vcmcACgkQVIU0mcT0Fojejg//aLduUK/4A7hGN1zEg5nK8mZtrf0IpAxO
 WbTDo5GwF5PIEYoAojLcweGi/dwuRpqVOml9qsmF4wu1aGqP3/GoRUfW7OIPkSZ9
 E5i+k73k9f9wtZgzAOdR6dkM/iKe8Yc5ZqS+zkV5mB/EsXvLEH//ZiLt8IEZDe+w
 OIlRVViTq6dLo1fNrX/upIpr0XCh1eubq+esyFKu2ax00Ym8+um2rfuF/KRrtzie
 3jGOlYmDPjJNMuc90VoiZHU4mK+o1UHtk85QUSP/MJQPnE9HBE1aL0WwInmrztBn
 QN+dQ/yoOQRY1k3O2a8XmzLVy1KW6kXeTy7wtX0HHTzuphw0cIJ8pIG6NKqPAMpx
 FOv9z142KlHl0KIg6O+Cw+C3hGi7PmZpCeMzSxXfznBxECN+o4vSFolTFVw11zjx
 q7JHINUBsckIAF4zPtnGUiAyRti2KUU0yTszbMD2VuSImrf/JhuC8Dh5qGrzCcV4
 zsO3b+RRbv0J8FnNdkJqMd2fR932dR+eKa9GsWU7Leiye3H4BTPXpuP/+dC3AH5m
 1e4tEfA8XXcc6Y5xTRpn+wg0ETro46LvkorW5E5nmvgc/CAlVHBP+2dhcGwl5Vpr
 v9RKqqxvkxmtzPDUwprclf2rqesZ9/7pdNQLpMRBaAvyoq2iuScRrbuIXsno1is1
 xXcKBhGr1hA=
 =x//G
 -----END PGP SIGNATURE-----

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

Jonathan writes:

IIO: 1st set of device support, features and cleanup for 7.4

2 merges
- v7.3-rc4 to get a x86 build fix needed by the ad9910 driver.
- devm_notifier_chain_register to pick up the IIO specific users of this
  new infrastructure.

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

Major refactors or new drivers needed:

adi,ad3530r
- Support for the AD5710R and AD5711R 8 channel IDAC / VDAC parts.
  Needed substantial driver rework to support channel type controls.
adi,ad5529r
- New driver for this 16 channel DAC with 12 and 16 bit variants.
adi,ad7768
- New driver for the 8 (AD7768) and 4 (AD7768-4) channel variants of this
  24-bit simultaneous sampling ADC family. They are very different from
  the 1 channel variant that has as separate driver.
adi,ad9910
- New driver for this DDS (Direct Digital Synthesizer). This was a large
  undertaking is it is a complex chip requiring quite a lot of new IIO ABI.
  Delayed from last cycle by an x86 bug that was fixed in rc4.
adi,ade9000
- Add support for the ADE9078 polyphase energy metering device.
  Required significant changes to introduce multiple part support into
  this driver.
adi,adis16201
- Add support for the ADIS16203 device, replacing the driver in staging.
axiado,saradc
- New driver for the SARADC found on the AX3000 and ADX3005 SoCs.
liteon,ltr501
- Add support for the LTR-329ALS-01 ambient light sensor. Included
  various bits of driver modernization.
microchip,mcp48fev02
- Split previously I2C specific mcp47feb02 into core and I2C specific
  parts.
- Add an SPI specific part for the many parts in the MCP48FxBy1/2/4/8
  series of SPI DACS 24 different part numbers covering:
  - 8, 10 and 12 bit resolutions
  - 1, 2, 4, and 8 channels
  - EEPROM and no non volatile storage variants.
- Substantial driver modification and cleanup was needed prior to the new
  support.
maxim,max40080
- New driver for this current-sense amplifier with integrated ADC.
renesas,rzg2l_adc
- Support the RZ/G3L ADC 1 that is dedicate to the on-chip thermal
  sensor unit. The thermal parts of this support will be going through
  that tree.
sensortek,stk3310
- Add support for the STK36C61 Ambient Light, proximity and RGB color
  sensor. Handling had to be added for RGB elements and the driver in
  general had to be made ready for support multiple parts.
ti,ads1100
- Add support for the ADS1110 with faster data rate and 2.048V reference.
ti,ads112c04
- New driver to support this 16bit sigma-delta ADC.
vishay,veml6031x00
- New driver for this ambient light sensor that was built in in stages.
- Add triggered buffer data capture.
- Add support for events and triggers.
- Enable mysterious 'internal calibration' setting.

Minor additions such as IDs, compatibles or device specific data.

adi,ad3530r
- Support the AD3536R which is low resolution equivalent of the already
  supported AD3532R.
adi,ad4080
- Support the AD4885 - only needed chip specific data.
aosong,am2315
- Add support for the AM2320, fully compatible wth the AM2315.
invensense,icm42600
- Minor tweaks + addition of compatible for the ICM42630 IMU.
mediatek,mt2701-adc
- Compatible for the MT6572
rockchip,saradc
- Support the RV1106.

Features
--------

IIO Core
- Add a helper to discover if timestamps are enabled.  In a few cases
  (typically when there is batching involved) we may have to refuse
  to start the buffer if timestamps are enabled.  Provided a helper
  to allow that to be queried.
IIO backend
- CRC support.
infineon,dps310
- Add triggered buffer support.
linear,ltc2497
- Add 2x conversion speed mode.
- Add the internal temperature channel.
renesas,r9a09g077
- Add missing DMA properties to DT and enable use of DMA
- Expose the sampling frequency as per channel attributes.
ti,ad1015
- Add per channel labels from DT support.
ti,ads112c14
- Add dataready trigger using continuous mode if only one channel is
  enabled.
- Add burnout current control including new IIO ABI.
- Add filter control.
- Add new ABI for settling time.

Cleanup and minor or late breaking fixes
----------------------------------------

Only calling out the more significant changes or ones that were carried
on out on several drivers.

multiple drivers
- Add sanity check for spi_device_get_match_data() returning NULL due
  to use of driver_override.
- Add some useful __counted_by_ptr markings.
- Add some missing MODULE_DEVICE_TABLE() calls.
- Use dmaenginge_get_dma_device() instead of chan->device->dev
- A few precursor cleanups for planed devm_ object allocators.
- Disable autosuspend on exit.  Note there is work ongoing to make
  this unnecessary.
- Header reorders and IWYU being applied to what was included.
- Use devm_blocking_notifier_chain_register() to replace open coded
  equivalent.
- Ensure some clk related structures are always fully initialized.
- Use the size checked iio_push_to_buffers_with_ts() replacement for
  iio_push_to_buffers_with_timestamp().
- Avoid shadowing various error codes from store() callbacks.
adi,axi-adc
- Fix missing mutex_init()
adi,ad4080
- Ensure autoincrement is set for multi register reads.
adi,ad5758
- Fix wrong offset calculation
- Reject out of range values rather than truncating values.
- Make sure buffer used for bulk acceses is DMA safe.
adi,ad7816
- Local lock to protect state by serializing accesses. A few extra locations
  were added much later in the cycle.
- Stop using non DMA safe buffers by using spi_write_then_read()
  to ensure the data was bounce buffered.
adi,adxl367
- Ensure interrupt mapping is resolved before device setup reducing work
  done before potential deferral.
- Support INT2 pin.
asahi-kasei,ak8975
- Use BIT() and GENMASK() to improve readability of defines.
- Add an enum for scan mask elements.
- Switch to devm_ for all resources.
avago,apds9306
- Fix the default sampling frequency.
awinc,aw96103
- Fix an early return that stopped all channels being checked.
broadcom,iproc-adc
- General modernization and conversion to devm managed cleanup.
- Use dev_err_probe(), local dev pointer and drop some duplicate error
  messages.
capella,cm32181
- Add device specific dt-binding as trivial-devices doesn't provide
  vdd-supply or interrupt properties.
freescale,mma8452
- Modernize driver via guard(), IIO specific cleanup helpers and
  bulk regulator handling.
infineon,dps310
- Add context analysis lock markings.
- Single local acquire / release per raw read.
- Replace opencoded get_unaligned_be24().
- Fix incorrect CFG_REG bit definitions.
invensense,icm42600
- Ensure ODR is updated when switching power mode to paper over a hardware
  bug.
- Fix detecting ODR change in invalid data packets.
- Optimize high frequency data readback by not bothering to read the
  FIFO count when the watermark is known to have been passed.
- Various other minor fixes.
isil,isl29028
- Fix a runtime pm reference leak.
liteon,ltr501
- Make the dt-binding property proximit-near-level only available
  on parts that support it.
kionix,kx022a
- Use as structure to make the channel layout explicit and use that for
  all cases (previously there were two similar buffers).
pulsed-light,lidar-lite-v2
- Move binding from trivial-devices to it's own file as there are power
  enable and mode control pins that needs describing.
renesas,r9a09g077
- Drop some interrupt descriptions for interrupts that aren't connected to
  the interrupt controller.
- Avoid direct reads when buffer enabled.
- Store the device PA and IRQ in state ready for the DMA support.
st,hts221
- Fix a potential division by zero if calibration data corrupted.
- Allow an unknown Who Am I value to support fallback dt-compatibles.
- Replace opencoded oversampling_ration_available handling with read_avail
  callback.
st,stm32-adc
- Fix up some wrong minimum sample times.
ti,ads1100
- Fix readings after datarate change by ensuring a long enough wait for
  a new sample.
ti,tmp117
- Fix case where cached state was updated before we know if the write
  to the device succeeds.
vishay,veml3328
- Reshape the scale array to improve readability as it is made up
  of value pairs.

* tag 'iio-for-7.4a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (270 commits)
  iio: dac: ad5758: Fix the offset calculation
  iio: dac: ad5758: Reject out-of-range raw values
  iio: dac: ad5758: Fix alignment for DMA safety
  iio: pressure: dps310: check the lock markings with context analysis
  iio: core: add an accessor for scan_timestamp
  iio: pressure: dps310: add triggered buffer support
  iio: pressure: dps310: take the lock once per raw read
  iio: pressure: dps310: use get_unaligned_be24() for the 24-bit results
  iio: pressure: dps310: use a local device pointer in probe
  iio: pressure: dps310: fix CFG_REG bit definitions
  staging: iio: adc: ad7816: Protect sysfs attributes with mutex
  dt-bindings: iio: Add dedicated CM32181 schema
  iio: adc: stm32: fix minimum sampling time values
  iio: light: veml6031x00: Enable internal calibration
  iio: dac: add support for Microchip MCP48FEB02
  dt-bindings: iio: dac: add support for MCP48FEB02 SPI
  iio: dac: mcp47feb02: refactor MCP47FEB02 I2C driver into two modules
  iio: dac: mcp47feb02: protect EEPROM store sequence with mutex
  iio: dac: mcp47feb02: Avoid unjustified probe error on missing label
  iio: adc: rzg2l_adc: Add RZ/G3L ADC support for TSU
  ...
This commit is contained in:
Greg Kroah-Hartman 2026-10-01 13:34:38 +02:00
commit 2670329311
221 changed files with 16052 additions and 2228 deletions

View File

@ -0,0 +1,23 @@
What: /sys/kernel/debug/iio/iio:deviceX/frequency_source
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Read-only. Reports the channel label that is read from the
<dir>_<type>[Y]_label attribute, which corresponds to the on-chip
signal generator that is currently driving the output frequency.
What: /sys/kernel/debug/iio/iio:deviceX/phase_source
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Read-only. Reports the channel label that is read from the
<dir>_<type>[Y]_label attribute, which corresponds to the on-chip
signal generator that is currently driving the output phase.
What: /sys/kernel/debug/iio/iio:deviceX/amplitude_source
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Read-only. Reports the channel label that is read from the
<dir>_<type>[Y]_label attribute, which corresponds to the on-chip
signal generator that is currently driving the output amplitude.

View File

@ -8,13 +8,13 @@ What: /sys/kernel/debug/iio/iio:deviceX/backendY/direct_reg_access
KernelVersion: 6.11
Contact: linux-iio@vger.kernel.org
Description:
Directly access the registers of backend Y. Typical usage is:
Directly access the registers of backend Y. Typical usage is::
Reading address 0x50
echo 0x50 > direct_reg_access
cat direct_reg_access
# Reading address 0x50
echo 0x50 > direct_reg_access
cat direct_reg_access
Writing address 0x50
echo 0x50 0x3 > direct_reg_access
//readback address 0x50
cat direct_reg_access
# Writing address 0x50
echo 0x50 0x3 > direct_reg_access
# readback address 0x50
cat direct_reg_access

View File

@ -442,6 +442,14 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_i_offset
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_q_offset
What: /sys/bus/iio/devices/iio:deviceX/in_currentY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_current_offset
What: /sys/bus/iio/devices/iio:deviceX/in_phaseY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_phase_offset
What: /sys/bus/iio/devices/iio:deviceX/out_phaseY_offset
What: /sys/bus/iio/devices/iio:deviceX/out_phase_offset
What: /sys/bus/iio/devices/iio:deviceX/in_frequencyY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_frequency_offset
What: /sys/bus/iio/devices/iio:deviceX/out_frequencyY_offset
What: /sys/bus/iio/devices/iio:deviceX/out_frequency_offset
What: /sys/bus/iio/devices/iio:deviceX/in_tempY_offset
What: /sys/bus/iio/devices/iio:deviceX/in_temp_offset
What: /sys/bus/iio/devices/iio:deviceX/in_pressureY_offset
@ -475,10 +483,22 @@ What: /sys/bus/iio/devices/iio:deviceX/in_voltage_scale
What: /sys/bus/iio/devices/iio:deviceX/in_voltage-voltage_scale
What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_scale
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_phaseY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_phase_scale
What: /sys/bus/iio/devices/iio:deviceX/out_phaseY_scale
What: /sys/bus/iio/devices/iio:deviceX/out_phase_scale
What: /sys/bus/iio/devices/iio:deviceX/in_frequencyY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_frequency_scale
What: /sys/bus/iio/devices/iio:deviceX/out_frequencyY_scale
What: /sys/bus/iio/devices/iio:deviceX/out_frequency_scale
What: /sys/bus/iio/devices/iio:deviceX/in_currentY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_currentY_supply_scale
What: /sys/bus/iio/devices/iio:deviceX/in_current_scale
What: /sys/bus/iio/devices/iio:deviceX/in_current_q_scale
What: /sys/bus/iio/devices/iio:deviceX/in_altcurrentY_scale
What: /sys/bus/iio/devices/iio:deviceX/in_altcurrent_scale
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_scale
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrent_scale
What: /sys/bus/iio/devices/iio:deviceX/in_accel_scale
What: /sys/bus/iio/devices/iio:deviceX/in_accel_peak_scale
What: /sys/bus/iio/devices/iio:deviceX/in_anglvel_scale
@ -507,6 +527,7 @@ What: /sys/bus/iio/devices/iio:deviceX/in_intensity_z_scale
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_red_scale
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_green_scale
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_blue_scale
What: /sys/bus/iio/devices/iio:deviceX/in_intensity_clear_scale
What: /sys/bus/iio/devices/iio:deviceX/in_concentration_co2_scale
What: /sys/bus/iio/devices/iio:deviceX/in_volumeflow_scale
What: /sys/bus/iio/devices/iio:deviceX/in_volumeflowY_scale
@ -762,6 +783,8 @@ What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown_mode
What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown_mode
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown_mode
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown_mode
What: /sys/bus/iio/devices/iio:deviceX/out_currentY_powerdown_mode
What: /sys/bus/iio/devices/iio:deviceX/out_current_powerdown_mode
KernelVersion: 2.6.38
Contact: linux-iio@vger.kernel.org
Description:
@ -774,6 +797,7 @@ Description:
6kohm_to_gnd: connected to ground via a 6kOhm resistor,
7.7kohm_to_gnd: connected to ground via a 7.7kOhm resistor,
10kohm_to_gnd: connected to ground via a 10kOhm resistor,
15kohm_to_gnd: connected to ground via a 15kOhm resistor,
16kohm_to_gnd: connected to ground via a 16kOhm resistor,
20kohm_to_gnd: connected to ground via a 20kOhm resistor,
32kohm_to_gnd: connected to ground via a 32kOhm resistor,
@ -802,6 +826,10 @@ What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_voltage_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltage_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_currentY_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_current_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_powerdown
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrent_powerdown
KernelVersion: 2.6.38
Contact: linux-iio@vger.kernel.org
Description:
@ -812,6 +840,7 @@ Description:
together.
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_frequency
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_frequency
KernelVersion: 3.4.0
Contact: linux-iio@vger.kernel.org
Description:
@ -838,8 +867,10 @@ Description:
all the other channels, since it involves changing the VCO
fundamental output frequency.
What: /sys/bus/iio/devices/iio:deviceX/in_altcurrentY_phase
What: /sys/bus/iio/devices/iio:deviceX/in_altvoltageY_i_phase
What: /sys/bus/iio/devices/iio:deviceX/in_altvoltageY_q_phase
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_phase
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_phase
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_i_phase
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_q_phase
@ -853,6 +884,7 @@ Description:
channel.
What: /sys/bus/iio/devices/iio:deviceX/out_currentY_raw
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_raw
Date: May 2012
KernelVersion: 3.5
Contact: Johan Hovold <jhovold@gmail.com>
@ -1739,6 +1771,7 @@ Description:
What: /sys/bus/iio/devices/iio:deviceX/in_currentY_raw
What: /sys/bus/iio/devices/iio:deviceX/in_currentY_supply_raw
What: /sys/bus/iio/devices/iio:deviceX/in_altcurrentY_raw
KernelVersion: 3.17
Contact: linux-iio@vger.kernel.org
Description:
@ -2129,7 +2162,9 @@ Description:
Raw counter device counters direction for channel Y.
What: /sys/bus/iio/devices/iio:deviceX/in_altcurrentY_label
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_label
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_label
What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_label
KernelVersion: 5.8
Contact: linux-iio@vger.kernel.org
@ -2139,6 +2174,50 @@ Description:
specific attributes. This is useful for userspace to be able to
better identify an individual channel.
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_parent
What: /sys/bus/iio/devices/iio:deviceX/out_voltageY_parent
What: /sys/bus/iio/devices/iio:deviceX/in_altvoltageY_parent
What: /sys/bus/iio/devices/iio:deviceX/out_altvoltageY_parent
What: /sys/bus/iio/devices/iio:deviceX/in_currentY_parent
What: /sys/bus/iio/devices/iio:deviceX/out_currentY_parent
What: /sys/bus/iio/devices/iio:deviceX/in_altcurrentY_parent
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_parent
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Read-only attribute containing the sysfs name prefix of the parent
channel for hierarchical channel relationships (e.g. "out_altvoltage0").
The prefix uniquely identifies the parent channel and can be used by
userspace to organize channels in tree-like structures that reflects
virtual or logical relationships between them.
For example, an IIO device may expose a primary output channel as
"out_voltage0" together with a set of profile-based or mode-based
subchannels used to configure or compose the output signal. These
subchannels may carry common attributes such as frequency, phase, etc.
They do not represent physical outputs, but rather logical/virtual
channels grouping configurations that affect the primary output.
Each subchannel exposes a <dir>_<type>[Y]_parent attribute reading
"out_voltage0", allowing userspace to group controls under the output
channel they belong to rather than treating them as unrelated top-level
channels.
What: /sys/bus/iio/devices/iio:deviceX/in_frequencyY_raw
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Raw (unscaled) frequency reading from channel Y.
Units after application of scale and offset are Hz.
What: /sys/bus/iio/devices/iio:deviceX/out_frequencyY_raw
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Raw (unscaled, no bias etc.) output frequency for channel Y.
The number must always be specified and unique if the output
corresponds to a single channel. Units after application of
scale and offset are Hz.
What: /sys/bus/iio/devices/iio:deviceX/in_phaseY_raw
KernelVersion: 4.18
Contact: linux-iio@vger.kernel.org
@ -2146,6 +2225,15 @@ Description:
Raw (unscaled) phase difference reading from channel Y.
Units after application of scale and offset are radians.
What: /sys/bus/iio/devices/iio:deviceX/out_phaseY_raw
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Raw (unscaled, no bias etc.) output phase for channel Y.
The number must always be specified and unique if the output
corresponds to a single channel. Units after application of
scale and offset are radians.
What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm1_input
What: /sys/bus/iio/devices/iio:deviceX/in_massconcentrationY_pm1_input
What: /sys/bus/iio/devices/iio:deviceX/in_massconcentration_pm2p5_input
@ -2380,6 +2468,7 @@ Description:
* "sinc4+lp" - Sinc4 + Low Pass Filter.
* "sinc4+sinc1" - Sinc4 + averaging by 8. Low 1st conversion
time.
* "sinc4+sinc1+pf1" - Sinc4 + Sinc1 + device specific Post Filter 1.
* "sinc4+rej60" - Sinc4 + 60Hz rejection.
* "sinc5" - The digital sinc5 filter. Excellent noise
performance
@ -2401,6 +2490,32 @@ Description:
Specifies which filter type apply to the channel. The possible
values are given by the filter_type_available attribute.
What: /sys/bus/iio/devices/iio:deviceX/in_resistanceY_settlingtime
What: /sys/bus/iio/devices/iio:deviceX/in_tempY_settlingtime
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_settlingtime
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_settlingtime
KernelVersion: 7.4
Contact: linux-iio@vger.kernel.org
Description:
Set/read total settling time in seconds for a device to settle
after starting the first conversion after any settings have
changed. The data for the conversion is outputted at the end of
this time.
Depending on the device and how it is used, this settling time
may apply to more than just the first conversion, e.g. to every
conversion in a single-shot conversion mode or when a device
setting changes after each conversion (input chopping).
What: /sys/bus/iio/devices/iio:deviceX/in_resistanceY_settlingtime_available
What: /sys/bus/iio/devices/iio:deviceX/in_tempY_settlingtime_available
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_settlingtime_available
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_settlingtime_available
KernelVersion: 7.4
Contact: linux-iio@vger.kernel.org
Description:
Available settlingtime values in IIO range or list format.
What: /sys/.../events/in_proximity_thresh_either_runningperiod
KernelVersion: 6.6
Contact: linux-iio@vger.kernel.org

View File

@ -0,0 +1,9 @@
What: /sys/bus/iio/devices/iio:deviceX/in_resistanceY_burnoutraw
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY_burnoutraw
What: /sys/bus/iio/devices/iio:deviceX/in_voltageY-voltageZ_burnoutraw
KernelVersion: 7.4
Contact: linux-iio@vger.kernel.org
Description:
Raw value from channel Y read using a single conversion with
the channel burnout current enabled. This is typically used
for diagnostic purposes to detect an open or shorted input.

View File

@ -0,0 +1,31 @@
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_dwell_en
What: /sys/bus/iio/devices/iio:deviceX/out_frequencyY_dwell_en
What: /sys/bus/iio/devices/iio:deviceX/out_phaseY_dwell_en
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
For a channel that produces parametric sweeps, this attribute controls
the sweep behavior at the configured limit. It enables dwell mode at a
sweep limit when set to 1, i.e., after the sweep is complete the output
value stays at the limit. Otherwise (setting this value to 0), the sweep
may stop or restart from the initial position, or even continue by
reversing the sweep direction.
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_raw_roc
What: /sys/bus/iio/devices/iio:deviceX/out_frequencyY_raw_roc
What: /sys/bus/iio/devices/iio:deviceX/out_phaseY_raw_roc
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
For a channel that produces parametric sweeps, this attribute controls
the rate of change of the parameter in raw units per second (slope).
This value may be influenced by the channel sampling_frequency attribute
if available. Multiplying this value by the scale attribute of the
channel yields the rate of change in physical units per second.
What: /sys/bus/iio/devices/iio:deviceX/out_altcurrentY_raw_roc_available
KernelVersion: 7.3
Contact: linux-iio@vger.kernel.org
Description:
Lists the available roc values for the channel. Values are
space-separated in ascending order.

View File

@ -4,21 +4,23 @@
$id: http://devicetree.org/schemas/iio/accel/adi,adis16201.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ADIS16201 Dual Axis Inclinometer and similar
title: ADIS16201 Inclinometer and similar
maintainers:
- Jonathan Cameron <Jonathan.Cameron@huawei.com>
description: |
Two similar parts from external interface point of view.
Three similar parts from external interface point of view.
SPI interface.
https://www.analog.com/en/products/adis16201.html
https://www.analog.com/en/products/adis16203.html
https://www.analog.com/en/products/adis16209.html
properties:
compatible:
enum:
- adi,adis16201
- adi,adis16203
- adi,adis16209
reg:

View File

@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices ADXL367 3-Axis Digital Accelerometer
maintainers:
- Cosmin Tanislav <cosmin.tanislav@analog.com>
- Antoniu Miclaus <antoniu.miclaus@analog.com>
description: |
The ADXL367 is an ultralow power, 3-axis MEMS accelerometer.
@ -33,7 +33,14 @@ properties:
maxItems: 1
interrupts:
maxItems: 1
minItems: 1
maxItems: 2
interrupt-names:
minItems: 1
items:
- enum: [INT1, INT2]
- const: INT2
vdd-supply: true
vddio-supply: true
@ -61,6 +68,7 @@ examples:
reg = <0x53>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT1";
};
};
- |
@ -76,5 +84,6 @@ examples:
spi-max-frequency = <1000000>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
interrupt-names = "INT1";
};
};

View File

@ -41,6 +41,7 @@ properties:
- adi,ad4880
- adi,ad4883
- adi,ad4884
- adi,ad4885
reg:
minItems: 1
@ -105,6 +106,7 @@ allOf:
- adi,ad4880
- adi,ad4883
- adi,ad4884
- adi,ad4885
then:
properties:
reg:
@ -127,15 +129,15 @@ examples:
#size-cells = <0>;
adc@0 {
compatible = "adi,ad4080";
reg = <0>;
spi-max-frequency = <10000000>;
vdd33-supply = <&vdd33>;
vddldo-supply = <&vddldo>;
vrefin-supply = <&vrefin>;
clocks = <&cnv>;
clock-names = "cnv";
io-backends = <&iio_backend>;
compatible = "adi,ad4080";
reg = <0>;
spi-max-frequency = <10000000>;
vdd33-supply = <&vdd33>;
vddldo-supply = <&vddldo>;
vrefin-supply = <&vrefin>;
clocks = <&cnv>;
clock-names = "cnv";
io-backends = <&iio_backend>;
};
};
- |
@ -144,15 +146,15 @@ examples:
#size-cells = <0>;
adc@0 {
compatible = "adi,ad4880";
reg = <0>, <1>;
spi-max-frequency = <10000000>;
vdd33-supply = <&vdd33>;
vddldo-supply = <&vddldo>;
vrefin-supply = <&vrefin>;
clocks = <&cnv>;
clock-names = "cnv";
io-backends = <&iio_backend_cha>, <&iio_backend_chb>;
compatible = "adi,ad4880";
reg = <0>, <1>;
spi-max-frequency = <10000000>;
vdd33-supply = <&vdd33>;
vddldo-supply = <&vddldo>;
vrefin-supply = <&vrefin>;
clocks = <&cnv>;
clock-names = "cnv";
io-backends = <&iio_backend_cha>, <&iio_backend_chb>;
};
};
...

View File

@ -8,7 +8,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD4130 family ADCs
maintainers:
- Cosmin Tanislav <cosmin.tanislav@analog.com>
- Marcelo Schmitt <marcelo.schmitt@analog.com>
- Antoniu Miclaus <antoniu.miclaus@analog.com>
description: |
Bindings for the Analog Devices AD4130 family ADCs.

View File

@ -142,13 +142,13 @@ examples:
io-backends = <&iio_backend>;
channel@0 {
reg = <0>;
diff-channels = <0 0>;
bipolar;
reg = <0>;
diff-channels = <0 0>;
bipolar;
};
channel@1 {
reg = <1>;
reg = <1>;
};
};
};

View File

@ -443,7 +443,7 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
adc@0 {
compatible = "adi,ad4111";
reg = <0>;

View File

@ -238,9 +238,9 @@ examples:
};
regulators {
vcm_reg: vcm-output {
regulator-name = "ad7768-1-vcm";
};
vcm_reg: vcm-output {
regulator-name = "ad7768-1-vcm";
};
};
};
};

View File

@ -0,0 +1,270 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/adi,ad7768.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD7768 and AD7768-4 ADC
maintainers:
- Janani Sunil <janani.sunil@analog.com>
description: |
The AD7768 is an 8-channel, 24-bit simultaneous sampling ADC with configurable
power and performance modes. The AD7768-4 is a 4-channel version.
This binding covers SPI mode only (register access via SPI). Pin control mode,
where configuration is set via hardware pins rather than SPI registers, is not
supported.
The io-backend represents the high-speed data output interface, consuming the
DOUTx data lines, DCLK (data clock), and DRDY (data ready) signals.
Datasheet at:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad7768-ad7768-4.pdf
HDL reference design:
https://github.com/analogdevicesinc/hdl/tree/main/projects/ad7768evb
properties:
compatible:
enum:
- adi,ad7768
- adi,ad7768-4
reg:
maxItems: 1
clocks:
maxItems: 1
clock-names:
description:
Describes the type of master clock (MCLK) attached to the XTAL1 and
XTAL2/MCLK pins. A CMOS clock is supplied on the XTAL2/MCLK pin, a
crystal oscillator is connected between the XTAL1 and XTAL2 pins, and an
LVDS differential clock is supplied on the XTAL1/XTAL2 pin pair. CMOS and
LVDS clocks must operate from 1.15 MHz to 34 MHz. Crystals must operate
from 8 MHz to 34 MHz.
enum:
- mclk
- xtal
- lvds
avdd1-supply:
description:
Analog supply. Its voltage is used to derive the supply-dependent VCM
output level, so it must be a regulator that can report its voltage.
avss-supply:
description:
Negative analog supply. If omitted, AVSS is assumed to be at system
ground.
avdd2-supply: true
iovdd-supply: true
ref1p-supply: true
ref1n-supply:
description:
Negative reference input supply for REF1. If omitted, REF1- is assumed
to be connected to ground.
ref2p-supply: true
ref2n-supply:
description:
Negative reference input supply for REF2. If omitted, REF2- is assumed
to be connected to ground.
reset-gpios:
maxItems: 1
description: GPIO connected to the active-low RESET pin
start-gpios:
maxItems: 1
description:
GPIO connected to the START pin. An active-low pulse on this pin
synchronizes the device to other AD7768 devices. When not used, this
pin must be tied to a logic high level through a pull-up resistor.
When used, SYNC_OUT must be wired back to SYNC_IN on all devices in
the synchronization chain.
sync-in-gpios:
maxItems: 1
description:
GPIO connected to the SYNC_IN pin. Receives the synchronization pulse
generated on SYNC_OUT in response to a START pulse. Must be synchronous
to the MCLK clock domain. In multi-device or daisy-chained systems,
two successive synchronization pulses must be applied to guarantee all
ADCs are synchronized.
gpio-controller: true
'#gpio-cells':
const: 2
adi,data-lines-number:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [1, 2, 4, 8]
description:
Number of DOUTx lines used for the high-speed data output interface
(distinct from the SPI control interface). AD7768 supports 1, 2, or 8
lines; AD7768-4 supports 1 or 4 lines. Defaults to the maximum number
of lines for the selected variant if omitted.
regulators:
type: object
description: Container for the on-chip VCM regulator.
additionalProperties: false
properties:
vcm-output:
type: object
description:
Buffered common-mode voltage output on the VCM pin. Use
regulator-always-on when no consumer node references this output.
Channel 0 must be present and enabled while VCM is used, since
putting channel 0 in standby disables the VCM output.
$ref: /schemas/regulator/regulator.yaml#
unevaluatedProperties: false
io-backends:
maxItems: 1
'#address-cells':
const: 1
'#size-cells':
const: 0
patternProperties:
"^channel@[0-7]$":
type: object
description:
Represents the external channels which are connected to the device.
AD7768 supports channels 0-7, AD7768-4 supports channels 0-3.
properties:
reg:
minimum: 0
maximum: 7
description: The channel number
adi,prechargebuf-pos-enable:
type: boolean
description: Enable positive input precharge buffer
adi,prechargebuf-neg-enable:
type: boolean
description: Enable negative input precharge buffer
adi,refbuf-pos-enable:
type: boolean
description: Enable positive reference buffer
adi,refbuf-neg-enable:
type: boolean
description: Enable negative reference buffer
required:
- reg
additionalProperties: false
required:
- compatible
- reg
- clocks
- clock-names
- avdd1-supply
- avdd2-supply
- iovdd-supply
- ref1p-supply
- ref2p-supply
- io-backends
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
- if:
properties:
compatible:
contains:
const: adi,ad7768-4
then:
properties:
adi,data-lines-number:
enum: [1, 4]
patternProperties:
"^channel@[0-3]$":
properties:
reg:
maximum: 3
"^channel@[4-7]$": false
else:
properties:
adi,data-lines-number:
enum: [1, 2, 8]
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7768";
reg = <0>;
spi-max-frequency = <1000000>;
avdd1-supply = <&avdd1_regulator>;
avss-supply = <&avss_regulator>;
avdd2-supply = <&avdd2_regulator>;
iovdd-supply = <&iovdd_regulator>;
ref1p-supply = <&ref1p_regulator>;
ref1n-supply = <&ref1n_regulator>;
ref2p-supply = <&ref2p_regulator>;
ref2n-supply = <&ref2n_regulator>;
reset-gpios = <&gpio0 86 GPIO_ACTIVE_LOW>;
clocks = <&ad7768_mclk>;
clock-names = "mclk";
adi,data-lines-number = <8>;
gpio-controller;
#gpio-cells = <2>;
io-backends = <&iio_backend>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
adi,prechargebuf-pos-enable;
adi,refbuf-pos-enable;
};
channel@1 {
reg = <1>;
adi,prechargebuf-pos-enable;
adi,prechargebuf-neg-enable;
adi,refbuf-pos-enable;
adi,refbuf-neg-enable;
};
channel@7 {
reg = <7>;
adi,prechargebuf-pos-enable;
adi,refbuf-pos-enable;
};
};
};
...

View File

@ -122,14 +122,14 @@ examples:
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7779";
reg = <0>;
start-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio0 93 GPIO_ACTIVE_LOW>;
interrupt-parent = <&intc>;
interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "adc_rdy";
clocks = <&adc_clk>;
compatible = "adi,ad7779";
reg = <0>;
start-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio0 93 GPIO_ACTIVE_LOW>;
interrupt-parent = <&intc>;
interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "adc_rdy";
clocks = <&adc_clk>;
};
};
@ -140,13 +140,13 @@ examples:
#size-cells = <0>;
adc@0 {
compatible = "adi,ad7779";
reg = <0>;
start-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio0 93 GPIO_ACTIVE_LOW>;
clocks = <&adc_clk>;
io-backends = <&iio_backend>;
adi,num-lanes = <4>;
compatible = "adi,ad7779";
reg = <0>;
start-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
reset-gpios = <&gpio0 93 GPIO_ACTIVE_LOW>;
clocks = <&adc_clk>;
io-backends = <&iio_backend>;
adi,num-lanes = <4>;
};
};
...

View File

@ -5,21 +5,23 @@
$id: http://devicetree.org/schemas/iio/adc/adi,ade9000.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices ADE9000 High Performance, Polyphase Energy Metering
title: Analog Devices ADE9000/ADE9078 High Performance, Polyphase Energy Metering
maintainers:
- Antoniu Miclaus <antoniu.miclaus@analog.com>
description: |
The ADE9000 is a highly accurate, fully integrated, multiphase energy and power
quality monitoring device. Superior analog performance and a digital signal
processing (DSP) core enable accurate energy monitoring over a wide dynamic
range. An integrated high end reference ensures low drift over temperature
with a combined drift of less than ±25 ppm/°C maximum for the entire channel
including a programmable gain amplifier (PGA) and an analog-to-digital
converter (ADC).
The ADE9000 and ADE9078 are highly accurate, fully integrated, multiphase
energy and power quality monitoring devices. Superior analog performance and a
digital signal processing (DSP) core enable accurate energy monitoring over a
wide dynamic range. An integrated high end reference ensures low drift over
temperature with a combined drift of less than ±25 ppm/°C maximum for the
entire channel including a programmable gain amplifier (PGA) and an
analog-to-digital converter (ADC). The ADE9078 does not provide the on-chip
dip/swell detection available on the ADE9000.
https://www.analog.com/media/en/technical-documentation/data-sheets/ADE9000.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ADE9078.pdf
$ref: /schemas/spi/spi-peripheral-props.yaml#
@ -27,6 +29,7 @@ properties:
compatible:
enum:
- adi,ade9000
- adi,ade9078
reg:
maxItems: 1
@ -67,6 +70,17 @@ required:
- reg
- vdd-supply
allOf:
- if:
properties:
compatible:
contains:
const: adi,ade9078
then:
properties:
spi-max-frequency:
maximum: 10000000
unevaluatedProperties: false
examples:
@ -75,20 +89,20 @@ examples:
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ade9000";
reg = <0>;
spi-max-frequency = <7000000>;
adc@0 {
compatible = "adi,ade9000";
reg = <0>;
spi-max-frequency = <7000000>;
#clock-cells = <0>;
reset-gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
interrupts = <2 IRQ_TYPE_EDGE_FALLING>, <3 IRQ_TYPE_EDGE_FALLING>, <4 IRQ_TYPE_EDGE_FALLING>;
interrupt-names = "irq0", "irq1", "dready";
interrupt-parent = <&gpio>;
clocks = <&ext_clock_24576khz>;
vdd-supply = <&vdd_reg>;
};
#clock-cells = <0>;
reset-gpios = <&gpio 4 GPIO_ACTIVE_LOW>;
interrupts = <2 IRQ_TYPE_EDGE_FALLING>, <3 IRQ_TYPE_EDGE_FALLING>, <4 IRQ_TYPE_EDGE_FALLING>;
interrupt-names = "irq0", "irq1", "dready";
interrupt-parent = <&gpio>;
clocks = <&ext_clock_24576khz>;
vdd-supply = <&vdd_reg>;
};
};

View File

@ -0,0 +1,65 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/adi,max40080.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices MAX40080 bidirectional current-sense amplifier
maintainers:
- Ciprian Hegbeli <ciprian.hegbeli@analog.com>
- Stefan Popa <stefan.popa@analog.com>
description: |
The MAX40080 is a high-precision, bidirectional current-sense amplifier with
an integrated 12-bit ADC and an I2C/SMBus interface. It measures the voltage
across an external shunt resistor and the input bus voltage, and stores the
results in an internal FIFO.
Datasheet:
https://www.analog.com/max40080
properties:
compatible:
const: adi,max40080
reg:
maxItems: 1
"#io-channel-cells":
const: 1
vdd-supply:
description: Power supply for the device.
interrupts:
maxItems: 1
description: ALERT_ output for overcurrent/undervoltage threshold events.
shunt-resistor-micro-ohms:
description:
Value of the current-sense shunt resistor connected between the RS+ and
RS- inputs. Used to scale the reported current.
required:
- compatible
- reg
- shunt-resistor-micro-ohms
- vdd-supply
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
adc@20 {
compatible = "adi,max40080";
reg = <0x20>;
#io-channel-cells = <1>;
vdd-supply = <&vdd>;
shunt-resistor-micro-ohms = <100000>;
};
};

View File

@ -0,0 +1,63 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/axiado,ax3000-saradc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Axiado AX3000/AX3005 Successive Approximation Register ADC
description:
The Axiado AX3000/AX3005 SAR ADC is a 10-bit ADC with sixteen input
channels on AX3000 and eight input channels on AX3005.
maintainers:
- Petar Stepanovic <pstepanovic@axiado.com>
- Akhila Kavi <akavi@axiado.com>
- Prasad Bolisetty <pbolisetty@axiado.com>
properties:
compatible:
enum:
- axiado,ax3000-saradc
- axiado,ax3005-saradc
reg:
maxItems: 1
clocks:
maxItems: 1
clock-names:
const: saradc
'#io-channel-cells':
const: 1
vref-supply:
description: Reference voltage regulator supplying the ADC
required:
- compatible
- reg
- clocks
- clock-names
- '#io-channel-cells'
- vref-supply
additionalProperties: false
examples:
- |
soc {
#address-cells = <2>;
#size-cells = <2>;
adc@806a0000 {
compatible = "axiado,ax3000-saradc";
reg = <0x0 0x806a0000 0x0 0x400>;
clocks = <&pclk>;
clock-names = "saradc";
vref-supply = <&vref_reg>;
#io-channel-cells = <1>;
};
};

View File

@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/iio/adc/lltc,ltc2497.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Linear Technology / Analog Devices LTC2497 and LTC2309 ADC
title: Linear Technology / Analog Devices LTC2497 and similar ADCs
maintainers:
- Michael Hennerich <michael.hennerich@analog.com>

View File

@ -118,22 +118,22 @@ examples:
#size-cells = <0>;
adc@1e {
compatible = "maxim,max34409";
reg = <0x1e>;
powerdown-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
powerdown-status-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
compatible = "maxim,max34409";
reg = <0x1e>;
powerdown-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
powerdown-status-gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>;
#address-cells = <1>;
#size-cells = <0>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0x0>;
maxim,rsense-val-micro-ohms = <5000>;
};
channel@0 {
reg = <0x0>;
maxim,rsense-val-micro-ohms = <5000>;
};
channel@1 {
reg = <0x1>;
maxim,rsense-val-micro-ohms = <10000>;
};
channel@1 {
reg = <0x1>;
maxim,rsense-val-micro-ohms = <10000>;
};
};
};

View File

@ -38,6 +38,7 @@ properties:
- const: mediatek,mt7986-auxadc
- items:
- enum:
- mediatek,mt6572-auxadc
- mediatek,mt6893-auxadc
- mediatek,mt8183-auxadc
- mediatek,mt8186-auxadc

View File

@ -56,6 +56,6 @@ examples:
clocks = <&ccu1 CLK_APB3_ADC0>;
vref-supply = <&reg_vdda>;
resets = <&rgu 40>;
};
};
};
...

View File

@ -34,8 +34,6 @@ properties:
- description: A/D scan end interrupt for Group C
- description: Window A compare match
- description: Window B compare match
- description: Compare match
- description: Compare mismatch
interrupt-names:
items:
@ -44,8 +42,6 @@ properties:
- const: gcadi
- const: cmpai
- const: cmpbi
- const: wcmpm
- const: wcmpum
clocks:
items:
@ -57,6 +53,18 @@ properties:
- const: adclk
- const: pclk
dmas:
minItems: 1
maxItems: 3
description:
Must contain a list of references to DMA RX specifiers.
dma-names:
minItems: 1
maxItems: 3
items:
const: rx
power-domains:
maxItems: 1
@ -107,11 +115,9 @@ examples:
<GIC_SPI 709 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 710 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 711 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 855 IRQ_TYPE_EDGE_RISING>,
<GIC_SPI 856 IRQ_TYPE_EDGE_RISING>;
<GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "adi", "gbadi", "gcadi",
"cmpai", "cmpbi", "wcmpm", "wcmpum";
"cmpai", "cmpbi";
clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKL>,
<&cpg CPG_MOD 225>;
clock-names = "adclk", "pclk";

View File

@ -25,7 +25,9 @@ properties:
- renesas,r9a07g054-adc # RZ/V2L
- const: renesas,rzg2l-adc
- items:
- const: renesas,r9a08g045-adc # RZ/G3S
- enum:
- renesas,r9a08g045-adc # RZ/G3S
- renesas,r9a08g046-adc1 # RZ/G3L ADC for TSU
reg:
maxItems: 1
@ -121,6 +123,19 @@ allOf:
reg:
maximum: 7
- if:
properties:
compatible:
contains:
const: renesas,r9a08g046-adc1
then:
patternProperties:
"^channel@[0-7]$": false
"^channel@[8]$":
properties:
reg:
const: 8
additionalProperties: false
examples:

View File

@ -66,6 +66,11 @@ patternProperties:
- minimum: 0
maximum: 7
label:
$ref: /schemas/types.yaml#/definitions/string
description:
A descriptive name for this channel, like "vcc_ram" or "CH3".
ti,gain:
$ref: /schemas/types.yaml#/definitions/uint32
minimum: 0
@ -125,6 +130,7 @@ examples:
reg = <4>;
ti,gain = <3>;
ti,datarate = <5>;
label = "CH3";
};
};
};

View File

@ -4,19 +4,23 @@
$id: http://devicetree.org/schemas/iio/adc/ti,ads1100.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: TI ADS1100/ADS1000 single channel I2C analog to digital converter
title: TI ADS1100 and similar single channel I2C Analog to Digital Converters
maintainers:
- Mike Looijmans <mike.looijmans@topic.nl>
description: |
Datasheet at: https://www.ti.com/lit/gpn/ads1100
Datasheets:
- https://www.ti.com/lit/gpn/ads1000
- https://www.ti.com/lit/gpn/ads1100
- https://www.ti.com/lit/gpn/ads1110
properties:
compatible:
enum:
- ti,ads1100
- ti,ads1000
- ti,ads1100
- ti,ads1110
reg:
maxItems: 1

View File

@ -0,0 +1,149 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/ti,ads112c04.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Texas Instruments ADS112C04 ADC
maintainers:
- Kyle Hsieh <kylehsieh1995@gmail.com>
description:
The ADS112C04 (16-bit) are precision analog-to-digital converters (ADCs)
with an I2C interface. They feature a flexible input multiplexer, a
low-noise programmable gain amplifier (PGA), two programmable excitation
current sources, a voltage reference, and a precision temperature sensor.
properties:
compatible:
enum:
- ti,ads112c04
reg:
maxItems: 1
description: I2C address of the device.
interrupts:
maxItems: 1
description:
Data ready (DRDY) interrupt output. DRDY pulses low when a conversion
result is ready and returns high once the result is latched, so an
edge trigger should be used.
"#address-cells":
const: 1
"#size-cells":
const: 0
reset-gpios:
maxItems: 1
description: GPIO connected to the RESET pin. Active low.
avdd-supply: true
dvdd-supply: true
refp-supply: true
refn-supply: true
ti,refp-refn-resistor-ohms:
description: Resistance of the external resistor between REFP and REFN.
patternProperties:
"^channel@[0-9a-b]$":
$ref: adc.yaml
unevaluatedProperties: false
properties:
reg:
items:
- maximum: 11
single-channel:
maximum: 3
diff-channels:
items:
maximum: 3
excitation-channels:
maxItems: 2
items:
maximum: 5
description:
Additionally to AIN0-AIN3, IDAC1/IDAC2 can also be routed to
REFP0 (4) and REFN0 (5).
excitation-current-nanoamp:
enum: [10000, 50000, 100000, 250000, 500000, 1000000, 1500000]
burn-out-current-nanoamp:
const: 10000
reference-sources:
items:
- enum: [internal, external, avdd]
default: [ internal ]
dependencies:
excitation-channels: [ excitation-current-nanoamp ]
excitation-current-nanoamp: [ excitation-channels ]
oneOf:
- required: [ single-channel ]
- required: [ diff-channels ]
required:
- compatible
- reg
- avdd-supply
- dvdd-supply
dependencies:
refn-supply: [ refp-supply ]
oneOf:
- required:
- refp-supply
- required:
- ti,refp-refn-resistor-ohms
- properties:
refp-supply: false
refn-supply: false
ti,refp-refn-resistor-ohms: false
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
#include <dt-bindings/gpio/gpio.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
adc@40 {
compatible = "ti,ads112c04";
reg = <0x40>;
interrupt-parent = <&gpio>;
interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
reset-gpios = <&gpio 13 GPIO_ACTIVE_LOW>;
avdd-supply = <&vdd_3v3_reg>;
dvdd-supply = <&vdd_3v3_reg>;
refp-supply = <&vref_reg>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
diff-channels = <0>, <1>;
};
channel@1 {
reg = <1>;
single-channel = <2>;
};
};
};

View File

@ -65,15 +65,15 @@ examples:
#size-cells = <0>;
adc@1 {
reg = <1>;
compatible = "ti,ads1298";
label = "ads1298-1-ecg";
avdd-supply = <&reg_iso_5v_a>;
clocks = <&clk_ads1298>;
interrupt-parent = <&gpio0>;
interrupts = <78 IRQ_TYPE_EDGE_FALLING>;
spi-max-frequency = <20000000>;
spi-cpha;
reg = <1>;
compatible = "ti,ads1298";
label = "ads1298-1-ecg";
avdd-supply = <&reg_iso_5v_a>;
clocks = <&clk_ads1298>;
interrupt-parent = <&gpio0>;
interrupts = <78 IRQ_TYPE_EDGE_FALLING>;
spi-max-frequency = <20000000>;
spi-cpha;
};
};
...

View File

@ -7,7 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD74115H device
maintainers:
- Cosmin Tanislav <cosmin.tanislav@analog.com>
- Marcelo Schmitt <marcelo.schmitt@analog.com>
- Antoniu Miclaus <antoniu.miclaus@analog.com>
description: |
The AD74115H is a single-channel software configurable input/output

View File

@ -7,7 +7,8 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD74412R/AD74413R device
maintainers:
- Cosmin Tanislav <cosmin.tanislav@analog.com>
- Marcelo Schmitt <marcelo.schmitt@analog.com>
- Antoniu Miclaus <antoniu.miclaus@analog.com>
description: |
The AD74412R and AD74413R are quad-channel software configurable input/output

View File

@ -10,13 +10,13 @@ maintainers:
- Kim Seer Paller <kimseer.paller@analog.com>
description: |
The AD3530/AD3530R (8-channel), AD3531/AD3531R (4-channel), and AD3532/AD3532R
(16-channel) are low-power, 16-bit, buffered voltage output digital-to-analog
converters (DACs) with software-programmable gain controls, providing
full-scale output spans of 2.5V or 5V for reference voltages of 2.5V. These
devices operate from a single 2.7V to 5.5V supply and are guaranteed monotonic
by design. The "R" variants include a 2.5V, 5ppm/°C internal reference, which
is disabled by default.
The AD3530/AD3530R (8-channel), AD3531/AD3531R (4-channel), AD3532/AD3532R
(16-channel), 16-bit and AD3536R (16-channel), 12-bit are low-power, buffered
voltage output digital-to-analog converters (DACs) with software-programmable
gain controls, providing full-scale output spans of 2.5V or 5V for reference
voltages of 2.5V. These devices operate from a single 2.7V to 5.5V supply and
are guaranteed monotonic by design. The "R" variants include a 2.5V, 5ppm/°C
internal reference, which is disabled by default.
Datasheet can be found here:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad3530_ad530r.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ad3531-ad3531r.pdf
@ -31,6 +31,7 @@ properties:
- adi,ad3531r
- adi,ad3532
- adi,ad3532r
- adi,ad3536r
reg:
maxItems: 1

View File

@ -0,0 +1,254 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5529r.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5529R 16-Channel 12/16-bit High Voltage DAC
maintainers:
- Janani Sunil <janani.sunil@analog.com>
description: |
The AD5529R is a 16-channel, 12-bit or 16-bit, high voltage, buffered voltage
output digital-to-analog converter (DAC) with an integrated precision reference.
The device operates from unipolar and bipolar supplies. It is guaranteed
monotonic and has built-in rail-to-rail output buffers that can source or
sink up to 25mA.
Specifications:
* 16 independent 12-bit or 16-bit DAC channels
* Independently programmable output ranges: 0V to 5V, 0V to 10V, 0V to 20V,
0V to 40V, ±5V, ±10V, ±15V, and ±20V
* The device supports SPI communication with Mode 0 and Mode 3.
* 4.096V precision reference, 12ppm/°C maximum
* Built-in function generation: Toggle, Sinusoidal Dither, and Ramp waveforms
* Multiplexer for output voltage, load current sense and die temperature
Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/ad5529r.pdf
properties:
compatible:
enum:
- adi,ad5529r-16 # 16-bit variant
- adi,ad5529r-12 # 12-bit variant
reg:
maxItems: 1
spi-max-frequency:
maximum: 25000000
description:
Maximum SPI frequency. The device supports SPI Mode 0 and Mode 3.
Read operations are limited to 25MHz maximum.
reset-gpios:
maxItems: 1
description:
GPIO connected to the RESET pin. Active low. When asserted low,
performs a power-on reset and initializes the device to its default state.
clear-gpios:
maxItems: 1
description:
GPIO connected to the CLEAR pin. Active low. When asserted low,
clears all DAC data registers without affecting configuration settings.
interrupts:
maxItems: 1
description:
Interrupt connected to the ALARM pin. Active low interrupt output
for overtemperature conditions, SPI CRC errors, and function completion.
pwms:
minItems: 1
maxItems: 4
description:
PWM signals connected to the TG0-TG3 toggle pins. Pulsing these pins
based on trigger edge settings allows selected DACs to be updated
synchronously for digital function generation.
pwm-names:
minItems: 1
maxItems: 4
items:
enum: [ tg0, tg1, tg2, tg3 ]
io-channels:
maxItems: 1
description:
ADC channel connected to the MUXOUT pin for monitoring output voltage,
load current sense, and die temperature.
io-channel-names:
const: muxout
vdd-io-supply:
description: Digital power supply (1.08V to 1.98V)
vdd-5v-supply:
description: Analog power supply (4.75V to 5.25V)
vdd-hv0-supply:
description:
High voltage positive supply (7V to 45V) for channels 0 to 3.
vdd-hv1-supply:
description:
High voltage positive supply (7V to 45V) for channels 4 to 7.
vdd-hv2-supply:
description:
High voltage positive supply (7V to 45V) for channels 8 to 11.
vdd-hv3-supply:
description:
High voltage positive supply (7V to 45V) for channels 12 to 15.
vss-hv0-supply:
description:
High voltage negative supply (-22.5V to 0V) for channels 0 to 3.
vss-hv1-supply:
description:
High voltage negative supply (-22.5V to 0V) for channels 4 to 7.
vss-hv2-supply:
description:
High voltage negative supply (-22.5V to 0V) for channels 8 to 11.
vss-hv3-supply:
description:
High voltage negative supply (-22.5V to 0V) for channels 12 to 15.
vref-supply:
description:
External voltage reference supply (4.056V to 4.136V, typically 4.096V).
When specified, the device uses external reference mode and the VREF pin
becomes an input. The device uses the internal 4.096V precision reference
otherwise.
spi-device-addr:
minItems: 1
maxItems: 4
items:
enum: [0, 1, 2, 3]
default: 0
description:
Hardware address of each device, selected by the ID0 and ID1 pins.
Up to four AD5529R devices can share a single SPI chip select.
"#address-cells":
const: 1
"#size-cells":
const: 0
patternProperties:
"^channel@([0-9a-f]{1,2})$":
$ref: dac.yaml
type: object
description: Child nodes for individual channel configuration
properties:
reg:
description:
Flattened channel number across all AD5529R devices sharing the chip
select. Within each 16-channel block, the physical channel number is reg % 16.
minimum: 0
maximum: 63
output-range-microvolt:
description:
Output voltage range for this channel as [min, max] in
microvolts.
oneOf:
- items:
- const: 0
default: 0
- enum: [5000000, 10000000, 20000000, 40000000]
default: 5000000
- items:
- const: -5000000
- const: 5000000
- items:
- const: -10000000
- const: 10000000
- items:
- const: -15000000
- const: 15000000
- items:
- const: -20000000
- const: 20000000
required:
- reg
additionalProperties: false
required:
- compatible
- reg
- vdd-io-supply
- vdd-5v-supply
- vdd-hv0-supply
- vdd-hv1-supply
- vdd-hv2-supply
- vdd-hv3-supply
dependencies:
spi-cpha: [ spi-cpol ]
spi-cpol: [ spi-cpha ]
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "adi,ad5529r-16";
reg = <0>;
spi-max-frequency = <25000000>;
spi-device-addr = <0>;
vdd-io-supply = <&vdd_io_regulator>;
vdd-5v-supply = <&vdd_5v_regulator>;
vdd-hv0-supply = <&vdd_hv0_regulator>;
vdd-hv1-supply = <&vdd_hv1_regulator>;
vdd-hv2-supply = <&vdd_hv2_regulator>;
vdd-hv3-supply = <&vdd_hv3_regulator>;
vss-hv0-supply = <&vss_hv0_regulator>;
vss-hv1-supply = <&vss_hv1_regulator>;
vss-hv2-supply = <&vss_hv2_regulator>;
vss-hv3-supply = <&vss_hv3_regulator>;
reset-gpios = <&gpio0 87 GPIO_ACTIVE_LOW>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
output-range-microvolt = <0 5000000>;
};
channel@1 {
reg = <1>;
output-range-microvolt = <(-10000000) 10000000>;
};
channel@2 {
reg = <2>;
output-range-microvolt = <0 40000000>;
};
};
};
...

View File

@ -0,0 +1,145 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5710r.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5710R/AD5711R 8-channel 12-/16-bit Configurable IDAC/VDAC
maintainers:
- Kim Seer Paller <kimseer.paller@analog.com>
description: |
The AD5710R (16-bit) and AD5711R (12-bit) are 8-channel, low-power,
configurable current/voltage output digital-to-analog converters (DACs) with
an on-chip 2.5V, 3ppm/°C reference. Each channel can be independently
configured as a voltage output (0V to VREF or 0V to 2 x VREF) or a current
output (0mA to 50mA). These devices operate from a single 2.7V to 5.5V
supply and are guaranteed monotonic by design.
Datasheet can be found here:
https://www.analog.com/media/en/technical-documentation/data-sheets/ad5711r-ad5710r.pdf
properties:
compatible:
enum:
- adi,ad5710r
- adi,ad5711r
reg:
maxItems: 1
spi-max-frequency:
maximum: 20000000
'#address-cells':
const: 1
'#size-cells':
const: 0
vdd-supply:
description: Power Supply Input.
iovdd-supply:
description: Digital Power Supply Input.
io-channels:
description:
ADC channel used to monitor internal die temperature, output voltages, and
current of a selected channel via the MUXOUT pin.
maxItems: 1
ref-supply:
description:
Reference Input/Output. The voltage at the REF pin sets the full-scale
range of all channels. If not provided the internal reference is used and
also provided on the VREF pin.
reset-gpios:
description:
Active low signal that is falling edge sensitive. When it is deasserted,
the digital core initialization is performed and all DAC registers except
the Interface Configuration A register are reset to their default values.
maxItems: 1
ldac-gpios:
description:
LDAC pin to be used as a hardware trigger to update the DAC channels. If
not present, the DAC channels are updated by Software LDAC.
maxItems: 1
adi,range-double:
description:
Configure the output range for all channels. If the property is present,
the output will range from 0V to 2 x Vref. If the property is not present,
the output will range from 0V to Vref.
type: boolean
patternProperties:
"^channel@[0-7]$":
$ref: /schemas/iio/dac/dac.yaml#
type: object
description:
Represents the external channels which are connected to the DAC.
properties:
reg:
description: Channel number
minimum: 0
maximum: 7
adi,ch-func:
description:
Channel output type. The values are defined in
<dt-bindings/iio/addac/adi,ad74413r.h>. Use
CH_FUNC_VOLTAGE_OUTPUT (1) for voltage output or
CH_FUNC_CURRENT_OUTPUT (2) for current output.
$ref: /schemas/types.yaml#/definitions/uint32
enum: [1, 2]
required:
- reg
- adi,ch-func
unevaluatedProperties: false
required:
- compatible
- reg
- vdd-supply
- iovdd-supply
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/iio/addac/adi,ad74413r.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "adi,ad5710r";
reg = <0>;
spi-max-frequency = <1000000>;
vdd-supply = <&vdd>;
iovdd-supply = <&iovdd>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
adi,ch-func = <CH_FUNC_VOLTAGE_OUTPUT>;
};
channel@1 {
reg = <1>;
adi,ch-func = <CH_FUNC_CURRENT_OUTPUT>;
};
};
};
...

View File

@ -4,58 +4,92 @@
$id: http://devicetree.org/schemas/iio/dac/microchip,mcp47feb02.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Microchip MCP47F(E/V)B(0/1/2)(1/2/4/8) DAC with I2C Interface Families
title: Microchip MCP4(7/8)F(E/V)B(0/1/2)(1/2/4/8) DAC with I2C/SPI Interface Families
maintainers:
- Ariana Lazar <ariana.lazar@microchip.com>
description: |
Datasheet for MCP47FEB01, MCP47FEB11, MCP47FEB21, MCP47FEB02, MCP47FEB12,
MCP47FEB22 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005375A.pdf
Datasheet for MCP47FVB01, MCP47FVB11, MCP47FVB21, MCP47FVB02, MCP47FVB12,
MCP47FVB22 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005405A.pdf
Datasheet for MCP47FEB04, MCP47FEB14, MCP47FEB24, MCP47FEB08, MCP47FEB18,
MCP47FEB28, MCP47FVB04, MCP47FVB14, MCP47FVB24, MCP47FVB08, MCP47FVB18,
MCP47FVB28 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/MCP47FXBX48-Data-Sheet-DS200006368A.pdf
Datasheets for MCP47F(E/V)B(0/1/2)(1/2/4/8) DAC with I2C Interface Families:
Datasheet for MCP47FEB01, MCP47FEB02, MCP47FEB11, MCP47FEB12, MCP47FEB21,
MCP47FEB22 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005375A.pdf
Datasheet for MCP47FVB01, MCP47FVB02, MCP47FVB11, MCP47FVB12, MCP47FVB21,
MCP47FVB22 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005405A.pdf
Datasheet for MCP47FEB04, MCP47FEB08, MCP47FEB14, MCP47FEB18, MCP47FEB24,
MCP47FEB28, MCP47FVB04, MCP47FVB08, MCP47FVB14, MCP47FVB18, MCP47FVB24,
MCP47FVB28 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/MCP47FXBX48-Data-Sheet-DS200006368A.pdf
Datasheets for MCP48F(E/V)B(0/1/2)(1/2/4/8) DAC with SPI Interface Families:
Datasheet for MCP48FEB01, MCP48FEB02, MCP48FEB11, MCP48FEB12, MCP48FEB21,
MCP48FEB22 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005429B.pdf
Datasheet for MCP48FVB01, MCP48FVB02, MCP48FVB11, MCP48FVB12, MCP48FVB21,
MCP48FVB22 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005466A.pdf
Datasheet for MCP48FEB04, MCP48FEB14, MCP48FEB24, MCP48FEB08, MCP48FEB18,
MCP48FEB28, MCP48FVB04, MCP48FVB14, MCP48FVB24, MCP48FVB08, MCP48FVB18,
MCP48FVB28 can be found here:
https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/MCP48FXBX4-8-Family-Data-Sheet-DS20006362A.pdf
+------------+--------------+-------------+-------------+------------+
| Device | Resolution | Channels | Vref number | Memory |
|------------|--------------|-------------|-------------|------------|
| MCP47FEB01 | 8-bit | 1 | 1 | EEPROM |
| MCP47FEB11 | 10-bit | 1 | 1 | EEPROM |
| MCP47FEB21 | 12-bit | 1 | 1 | EEPROM |
|------------|--------------|-------------|-------------|------------|
| MCP47FEB02 | 8-bit | 2 | 1 | EEPROM |
| MCP47FEB12 | 10-bit | 2 | 1 | EEPROM |
| MCP47FEB22 | 12-bit | 2 | 1 | EEPROM |
|------------|--------------|-------------|-------------|------------|
| MCP47FVB01 | 8-bit | 1 | 1 | RAM |
| MCP47FVB11 | 10-bit | 1 | 1 | RAM |
| MCP47FVB21 | 12-bit | 1 | 1 | RAM |
|------------|--------------|-------------|-------------|------------|
| MCP47FVB02 | 8-bit | 2 | 1 | RAM |
| MCP47FVB12 | 10-bit | 2 | 1 | RAM |
| MCP47FVB22 | 12-bit | 2 | 1 | RAM |
|------------|--------------|-------------|-------------|------------|
| MCP47FVB04 | 8-bit | 4 | 2 | RAM |
| MCP47FVB14 | 10-bit | 4 | 2 | RAM |
| MCP47FVB24 | 12-bit | 4 | 2 | RAM |
|------------|--------------|-------------|-------------|------------|
| MCP47FVB08 | 8-bit | 8 | 2 | RAM |
| MCP47FVB18 | 10-bit | 8 | 2 | RAM |
| MCP47FVB28 | 12-bit | 8 | 2 | RAM |
|------------|--------------|-------------|-------------|------------|
| MCP47FEB04 | 8-bit | 4 | 2 | EEPROM |
| MCP47FEB14 | 10-bit | 4 | 2 | EEPROM |
| MCP47FEB24 | 12-bit | 4 | 2 | EEPROM |
|------------|--------------|-------------|-------------|------------|
| MCP47FEB08 | 8-bit | 8 | 2 | EEPROM |
| MCP47FEB18 | 10-bit | 8 | 2 | EEPROM |
| MCP47FEB28 | 12-bit | 8 | 2 | EEPROM |
+------------+--------------+-------------+-------------+------------+
+------------+--------------+-------------+-------------+------------+------------+
| Device | Resolution | Channels | Vref number | Memory | Interface |
|------------|--------------|-------------|-------------|------------|------------|
| MCP47FEB01 | | 1 | 1 | EEPROM | I2C |
| MCP47FEB02 | | 2 | 1 | EEPROM | I2C |
| MCP47FEB04 | | 4 | 2 | EEPROM | I2C |
| MCP47FEB08 | 8-bit | 8 | 2 | EEPROM | I2C |
| MCP48FEB01 | | 1 | 1 | EEPROM | SPI |
| MCP48FEB02 | | 2 | 1 | EEPROM | SPI |
| MCP48FEB04 | | 4 | 2 | EEPROM | SPI |
| MCP48FEB08 | | 8 | 2 | EEPROM | SPI |
|------------|--------------|-------------|-------------|------------|------------|
| MCP47FEB11 | | 1 | 1 | EEPROM | I2C |
| MCP47FEB12 | | 2 | 1 | EEPROM | I2C |
| MCP47FEB14 | | 4 | 2 | EEPROM | I2C |
| MCP47FEB18 | 10-bit | 8 | 2 | EEPROM | I2C |
| MCP48FEB11 | | 1 | 1 | EEPROM | SPI |
| MCP48FEB12 | | 2 | 1 | EEPROM | SPI |
| MCP48FEB14 | | 4 | 2 | EEPROM | SPI |
| MCP48FEB18 | | 8 | 2 | EEPROM | SPI |
|------------|--------------|-------------|-------------|------------|------------|
| MCP47FEB21 | | 1 | 1 | EEPROM | I2C |
| MCP47FEB22 | | 2 | 1 | EEPROM | I2C |
| MCP47FEB24 | | 4 | 2 | EEPROM | I2C |
| MCP47FEB28 | 12-bit | 8 | 2 | EEPROM | I2C |
| MCP48FEB21 | | 1 | 1 | EEPROM | SPI |
| MCP48FEB22 | | 2 | 1 | EEPROM | SPI |
| MCP48FEB24 | | 4 | 2 | EEPROM | SPI |
| MCP48FEB28 | | 8 | 2 | EEPROM | SPI |
|------------|--------------|-------------|-------------|------------|------------|
| MCP47FVB01 | | 1 | 1 | RAM | I2C |
| MCP47FVB02 | | 2 | 1 | RAM | I2C |
| MCP47FVB04 | | 4 | 2 | RAM | I2C |
| MCP47FVB08 | 8-bit | 8 | 2 | RAM | I2C |
| MCP48FVB01 | | 1 | 1 | RAM | SPI |
| MCP48FVB02 | | 2 | 1 | RAM | SPI |
| MCP48FVB04 | | 4 | 2 | RAM | SPI |
| MCP48FVB08 | | 8 | 2 | RAM | SPI |
|------------|--------------|-------------|-------------|------------|------------|
| MCP47FVB11 | | 1 | 1 | RAM | I2C |
| MCP47FVB12 | | 2 | 1 | RAM | I2C |
| MCP47FVB14 | | 4 | 2 | RAM | I2C |
| MCP47FVB18 | 10-bit | 8 | 2 | RAM | I2C |
| MCP48FVB11 | | 1 | 1 | RAM | SPI |
| MCP48FVB12 | | 2 | 1 | RAM | SPI |
| MCP48FVB14 | | 4 | 2 | RAM | SPI |
| MCP48FVB18 | | 8 | 2 | RAM | SPI |
|------------|--------------|-------------|-------------|------------|------------|
| MCP47FVB21 | | 1 | 1 | RAM | I2C |
| MCP47FVB22 | | 2 | 1 | RAM | I2C |
| MCP47FVB24 | | 4 | 2 | RAM | I2C |
| MCP47FVB28 | 12-bit | 8 | 2 | RAM | I2C |
| MCP48FVB21 | | 1 | 1 | RAM | SPI |
| MCP48FVB22 | | 2 | 1 | RAM | SPI |
| MCP48FVB24 | | 4 | 2 | RAM | SPI |
| MCP48FVB28 | | 8 | 2 | RAM | SPI |
+------------+--------------+-------------+-------------+------------+------------+
properties:
compatible:
@ -84,10 +118,37 @@ properties:
- microchip,mcp47feb08
- microchip,mcp47feb18
- microchip,mcp47feb28
- microchip,mcp48feb01
- microchip,mcp48feb02
- microchip,mcp48feb04
- microchip,mcp48feb08
- microchip,mcp48feb11
- microchip,mcp48feb12
- microchip,mcp48feb14
- microchip,mcp48feb18
- microchip,mcp48feb21
- microchip,mcp48feb22
- microchip,mcp48feb24
- microchip,mcp48feb28
- microchip,mcp48fvb01
- microchip,mcp48fvb02
- microchip,mcp48fvb04
- microchip,mcp48fvb08
- microchip,mcp48fvb11
- microchip,mcp48fvb12
- microchip,mcp48fvb14
- microchip,mcp48fvb18
- microchip,mcp48fvb21
- microchip,mcp48fvb22
- microchip,mcp48fvb24
- microchip,mcp48fvb28
reg:
maxItems: 1
spi-max-frequency:
maximum: 10000000
"#address-cells":
const: 1
@ -178,6 +239,21 @@ required:
- vdd-supply
allOf:
- if:
properties:
compatible:
contains:
pattern: "^microchip,mcp48f[ev]b[0-2][1248]$"
then:
$ref: /schemas/spi/spi-peripheral-props.yaml#
dependencies:
spi-cpha: [ spi-cpol ]
spi-cpol: [ spi-cpha ]
else:
properties:
spi-max-frequency: false
spi-cpha: false
spi-cpol: false
- if:
properties:
compatible:
@ -189,6 +265,12 @@ allOf:
- microchip,mcp47fvb01
- microchip,mcp47fvb11
- microchip,mcp47fvb21
- microchip,mcp48feb01
- microchip,mcp48feb11
- microchip,mcp48feb21
- microchip,mcp48fvb01
- microchip,mcp48fvb11
- microchip,mcp48fvb21
then:
properties:
lat1-gpios: false
@ -211,6 +293,12 @@ allOf:
- microchip,mcp47fvb02
- microchip,mcp47fvb12
- microchip,mcp47fvb22
- microchip,mcp48feb02
- microchip,mcp48feb12
- microchip,mcp48feb22
- microchip,mcp48fvb02
- microchip,mcp48fvb12
- microchip,mcp48fvb22
then:
properties:
lat1-gpios: false
@ -233,6 +321,12 @@ allOf:
- microchip,mcp47feb04
- microchip,mcp47feb14
- microchip,mcp47feb24
- microchip,mcp48feb04
- microchip,mcp48feb14
- microchip,mcp48feb24
- microchip,mcp48fvb04
- microchip,mcp48fvb14
- microchip,mcp48fvb24
then:
patternProperties:
"^channel@[0-3]$":
@ -251,6 +345,12 @@ allOf:
- microchip,mcp47feb08
- microchip,mcp47feb18
- microchip,mcp47feb28
- microchip,mcp48feb08
- microchip,mcp48feb18
- microchip,mcp48feb28
- microchip,mcp48fvb08
- microchip,mcp48fvb18
- microchip,mcp48fvb28
then:
patternProperties:
"^channel@[0-7]$":
@ -272,7 +372,7 @@ allOf:
properties:
microchip,vref1-buffered: false
additionalProperties: false
unevaluatedProperties: false
examples:
- |
@ -299,4 +399,29 @@ examples:
};
};
};
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "microchip,mcp48feb02";
reg = <0x0>;
vdd-supply = <&vdac_vdd>;
vref-supply = <&vref_reg>;
spi-max-frequency = <10000000>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
label = "Adjustable_voltage_ch0";
};
channel@1 {
reg = <0x1>;
label = "Adjustable_voltage_ch1";
};
};
};
...

View File

@ -0,0 +1,209 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/frequency/adi,ad9910.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD9910 Direct Digital Synthesizer
maintainers:
- Rodrigo Alencar <rodrigo.alencar@analog.com>
description: >
The AD9910 is a 1 GSPS direct digital synthesizer (DDS) with an integrated
14-bit DAC. It features single tone mode with 8 configurable profiles,
a digital ramp generator, RAM control, OSK, and a parallel data port for
high-speed streaming.
https://www.analog.com/en/products/ad9910.html
properties:
compatible:
const: adi,ad9910
reg:
maxItems: 1
spi-max-frequency:
maximum: 70000000
clocks:
minItems: 1
items:
- description: Reference clock (REF_CLK).
- description: Optional synchronization clock (SYNC_IN).
clock-names:
minItems: 1
items:
- const: ref_clk
- const: sync_in
'#clock-cells':
const: 1
clock-output-names:
items:
- const: sync_clk
- const: pdclk
- const: sync_out
interrupts:
minItems: 1
maxItems: 2
description:
Requires interrupt-names property with the same number of items. The
supported interrupts are 'drover' (digital ramp generator limit) and
'ram_swp_ovr' (end of RAM sweep).
interrupt-names:
minItems: 1
maxItems: 2
items:
enum: [ drover, ram_swp_ovr ]
dvdd-io33-supply:
description: 3.3V Digital I/O supply.
avdd33-supply:
description: 3.3V Analog DAC supply.
dvdd18-supply:
description: 1.8V Digital Core supply.
avdd18-supply:
description: 1.8V Analog Core supply.
reset-gpios:
maxItems: 1
description:
GPIOs controlling the Main Device reset.
io-reset-gpios:
maxItems: 1
description:
GPIO controlling the I/O_RESET pin.
powerdown-gpios:
maxItems: 1
description:
GPIO controlling the EXT_PWR_DWN pin.
update-gpios:
maxItems: 1
description:
GPIO controlling the I/O_UPDATE pin.
profile-gpios:
minItems: 3
maxItems: 3
description:
GPIOs controlling the PROFILE[2:0] pins for profile selection.
sync-err-gpios:
maxItems: 1
description:
GPIO used to read SYNC_SMP_ERR pin status.
lock-detect-gpios:
maxItems: 1
description:
GPIO used to read PLL_LOCK pin status.
pwms:
maxItems: 1
description:
PWM used to drive the DRCTL pin, which controls the digital ramp
generator slope direction.
pwm-names:
items:
- const: drctl
adi,pll-enable:
type: boolean
description:
Enables the internal PLL. Applicable when external loop filter components
are connected to the PLL_LOOP_FILTER pin and low reference clock
frequencies are used, often provided by a crystal or by a single-ended
on-board oscillator.
adi,charge-pump-current-microamp:
minimum: 212
maximum: 387
default: 212
description:
PLL charge pump current in microamps. Only applicable when the internal
PLL is enabled. The value is rounded to the nearest supported step. This
value depends mostly on the loop filter design.
adi,refclk-out-drive-strength:
$ref: /schemas/types.yaml#/definitions/string
enum: [ disabled, low, medium, high ]
default: disabled
description:
Reference clock output (DRV0) drive strength. Only applicable when
the internal PLL is enabled.
dependencies:
adi,charge-pump-current-microamp: [ 'adi,pll-enable' ]
adi,refclk-out-drive-strength: [ 'adi,pll-enable' ]
lock-detect-gpios: [ 'adi,pll-enable' ]
interrupts: [ interrupt-names ]
pwms: [ pwm-names ]
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
- dvdd-io33-supply
- avdd33-supply
- dvdd18-supply
- avdd18-supply
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
dds@0 {
compatible = "adi,ad9910";
reg = <0>;
spi-max-frequency = <1000000>;
#clock-cells = <1>;
clock-output-names = "sync_clk", "pdclk", "sync_out";
clocks = <&ad9910_refclk>;
clock-names = "ref_clk";
dvdd-io33-supply = <&vdd_io33>;
avdd33-supply = <&vdd_a33>;
dvdd18-supply = <&vdd_d18>;
avdd18-supply = <&vdd_a18>;
reset-gpios = <&gpio 0 GPIO_ACTIVE_HIGH>;
io-reset-gpios = <&gpio 1 GPIO_ACTIVE_HIGH>;
powerdown-gpios = <&gpio 2 GPIO_ACTIVE_HIGH>;
update-gpios = <&gpio 3 GPIO_ACTIVE_HIGH>;
profile-gpios = <&gpio 4 GPIO_ACTIVE_HIGH>,
<&gpio 5 GPIO_ACTIVE_HIGH>,
<&gpio 6 GPIO_ACTIVE_HIGH>;
pwms = <&pwm 0 1000000 0>;
pwm-names = "drctl";
adi,pll-enable;
adi,charge-pump-current-microamp = <387>;
adi,refclk-out-drive-strength = "disabled";
};
};
...

View File

@ -26,16 +26,20 @@ description: |
properties:
compatible:
enum:
- invensense,icm42600
- invensense,icm42602
- invensense,icm42605
- invensense,icm42607
- invensense,icm42607p
- invensense,icm42622
- invensense,icm42631
- invensense,icm42686
- invensense,icm42688
oneOf:
- enum:
- invensense,icm42600
- invensense,icm42602
- invensense,icm42605
- invensense,icm42607
- invensense,icm42607p
- invensense,icm42622
- invensense,icm42631
- invensense,icm42686
- invensense,icm42688
- items:
- const: invensense,icm42630
- const: invensense,icm42631
reg:
maxItems: 1

View File

@ -40,10 +40,10 @@ examples:
#size-cells = <0>;
adux1020@64 {
compatible = "adi,adux1020";
reg = <0x64>;
interrupt-parent = <&msmgpio>;
interrupts = <24 IRQ_TYPE_LEVEL_HIGH>;
compatible = "adi,adux1020";
reg = <0x64>;
interrupt-parent = <&msmgpio>;
interrupts = <24 IRQ_TYPE_LEVEL_HIGH>;
};
};
...

View File

@ -45,6 +45,6 @@ examples:
compatible = "amstaos,tsl2591";
reg = <0x29>;
interrupts = <20 IRQ_TYPE_EDGE_FALLING>;
};
};
};
...

View File

@ -0,0 +1,44 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/light/capella,cm32181.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Capella CM32181 ambient light sensor
maintainers:
- Kevin Tsai <ktsai@capellamicro.com>
properties:
compatible:
const: capella,cm32181
reg:
maxItems: 1
vdd-supply: true
interrupts:
maxItems: 1
required:
- compatible
- reg
additionalProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
light-sensor@10 {
compatible = "capella,cm32181";
reg = <0x10>;
vdd-supply = <&vdd_3v3>;
interrupt-parent = <&gpio>;
interrupts = <17 IRQ_TYPE_EDGE_RISING>;
};
};

View File

@ -50,9 +50,9 @@ examples:
#size-cells = <0>;
sensor@44 {
compatible = "isil,isl29018";
reg = <0x44>;
interrupts-extended = <&msmgpio 61 IRQ_TYPE_LEVEL_HIGH>;
compatible = "isil,isl29018";
reg = <0x44>;
interrupts-extended = <&msmgpio 61 IRQ_TYPE_LEVEL_HIGH>;
};
};
...

View File

@ -9,15 +9,14 @@ title: LiteON LTR501 I2C Proximity and Light sensor
maintainers:
- Nikita Travkin <nikita@trvn.ru>
allOf:
- $ref: ../common.yaml#
properties:
compatible:
enum:
- liteon,ltr301
- liteon,ltr303
- liteon,ltr329
- liteon,ltr501
- liteon,ltr559
- liteon,ltr301
reg:
maxItems: 1
@ -36,6 +35,31 @@ required:
- compatible
- reg
allOf:
- $ref: ../common.yaml#
- if:
properties:
compatible:
contains:
enum:
- liteon,ltr329
then:
properties:
interrupts: false
- if:
properties:
compatible:
contains:
enum:
- liteon,ltr301
- liteon,ltr303
- liteon,ltr329
then:
properties:
proximity-near-level: false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>

View File

@ -39,8 +39,8 @@ examples:
#size-cells = <0>;
light@39 {
compatible = "onnn,noa1305";
reg = <0x39>;
compatible = "onnn,noa1305";
reg = <0x39>;
};
};
...

View File

@ -4,14 +4,14 @@
$id: http://devicetree.org/schemas/iio/light/stk33xx.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: |
Sensortek STK33xx I2C Ambient Light and Proximity sensor
title: Sensortek STK33xx/STK36C61 I2C Ambient Light and Proximity sensor
maintainers:
- Jonathan Cameron <jic23@kernel.org>
description: |
Ambient light and proximity sensor over an i2c interface.
description:
Ambient light and proximity sensor over an i2c interface. The STK36C61
additionally provides RGBC colour channels.
allOf:
- $ref: ../common.yaml#
@ -26,6 +26,7 @@ properties:
- items:
- enum:
- sensortek,stk3013
- sensortek,stk36c61
- const: sensortek,stk3310
reg:
@ -52,11 +53,11 @@ examples:
#size-cells = <0>;
stk3310@48 {
compatible = "sensortek,stk3310";
reg = <0x48>;
proximity-near-level = <25>;
interrupt-parent = <&gpio1>;
interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
compatible = "sensortek,stk3310";
reg = <0x48>;
proximity-near-level = <25>;
interrupt-parent = <&gpio1>;
interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
};
};
...

View File

@ -41,8 +41,8 @@ examples:
#size-cells = <0>;
light-sensor@29 {
compatible = "amstaos,tsl2581";
reg = <0x29>;
compatible = "amstaos,tsl2581";
reg = <0x29>;
};
};
...

View File

@ -74,13 +74,13 @@ examples:
#size-cells = <0>;
sensor@39 {
compatible = "amstaos,tsl2772";
reg = <0x39>;
interrupts-extended = <&msmgpio 61 IRQ_TYPE_EDGE_FALLING>;
vdd-supply = <&pm8941_l17>;
vddio-supply = <&pm8941_lvs1>;
amstaos,proximity-diodes = <0>;
led-max-microamp = <100000>;
compatible = "amstaos,tsl2772";
reg = <0x39>;
interrupts-extended = <&msmgpio 61 IRQ_TYPE_EDGE_FALLING>;
vdd-supply = <&pm8941_l17>;
vddio-supply = <&pm8941_lvs1>;
amstaos,proximity-diodes = <0>;
led-max-microamp = <100000>;
};
};
...

View File

@ -4,7 +4,8 @@
$id: http://devicetree.org/schemas/iio/light/vishay,veml6030.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: VEML3235, VEML3328, VEML6030, VEML6035 and VEML7700 Ambient Light Sensors (ALS)
title: VEML3235, VEML3328, VEML6030, VEML6031x00 series, VEML6035
and VEML7700 Ambient Light Sensors (ALS)
maintainers:
- Rishi Gupta <gupt21@gmail.com>
@ -23,6 +24,8 @@ description: |
https://www.vishay.com/docs/80131/veml3235.pdf
https://www.vishay.com/docs/84968/veml3328.pdf
https://www.vishay.com/docs/84366/veml6030.pdf
https://www.vishay.com/docs/80007/veml6031x00.pdf
https://www.vishay.com/docs/80008/veml6031x01.pdf
https://www.vishay.com/docs/84889/veml6035.pdf
https://www.vishay.com/docs/84286/veml7700.pdf
@ -32,6 +35,10 @@ properties:
- vishay,veml3235
- vishay,veml3328
- vishay,veml6030
- vishay,veml6031x00
- vishay,veml6031x01
- vishay,veml60311x00
- vishay,veml60311x01
- vishay,veml6035
- vishay,veml7700
@ -69,6 +76,8 @@ allOf:
properties:
compatible:
enum:
- vishay,veml6031x00
- vishay,veml6031x01
- vishay,veml6035
then:
properties:
@ -82,6 +91,8 @@ allOf:
enum:
- vishay,veml3235
- vishay,veml3328
- vishay,veml60311x00
- vishay,veml60311x01
- vishay,veml7700
then:
properties:
@ -101,10 +112,10 @@ examples:
#size-cells = <0>;
light-sensor@10 {
compatible = "vishay,veml6030";
reg = <0x10>;
interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
vdd-supply = <&vdd>;
compatible = "vishay,veml6030";
reg = <0x10>;
interrupts = <12 IRQ_TYPE_LEVEL_LOW>;
vdd-supply = <&vdd>;
};
};
...

View File

@ -45,10 +45,10 @@ examples:
#size-cells = <0>;
dps: pressure-sensor@76 {
compatible = "infineon,dps310";
reg = <0x76>;
#io-channel-cells = <0>;
vdd-supply = <&vref1>;
vddio-supply = <&vref2>;
compatible = "infineon,dps310";
reg = <0x76>;
#io-channel-cells = <0>;
vdd-supply = <&vref1>;
vddio-supply = <&vref2>;
};
};

View File

@ -0,0 +1,71 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/proximity/pulsedlight,lidar-lite-v2.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Pulsedlight/Garmin LIDAR-Lite range-finding sensors
maintainers:
- Matt Ranostay <matt@ranostay.sg>
- Rodrigo Gobbi <rodrigo.gobbi.7@gmail.com>
description: |
This binding covers the I2C interface of the Pulsedlight/Garmin
LIDAR-Lite v2 and v3 laser rangefinders.
Besides I2C, the mode control pin can also trigger acquisitions and
report the measured distance through a PWM signal, without using I2C
at all. That usage is bidirectional and non-cyclic, and is not
described by this binding. The same pin can also be used, while I2C
remains the active interface, as a plain status output signalling
when an acquisition has completed.
Datasheets:
https://static.garmin.com/pumac/LIDAR_Lite_v3_Operation_Manual_and_Technical_Specifications.pdf
https://github.com/PulsedLight3D/LIDAR-Lite-Documentation/blob/master/Docs/LIDAR-Lite-v2-Docs.pdf
properties:
compatible:
oneOf:
- items:
- enum:
- grmn,lidar-lite-v3
- const: pulsedlight,lidar-lite-v2
- const: pulsedlight,lidar-lite-v2
reg:
maxItems: 1
powerdown-gpios:
description: GPIO that can be driven low to shut off power to the device.
maxItems: 1
vdd-supply: true
interrupts:
description:
Mode control pin used as a status output, driven while the device is
busy performing an acquisition. Can be used to signal completion
instead of polling over I2C.
maxItems: 1
required:
- compatible
- reg
- vdd-supply
additionalProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
lidar@62 {
compatible = "grmn,lidar-lite-v3", "pulsedlight,lidar-lite-v2";
reg = <0x62>;
vdd-supply = <&vdd_5v0>;
};
};
...

View File

@ -57,8 +57,8 @@ examples:
#size-cells = <0>;
proximity@13 {
compatible = "vishay,vcnl3020";
reg = <0x13>;
vishay,led-current-microamp = <200000>;
compatible = "vishay,vcnl3020";
reg = <0x13>;
vishay,led-current-microamp = <200000>;
};
};

View File

@ -17,6 +17,7 @@ description: |
- LTC2986
- LTM2985
https://www.analog.com/media/en/technical-documentation/data-sheets/adt7604.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/2983fc.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/2984fb.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/29861fa.pdf

View File

@ -142,6 +142,13 @@ properties:
minItems: 2
maxItems: 4
spi-device-addr:
$ref: /schemas/types.yaml#/definitions/uint32-array
description:
Device addresses used when multiple peripherals share a single chip
select. The array allows one logical peripheral to comprise multiple
physical devices, with one address per physical device.
st,spi-midi-ns:
deprecated: true
description: |

View File

@ -62,6 +62,8 @@ properties:
# Aosong temperature & humidity sensors with I2C interface
- aosong,aht10
- aosong,aht20
- aosong,am2315
- aosong,am2320
- aosong,dht20
# Arduino microcontroller interface over SPI on UnoQ board
- arduino,unoq-mcu
@ -77,8 +79,6 @@ properties:
- atmel,atsha204a
# BPA-RS600: Power Supply
- blutek,bpa-rs600
# CM32181: Ambient Light Sensor
- capella,cm32181
# CM3232: Ambient Light Sensor
- capella,cm3232
# CM3323: Ambient Light Sensor
@ -400,8 +400,6 @@ properties:
- onnn,adt7462
# 48-Lane, 12-Port PCI Express Gen 2 (5.0 GT/s) Switch
- plx,pex8648
# Pulsedlight LIDAR range-finding sensor
- pulsedlight,lidar-lite-v2
# Renesas HS3001 Temperature and Relative Humidity Sensors
- renesas,hs3001
# Renesas ISL29501 time-of-flight sensor

View File

@ -0,0 +1,275 @@
.. SPDX-License-Identifier: GPL-2.0-only
=============
AD7768 driver
=============
ADC driver for Analog Devices Inc. AD7768 and AD7768-4 devices. The module name
is ``ad7768``.
Supported devices
=================
The following chips are supported by this driver:
* `AD7768 <https://www.analog.com/en/products/ad7768.html>`_ -
8-channel, 24-bit simultaneous sampling ADC
* `AD7768-4 <https://www.analog.com/en/products/ad7768-4.html>`_ -
4-channel, 24-bit simultaneous sampling ADC
Supported features
==================
Clock sources
-------------
The master clock source is selected using the ``clock-names`` device tree
property:
* ``mclk`` selects a CMOS clock on XTAL2/MCLK. CLK_SEL must be low and XTAL1
must be connected to DGND.
* ``xtal`` selects a crystal connected between XTAL1 and XTAL2. CLK_SEL must
be high. The driver drives FILTER/GPIO4 high and keeps channel 4 on the
AD7768 or channel 2 on the AD7768-4 enabled to maintain crystal excitation.
* ``lvds`` selects a differential clock on XTAL1 and XTAL2. CLK_SEL must be
high. The driver drives FILTER/GPIO4 low before enabling the LVDS input.
GPIO4 is reserved when ``xtal`` or ``lvds`` is selected.
Power modes
-----------
The AD7768 family supports three power and performance modes:
* **Low power mode** - Optimized for lowest power consumption
* **Median mode** - Balanced power and performance
* **Fast mode** - Highest performance with maximum sampling rates
The driver initializes the device in fast mode and uses the maximum fast-mode
output data rate as the default sampling frequency.
When buffered capture starts, the driver selects the lowest-noise mode that can
produce the requested output data rates for all enabled channels. Where output
data rates overlap, fast mode is preferred over median mode, and median mode is
preferred over low power mode. This prioritizes the lower RMS noise and higher
dynamic range offered by a faster mode at the same output data rate.
Data output configuration
-------------------------
The devices support flexible serial data output configurations:
AD7768 data lines
^^^^^^^^^^^^^^^^^
* 1 data line (DOUT0) - Standard single-lane output
* 2 data lines (DOUT0, DOUT1) - Dual-lane output for higher throughput
* 8 data lines (DOUT0-DOUT7) - Maximum throughput, one line per channel
AD7768-4 data lines
^^^^^^^^^^^^^^^^^^^
* 1 data line (DOUT0) - Standard single-lane output
* 4 data lines (DOUT0-DOUT3) - Maximum throughput, one line per channel
The number of data lines can be configured via the ``adi,data-lines-number``
device tree property. If omitted, the driver uses the maximum supported by the
selected variant: eight lines for AD7768 and four lines for AD7768-4.
Channel configuration
---------------------
Each channel can be individually configured with:
Channel modes
^^^^^^^^^^^^^
* **Mode A** - First set of filter and decimation settings
* **Mode B** - Second set of filter and decimation settings
The hardware provides two mode profiles (A and B), each holding one
(frequency, filter) combination. When buffered capture is started,
enabled channels are grouped by their configured (frequency, filter)
pair. Up to two distinct groups are supported; the driver automatically
assigns each group to a mode slot and programs the hardware accordingly.
If the enabled channels request more than two distinct pairs, buffer setup
fails and capture does not start.
Precharge and reference buffers
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Per-channel buffer control for optimal signal integrity:
* Positive input precharge buffer (``adi,prechargebuf-pos-enable``)
* Negative input precharge buffer (``adi,prechargebuf-neg-enable``)
* Positive reference buffer (``adi,refbuf-pos-enable``)
* Negative reference buffer (``adi,refbuf-neg-enable``)
Common mode voltage
-------------------
The VCM pin provides a buffered common-mode voltage output used to bias
the analog inputs. The driver exposes this as a standard voltage regulator
provider under a ``regulators`` subnode in the device tree. Supported
output voltage levels are:
* (AVDD1 - AVSS) / 2 - Mid-supply (hardware default), reported as half the
voltage provided by ``avdd1-supply``
* 1,650,000 µV - 1.65V
* 2,500,000 µV - 2.5V
* 2,140,000 µV - 2.14V
The regulator can be enabled and disabled at runtime using the standard
regulator framework interfaces.
The VCM circuitry is associated with channel 0. When VCM is used externally,
``channel@0`` must be present in the device tree and channel 0 must remain
enabled in the active scan mask. Placing channel 0 in standby disables the VCM
output.
Filter types
------------
Two digital filter types are available:
* **Wideband** - Optimized for wide bandwidth applications
* **Sinc5** - Fifth-order sinc filter for high rejection of out-of-band noise
IIO backend support
-------------------
The driver integrates with IIO backends (e.g., AXI ADC) for high-speed data
capture and DMA operations. Features include:
* Automatic channel enable/disable based on scan mask
* CRC on data interface. CRC replaces the header every 4th output sample.
* High-throughput buffered data acquisition
GPIO controller
---------------
The AD7768 includes a 5-pin GPIO controller for auxiliary digital I/O
operations. The GPIO pins can be configured as inputs or outputs.
GPIO4 is reserved when a crystal or LVDS master clock is used. GPIO0 through
GPIO3 remain available in these configurations.
Device attributes
=================
The following IIO attributes are available for each enabled channel:
Voltage scale
-------------
.. list-table::
:header-rows: 1
:widths: 40 60
* - Attribute
- Description
* - ``in_voltage<N>_scale``
- Scale in millivolts per least significant bit for signed 24-bit data,
calculated as twice the differential reference voltage used by channel
N divided by 2\ :sup:`24`.
Sampling frequency
------------------
.. list-table::
:header-rows: 1
:widths: 40 60
* - Attribute
- Description
* - ``in_voltage<N>_sampling_frequency``
- Requested sampling frequency in Hz for channel N. Enabled channels are
grouped into up to two profiles at capture time.
* - ``in_voltage<N>_sampling_frequency_available``
- Available sampling frequencies in Hz for channel N across all power
modes, based on the master clock frequency. Buffer setup fails if no
single power mode supports the frequencies requested by all enabled
channels.
Filter configuration
---------------------
.. list-table::
:header-rows: 1
:widths: 40 60
* - Attribute
- Description
* - ``in_voltage<N>_filter_type``
- Requested filter type for channel N: "wideband" or "sinc5". It is
grouped with sampling frequency at capture time.
* - ``in_voltage<N>_filter_type_available``
- Available filter types for channel N: "wideband sinc5".
Per-channel calibration
-----------------------
.. list-table::
:header-rows: 1
:widths: 40 60
* - Attribute
- Description
* - ``in_voltage<N>_calibbias``
- Signed 24-bit two's complement channel offset register value.
* - ``in_voltage<N>_calibscale``
- Raw unsigned 24-bit channel gain register value.
* - ``in_voltage<N>_convdelay``
- Per-channel conversion delay. The driver exposes the sync phase offset
value in seconds with picosecond precision. Resolution and valid range
depend on the decimation ratio in use (see datasheet
Table 32).
Device buffers
==============
This driver supports IIO buffered data acquisition through IIO backends.
When used with compatible backends like the AXI ADC, it provides:
* High-speed simultaneous sampling across all enabled channels
* Hardware-driven data capture
* DMA-based data transfer for minimal CPU overhead
* CRC error detection
See :doc:`iio_devbuf` for more information about IIO device buffers.
Example usage
=============
.. code-block:: bash
# Read current sampling frequency for channel 0
cat /sys/bus/iio/devices/iio:device0/in_voltage0_sampling_frequency
# Update sampling frequency for channel 0
echo 8000 > /sys/bus/iio/devices/iio:device0/in_voltage0_sampling_frequency
# Read current filter type for channel 0
cat /sys/bus/iio/devices/iio:device0/in_voltage0_filter_type
# List available filter types for channel 0
cat /sys/bus/iio/devices/iio:device0/in_voltage0_filter_type_available
# Update filter type for channel 0 to wideband
echo wideband > /sys/bus/iio/devices/iio:device0/in_voltage0_filter_type
# Buffer setup fails if enabled channels request more than two distinct
# (sampling frequency, filter type) combinations.
# Read calibration scale for channel 0
cat /sys/bus/iio/devices/iio:device0/in_voltage0_calibscale
# Read conversion delay for channel 0
cat /sys/bus/iio/devices/iio:device0/in_voltage0_convdelay
Unimplemented features
======================
* CRC message every 16 samples (CRC_SEL configuration) - currently only
supports CRC every 4 samples

View File

@ -0,0 +1,792 @@
.. SPDX-License-Identifier: GPL-2.0-only
=============
AD9910 driver
=============
Direct Digital Synthesizer (DDS) driver for the Analog Devices Inc. AD9910.
The module name is ``ad9910``.
* `AD9910 <https://www.analog.com/en/products/ad9910.html>`_
The AD9910 is a 1 GSPS DDS with a 14-bit DAC, controlled over SPI. The driver
exposes the device through a hierarchy of typed IIO output channels. The root
``phy`` channel controls the system clock and full-scale output current.
Sub-channels provide independent control over single tone profiles, parallel
port modulation, digital ramp generation (DRG), RAM playback and output shift
keying (OSK).
Channel hierarchy
=================
The driver exposes the following IIO output channels, each identified by a
unique channel number and a human-readable label. The ``phy`` channel is the
root of the hierarchy. Changing its ``sampling_frequency`` reconfigures the
system clock (SYSCLK) which affects all other channels.
.. flat-table::
:header-rows: 1
* - Channel
- Label
- Parent
- Description
* - ``out_altcurrent100``
- ``phy``
-
- Physical output: system clock and full-scale output current (:math:`I_{FS}`).
See `Physical channel`_.
* - ``out_altcurrent110`` ... ``out_altcurrent117``
- ``profile0`` ... ``profile7``
- ``phy``
- Single tone control: frequency, phase, amplitude, enable.
See `Single Tone mode`_.
* - ``out_altcurrent120``
- ``parallel_amplitude``
- ``phy``
- Parallel port amplitude channel.
See `Parallel Port mode`_.
* - ``out_phase120``
- ``parallel_phase``
- ``phy``
- Parallel port phase channel.
* - ``out_frequency120``
- ``parallel_frequency``
- ``phy``
- Parallel port frequency channel: ``scale`` sets the FM gain
(power-of-2 multiplier), ``offset`` sets the base FTW.
* - ``out_altcurrent121``
- ``parallel_polar_amplitude``
- ``phy``
- Parallel polar amplitude channel: ``scale`` is the amplitude
resolution, ``offset`` is the amplitude bias (lower 6 bits of ASF).
* - ``out_phase121``
- ``parallel_polar_phase``
- ``phy``
- Parallel polar phase channel: ``scale`` is the phase resolution,
``offset`` is the phase bias (lower 8 bits of POW).
* - ``out_frequency130``
- ``drg_frequency``
- ``phy``
- DRG frequency channel: ``en`` selects and enables the DRG with
frequency as the ramp target.
See `Digital ramp generator (DRG)`_.
* - ``out_frequency131``
- ``drg_rising_frequency``
- ``drg_frequency``
- DRG frequency rising-ramp parameters: limit code, dwell enable,
ramp clock, rate of change.
* - ``out_frequency132``
- ``drg_falling_frequency``
- ``drg_frequency``
- DRG frequency falling-ramp parameters: limit code, dwell enable,
ramp clock, rate of change.
* - ``out_phase130``
- ``drg_phase``
- ``phy``
- DRG phase channel: ``en`` selects and enables the DRG with phase
as the ramp target.
See `Digital ramp generator (DRG)`_.
* - ``out_phase131``
- ``drg_rising_phase``
- ``drg_phase``
- DRG phase rising-ramp parameters: limit code, dwell enable, ramp clock,
rate of change.
* - ``out_phase132``
- ``drg_falling_phase``
- ``drg_phase``
- DRG phase falling-ramp parameters: limit code, dwell enable, ramp clock,
rate of change.
* - ``out_altcurrent130``
- ``drg_amplitude``
- ``phy``
- DRG amplitude channel: ``en`` selects and enables the DRG with
amplitude as the ramp target.
See `Digital ramp generator (DRG)`_.
* - ``out_altcurrent131``
- ``drg_rising_amplitude``
- ``drg_amplitude``
- DRG amplitude rising-ramp parameters: limit code, dwell enable,
ramp clock, rate of change.
* - ``out_altcurrent132``
- ``drg_falling_amplitude``
- ``drg_amplitude``
- DRG amplitude falling-ramp parameters: limit code, dwell enable,
ramp clock, rate of change.
* - ``out_altcurrent140``
- ``ram``
- ``phy``
- RAM playback: enable, frequency, phase and sampling frequency for
the active profile. See `RAM mode`_.
* - ``out_altcurrent150``
- ``osk``
- ``phy``
- Output shift keying (OSK): enable, amplitude code, ramp rate,
rate of change. See `Output Shift Keying (OSK)`_.
DDS modes
=========
The AD9910 supports multiple modes of operation that can be configured
independently or in combination. Each DDS core parameter (frequency, phase
and amplitude) can come from different sources, but only one is active at a
time. This activation depends on a priority list, which is based on the enable
and destination configurations for such modes. The following tables are
extracted from the AD9910 datasheet and summarize the control parameters for
each mode and their priority when multiple sources are enabled simultaneously:
.. flat-table:: DDS Frequency Control
:header-rows: 1
* - Priority
- Data Source
- Conditions
* - Highest Priority
- RAM
- RAM enabled and data destination is frequency
* -
- DRG
- DRG enabled and data destination is frequency
* -
- Parallel data and Frequency Tuning Word, FTW (frequency_offset)
- Parallel data port enabled and data destination is frequency
* -
- FTW register (frequency)
- RAM enabled and data destination is not frequency
* - Lowest Priority
- FTW (frequency) in single tone channel for the active profile
- All other cases
.. flat-table:: DDS Phase Control
:header-rows: 1
* - Priority
- Data Source
- Conditions
* - Highest Priority
- RAM
- RAM enabled and data destination is phase or polar
* -
- DRG
- DRG enabled and data destination is phase
* -
- Parallel data port
- Parallel data port enabled and data destination is phase
* -
- Parallel data port and Phase Offset Word, POW register LSBs (phase_offset)
- Parallel data port enabled and data destination is polar
* -
- POW register (phase)
- RAM enabled and destination is not phase nor polar
* - Lowest Priority
- POW (phase) in single tone channel for the active profile
- All other cases
.. flat-table:: DDS Amplitude Control
:header-rows: 1
* - Priority
- Data Source
- Conditions
* - Highest Priority
- Amplitude Scale Factor, ASF register and OSK generator
- OSK enabled
* -
- RAM
- RAM enabled and data destination is amplitude or polar
* -
- DRG
- DRG enabled and data destination is amplitude
* -
- Parallel data port
- Parallel data port enabled and data destination is amplitude
* -
- Parallel data port and ASF register LSBs (scale_offset)
- Parallel data port enabled and data destination is polar
* - Lowest Priority
- ASF (scale) in single tone channel for the active profile
- (Amplitude scale is already enabled by default)
While debugging or testing, the debug attributes ``frequency_source``,
``phase_source`` and ``amplitude_source`` can be used to read the label of
the channel that is actively controlling the correspondent DDS parameter,
which reflects the priority list described above.
Single Tone mode
----------------
Single tone is the baseline operating mode. The ``profileY`` channels
provide enable, frequency, phase and amplitude control:
.. flat-table::
:header-rows: 1
* - Attribute
- Unit
- Description
* - ``en``
- boolean (0 or 1)
- Enable/disable profile Y. Only one profile can be active at a
time. When enabling a profile it disables the current active profile.
Disabling an active profile brings the device to a powered down state.
* - ``frequency``
- Hz
- Output frequency. Range :math:`[0, f_{SYSCLK} / 2)`. Stored in the
profile's frequency tuning word (FTW).
* - ``phase``
- rad
- Phase offset. Range :math:`[0, 2\pi)`. Stored in the profile's phase
offset word (POW).
* - ``raw``
- integer
- Amplitude scale factor code. Range :math:`[0, 16383]`. Stored in the
profile's amplitude scale factor (ASF) register. The physical output
amplitude is ``raw * scale`` where ``scale`` is read from the ``phy``
channel.
Profile switching is allowed while RAM mode is enabled. In that case single
tone parameters are stored in a shadow register and are not written to
hardware until RAM mode is disabled.
Usage examples
^^^^^^^^^^^^^^
Configure a 100 MHz tone in profile 2 and set it as the active profile:
.. code-block:: bash
echo 100000000 > /sys/bus/iio/devices/iio\:device0/out_altcurrent112_frequency
echo 0 > /sys/bus/iio/devices/iio\:device0/out_altcurrent112_phase
echo 16383 > /sys/bus/iio/devices/iio\:device0/out_altcurrent112_raw
# Activate profile 2
echo 1 > /sys/bus/iio/devices/iio\:device0/out_altcurrent112_en
Read back the current single tone frequency:
.. code-block:: bash
cat /sys/bus/iio/devices/iio\:device0/out_altcurrent112_frequency
Parallel Port mode
------------------
The parallel port allows real-time modulation of DDS parameters through a
16-bit external data bus. The driver exposes separate typed channels for each
modulation target.
Non-polar modulation
^^^^^^^^^^^^^^^^^^^^
In non-polar mode each DDS parameter is controlled by an independent 16-bit bus
input. The parallel port channels expose the resolution and base offset of their
respective bus inputs:
.. flat-table::
:header-rows: 1
* - Channel
- Attribute
- Unit
- Description
* - ``out_phase120``
- ``scale``
- rad
- Phase resolution per parallel bus LSB. Fixed at :math:`\pi / 2^{15}`
rad/LSB (full 16-bit POW resolution).
* - ``out_frequency120``
- ``scale``
- Hz
- Outputs the frequency scale evaluated as
:math:`f_{SYSCLK} \cdot FM / 2^{32}`. Assuming that :math:`f_{SYSCLK}` is
fixed, it is used to configure the modulation gain :math:`FM`, which is a
power-of-2 multiplier in range :math:`[1, 32768]`. Writing to this
attribute rounds up to the nearest :math:`FM` power of 2.
* - ``out_frequency120``
- ``offset``
- Hz
- Outputs the frequency offset in raw units evaluated as :math:`FTW / FM`.
Assuming that :math:`FM` is fixed, it is used to configure the FTW
register, which is a 32-bit unsigned integer.
Polar modulation
^^^^^^^^^^^^^^^^
In polar mode a single 16-bit bus word carries both amplitude (high byte)
and phase (low byte). The ``parallel_polar_amplitude`` and
``parallel_polar_phase`` channels configure the bias applied to the low-order
bits of the ASF and POW registers respectively:
.. flat-table::
:header-rows: 1
* - Channel
- Attribute
- Unit
- Description
* - ``out_altcurrent121``
- ``scale``
- mA/LSB
- Full-scale amplitude resolution (read-only, fixed at :math:`I_{FS} / 2^{8}`).
* - ``out_altcurrent121``
- ``offset``
- fractional (raw units)
- Amplitude bias. Lower 6 bits of ASF register. Range :math:`[0, 1)`.
* - ``out_phase121``
- ``scale``
- rad/LSB
- Phase resolution (read-only, fixed at :math:`\pi / 2^{7}`).
* - ``out_phase121``
- ``offset``
- fractional (raw units)
- Phase bias. Lower 8 bits of POW register. Range :math:`[0, 1)`.
Usage examples
^^^^^^^^^^^^^^
Set parallel port frequency modulation with a modulation gain of 16 and a 50 MHz
offset:
.. code-block:: bash
# f_SYSCLK = 1 GHz, FM = 16
# frequency scale = f_SYSCLK * FM / 2^32 = 3.725290298
echo 3.725290298 > /sys/bus/iio/devices/iio\:device0/out_frequency120_scale
# frequency offset = 50 MHz / scale = 50e6 / 13421772.8
echo 13421772.8 > /sys/bus/iio/devices/iio\:device0/out_frequency120_offset
One should choose a frequency scale that allows all the desired frequencies
to be represented in the 16-bit bus range, i.e.,
:math:`scale = (f_{max} - f_{min}) / 2^{16}`.
Digital ramp generator (DRG)
----------------------------
The DRG produces linear frequency, phase or amplitude sweeps using dedicated
hardware. The active ramp target (destination) is selected by enabling the
corresponding typed channel at channel number 130:
- ``out_frequency130`` (label ``drg_frequency``) — ramp targets frequency
- ``out_phase130`` (label ``drg_phase``) — ramp targets phase
- ``out_altcurrent130`` (label ``drg_amplitude``) — ramp targets amplitude
Writing ``en=1`` to one of these channels enables the DRG and switches its
destination. Writing ``en=0`` disables the DRG if the channel is the current
active destination; writing to an already-inactive destination is a no-op.
Each destination channel also exposes a read-only ``scale`` attribute
reporting the physical quantity per ramp register LSB, which allows converting
raw limit codes to physical values.
The six ramp channels:
- ``out_frequency131`` (label ``drg_rising_frequency``)
- ``out_frequency132`` (label ``drg_falling_frequency``)
- ``out_phase131`` (label ``drg_rising_phase``)
- ``out_phase132`` (label ``drg_falling_phase``)
- ``out_altcurrent131`` (label ``drg_rising_amplitude``)
- ``out_altcurrent132`` (label ``drg_falling_amplitude``)
configure ascending and descending ramp parameters.
Destination channel attributes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. flat-table::
:header-rows: 1
* - Attribute
- Unit
- Description
* - ``en``
- boolean
- Enable the DRG with this channel as the active destination. Only one
destination can be active at a time.
* - ``scale``
- Hz/LSB, rad/LSB or mA/LSB
- Read-only. Physical quantity per raw units. Multiply a ramp
rising/falling channel ``raw`` value by this scale to get the physical
ramp target.
Ramp channel attributes
^^^^^^^^^^^^^^^^^^^^^^^
.. flat-table::
:header-rows: 1
* - Attribute
- Unit
- Description
* - ``dwell_en``
- boolean
- Enable dwell at the ramp limit. When disabled, the ramp
auto-transitions at this limit without waiting for the DRCTL pin.
Disabling both creates a bidirectional continuous ramp (triangular
pattern). Other combinations create single-shot ramps at the DRCTL
pin transition.
* - ``raw``
- integer (64-bit)
- Ramp limit expressed as a raw DRG register code in
:math:`[0, 2^{32}-1]`. The physical value is ``raw * scale`` where
``scale`` is read from the active destination channel.
* - ``sampling_frequency``
- Hz
- Ramp clock rate. Controlled by an integer divider; the written value
is adjusted to the nearest supported rate.
* - ``raw_roc``
- /s
- Rate of change. Number of register codes advanced per second, computed
from the hardware step size and the current ramp clock. Writing
requires ``sampling_frequency`` to be configured first.
Usage examples
^^^^^^^^^^^^^^
Configure a frequency sweep from 40 MHz to 60 MHz with a rate of change of
25 GHz/s:
.. code-block:: bash
# Disable dwell on both limits for a bidirectional continuous ramp
echo 0 > /sys/bus/iio/devices/iio\:device0/out_frequency131_dwell_en
echo 0 > /sys/bus/iio/devices/iio\:device0/out_frequency132_dwell_en
# Set ramp rate at 250 MHz
echo 250000000 > /sys/bus/iio/devices/iio\:device0/out_frequency131_sampling_frequency
echo 250000000 > /sys/bus/iio/devices/iio\:device0/out_frequency132_sampling_frequency
# read the frequency scale to convert physical values to raw units
cat /sys/bus/iio/devices/iio\:device0/out_frequency130_scale
0.232830643650
# 40 MHz / 0.232830643650 = 171798692
echo 171798692 > /sys/bus/iio/devices/iio\:device0/out_frequency131_raw
# 60 MHz / 0.232830643650 = 257698038
echo 257698038 > /sys/bus/iio/devices/iio\:device0/out_frequency132_raw
# 25 GHz/s / 0.232830643650 = 107374182402
echo 107374182402 > /sys/bus/iio/devices/iio\:device0/out_frequency131_raw_roc
echo 107374182402 > /sys/bus/iio/devices/iio\:device0/out_frequency132_raw_roc
# Enable the DRG with frequency as the destination
echo 1 > /sys/bus/iio/devices/iio\:device0/out_frequency130_en
RAM mode
--------
The AD9910 contains a 1024 x 32-bit RAM that can be loaded with waveform data
and played back to modulate frequency, phase, amplitude, or polar (phase +
amplitude) parameters.
RAM control channel attributes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. flat-table::
:header-rows: 1
* - Attribute
- Unit
- Description
* - ``en``
- boolean
- Enable/disable RAM playback. Toggling swaps profile registers between
single tone and RAM configurations across all 8 profiles.
* - ``frequency``
- Hz
- Frequency tuning word used as the single tone frequency when
RAM destination is not ``frequency``. Range: :math:`[0, f_{SYSCLK} / 2)`.
* - ``phase``
- rad
- Phase offset word used as the single tone phase when RAM destination
is not ``phase``. Range: :math:`[0, 2\pi)`.
* - ``sampling_frequency``
- Hz
- RAM playback step rate of the active profile, which controls how fast
the address counter advances. Controlled by an integer divider; the
written value is adjusted to the nearest supported rate.
Loading RAM data
^^^^^^^^^^^^^^^^
RAM data is loaded through the firmware upload framework. The driver registers
a firmware upload sysfs entry named ``iio_deviceX:ram``. The firmware data
follows a binary format (version 1) with an 80-byte header followed by data
words. All fields are big-endian.
.. flat-table:: RAM firmware header (80 bytes)
:header-rows: 1
* - Offset
- Size
- Field
- Description
* - 0
- 4
- ``magic``
- Magic number: ``0x00AD9910``
* - 4
- 2
- ``version``
- Format version: ``0x0001``
* - 6
- 2
- ``wcount``
- Number of 32-bit RAM data words (0--1024)
* - 8
- 4
- ``crc``
- CRC32 checksum over ``cfr1``, ``profiles`` and ``words``
* - 12
- 4
- ``cfr1``
- CFR1 register value. Only RAM-relevant bits are used:
bits [30:29] set data destination (00: frequency, 01: phase,
10: amplitude, 11: polar); bits [20:17] set internal profile
control (see datasheet Table 14)
* - 16
- 64
- ``profiles[0..7]``
- 8 sets of 8-byte RAM profile configurations (see below)
* - 80
- 4 x wcount
- ``words[]``
- RAM data words in reverse order
Each 8-byte profile entry contains:
.. flat-table:: RAM profile entry (8 bytes)
:header-rows: 1
* - Bits
- Field
- Description
* - [55:40]
- Address step rate
- Controls playback speed for this profile
* - [39:30]
- End address
- Last RAM address for this profile
* - [23:14]
- Start address
- First RAM address for this profile
* - [5]
- No-dwell high
- No-dwell at high limit (ramp-up mode)
* - [3]
- Zero-crossing
- Zero-crossing enable (direct-switch mode)
* - [2:0]
- Operating mode
- 000: direct switch, 001: ramp-up, 010: bidirectional,
011: bidirectional continuous, 100: ramp-up continuous
Usage examples
^^^^^^^^^^^^^^
Configure RAM mode with firmware data and enable it:
.. code-block:: bash
# Load RAM data via firmware upload
echo 1 > /sys/class/firmware/iio\:device0\:ram/loading
cat ad9910-ram.bin > /sys/class/firmware/iio\:device0\:ram/data
echo 0 > /sys/class/firmware/iio\:device0\:ram/loading
# Enable RAM mode
echo 1 > /sys/bus/iio/devices/iio\:device0/out_altcurrent140_en
Output Shift Keying (OSK)
-------------------------
OSK controls the output amplitude envelope, allowing the output to be ramped
on/off rather than switched abruptly.
.. flat-table::
:header-rows: 1
* - Attribute
- Unit
- Description
* - ``en``
- boolean (0 or 1)
- Enable/disable OSK.
* - ``raw``
- integer
- Target amplitude code. 14-bit ASF field. Range: :math:`[0, 16383]`.
The physical output amplitude is ``raw * scale`` where ``scale`` is read
from the ``phy`` channel.
* - ``raw_roc``
- /s
- Amplitude ramp rate. Writing a non-zero value enables automatic OSK
and selects the closest hardware step size. Writing ``0`` disables
automatic ramping (manual control via ``raw``). Writing the maximum
available value enables pin-controlled immediate transition.
* - ``raw_roc_available``
- /s
- Lists the available ``raw_roc`` values based on the current
``sampling_frequency``. The first value is always ``0`` (disabled) and
the last value corresponds to pin-controlled immediate mode.
* - ``sampling_frequency``
- Hz
- OSK ramp clock. Controlled by an integer divider; the written value
is adjusted to the nearest supported rate.
Usage examples
^^^^^^^^^^^^^^
Enable OSK with automatic ramping:
.. code-block:: bash
# Set ramp rate 1MHz
echo 1000000 > /sys/bus/iio/devices/iio\:device0/out_altcurrent150_sampling_frequency
# Check available rate of change values
cat /sys/bus/iio/devices/iio\:device0/out_altcurrent150_raw_roc_available
0 1000000 2000000 4000000 8000000 16383000000
# Enable automatic OSK with a rate of change of 8000000 raw units/s
echo 8000000 > /sys/bus/iio/devices/iio\:device0/out_altcurrent150_raw_roc
# Enable OSK
echo 1 > /sys/bus/iio/devices/iio\:device0/out_altcurrent150_en
Enable pin-controlled immediate OSK:
.. code-block:: bash
# Enable OSK in manual mode (no ramp)
echo 0 > /sys/bus/iio/devices/iio\:device0/out_altcurrent150_raw_roc
echo 1 > /sys/bus/iio/devices/iio\:device0/out_altcurrent150_en
# Set target amplitude to full scale
echo 16383 > /sys/bus/iio/devices/iio\:device0/out_altcurrent150_raw
Physical channel
================
The ``phy`` channel provides device-level control:
.. flat-table::
:header-rows: 1
* - Attribute
- Unit
- Description
* - ``sampling_frequency``
- Hz
- System clock (SYSCLK) frequency. When the internal PLL is enabled
(via the ``adi,pll-enable`` devicetree property), configures the PLL
multiplier (Range: :math:`[420, 1000]` MHz). Without PLL, the reference
clock can only be divided by 2.
* - ``scale``
- mA/LSB
- Full-scale DAC output current per amplitude code LSB, which is evaluated
as :math:`I_{FS} / 2^{14}`. Shared across all ``altcurrent`` channels.
Setting this attribute reconfigures the auxiliary DAC full-scale code and
updates the effective amplitude resolution for single tone profiles,
DRG amplitude ramps and OSK.
* - ``powerdown``
- boolean (0 or 1)
- Software power-down. Writing 1 powers down the digital core, DAC,
reference clock input and auxiliary DAC simultaneously.
Usage examples
--------------
Set the system clock to 1 GHz:
.. code-block:: bash
echo 1000000000 > /sys/bus/iio/devices/iio\:device0/out_altcurrent100_sampling_frequency
Read current system clock frequency:
.. code-block:: bash
cat /sys/bus/iio/devices/iio\:device0/out_altcurrent100_sampling_frequency
Power down the device:
.. code-block:: bash
echo 1 > /sys/bus/iio/devices/iio\:device0/out_altcurrent100_powerdown

View File

@ -1,24 +1,30 @@
.. SPDX-License-Identifier: GPL-2.0
===============
ADE9000 driver
===============
======================
ADE9000/ADE9078 driver
======================
This driver supports Analog Device's ADE9000 energy measurement IC on SPI bus.
This driver supports Analog Devices' ADE9000 and ADE9078 energy measurement
ICs on SPI bus.
1. Supported devices
====================
* `ADE9000 <https://www.analog.com/media/en/technical-documentation/data-sheets/ADE9000.pdf>`_
* `ADE9078 <https://www.analog.com/media/en/technical-documentation/data-sheets/ADE9078.pdf>`_
The ADE9000 is a highly accurate, fully integrated, multiphase energy and power
quality monitoring device. Superior analog performance and a digital signal
processing (DSP) core enable accurate energy monitoring over a wide dynamic
range. An integrated high end reference ensures low drift over temperature
with a combined drift of less than ±25 ppm/°C maximum for the entire channel
including a programmable gain amplifier (PGA) and an analog-to-digital
The ADE9000 and ADE9078 are highly accurate, fully integrated, multiphase energy
and power quality monitoring devices. Superior analog performance and a digital
signal processing (DSP) core enable accurate energy monitoring over a wide
dynamic range. An integrated high end reference ensures low drift over
temperature with a combined drift of less than ±25 ppm/°C maximum for the entire
channel including a programmable gain amplifier (PGA) and an analog-to-digital
converter (ADC).
The ADE9078 does not provide the on-chip dip/swell (sag) detection available on
the ADE9000, so the RMS voltage swell/dip events described below are only
available on the ADE9000.
2. Device attributes
====================

View File

@ -4,7 +4,7 @@
ADIS16475 driver
================
This driver supports Analog Device's IMUs on SPI bus.
This driver supports Analog Devices' IMUs on SPI bus.
1. Supported devices
====================

View File

@ -4,7 +4,7 @@
ADIS16480 driver
================
This driver supports Analog Device's IMUs on SPI bus.
This driver supports Analog Devices' IMUs on SPI bus.
1. Supported devices
====================

View File

@ -4,7 +4,7 @@
ADIS16550 driver
================
This driver supports Analog Device's IMUs on SPI bus.
This driver supports Analog Devices' IMUs on SPI bus.
1. Supported devices
====================

View File

@ -4,7 +4,7 @@
ADXL313 driver
===============
This driver supports Analog Device's ADXL313 on SPI/I2C bus.
This driver supports Analog Devices' ADXL313 on SPI/I2C bus.
1. Supported devices
====================

View File

@ -4,7 +4,7 @@
ADXL345 driver
===============
This driver supports Analog Device's ADXL345/375 on SPI/I2C bus.
This driver supports Analog Devices' ADXL345/375 on SPI/I2C bus.
1. Supported Devices
====================

View File

@ -4,7 +4,7 @@
ADXL380 driver
===============
This driver supports Analog Device's ADXL380/382 on SPI/I2C bus.
This driver supports Analog Devices' ADXL380/382 on SPI/I2C bus.
1. Supported devices
====================
@ -39,13 +39,13 @@ specific device folder path ``/sys/bus/iio/devices/iio:deviceX``.
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_scale | Scale for the accelerometer channels. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_filter_high_pass_3db_frequency | Low pass filter bandwidth. |
| in_accel_filter_high_pass_3db_frequency | High pass filter bandwidth. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_filter_high_pass_3db_frequency_available | Available low pass filter bandwidth configurations. |
| in_accel_filter_high_pass_3db_frequency_available | Available high pass filter bandwidth configurations. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_filter_low_pass_3db_frequency | High pass filter bandwidth. |
| in_accel_filter_low_pass_3db_frequency | Low pass filter bandwidth. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_filter_low_pass_3db_frequency_available | Available high pass filter bandwidth configurations. |
| in_accel_filter_low_pass_3db_frequency_available | Available low pass filter bandwidth configurations. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_x_calibbias | Calibration offset for the X-axis accelerometer channel. |
+---------------------------------------------------+----------------------------------------------------------+

View File

@ -29,7 +29,9 @@ Industrial I/O Kernel Drivers
ad7380
ad7606
ad7625
ad7768
ad7944
ad9910
ade9000
adf41513
adis16475

View File

@ -640,6 +640,7 @@ F: drivers/iio/accel/adxl355_spi.c
ADXL367 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
@ -1468,6 +1469,7 @@ L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/dac/adi,ad3530r.yaml
F: Documentation/devicetree/bindings/iio/dac/adi,ad5710r.yaml
F: drivers/iio/dac/ad3530r.c
ANALOG DEVICES INC AD3552R DRIVER
@ -1517,6 +1519,7 @@ F: drivers/iio/adc/ad4080.c
ANALOG DEVICES INC AD4130 DRIVER
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
@ -1571,6 +1574,14 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad4851.yaml
F: drivers/iio/adc/ad4851.c
ANALOG DEVICES INC AD5529R DRIVER
M: Janani Sunil <janani.sunil@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/dac/adi,ad5529r.yaml
F: drivers/iio/dac/ad5529r.c
ANALOG DEVICES INC AD5706R DRIVER
M: Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
L: linux-iio@vger.kernel.org
@ -1622,6 +1633,7 @@ F: drivers/iio/dac/ad7293.c
ANALOG DEVICES INC AD74115 DRIVER
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
@ -1630,6 +1642,7 @@ F: drivers/iio/addac/ad74115.c
ANALOG DEVICES INC AD74413R DRIVER
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
M: Antoniu Miclaus <antoniu.miclaus@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
@ -1657,6 +1670,15 @@ F: Documentation/devicetree/bindings/iio/adc/adi,ad7768-1.yaml
F: drivers/iio/adc/ad7768-1.c
F: include/dt-bindings/iio/adc/adi,ad7768-1.h
ANALOG DEVICES INC AD7768 DRIVER
M: Janani Sunil <janani.sunil@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad7768.yaml
F: Documentation/iio/ad7768.rst
F: drivers/iio/adc/ad7768.c
ANALOG DEVICES INC AD7780 DRIVER
M: Michael Hennerich <Michael.Hennerich@analog.com>
M: Renato Lui Geh <renatogeh@gmail.com>
@ -1702,6 +1724,17 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/dac/adi,ad9739a.yaml
F: drivers/iio/dac/ad9739a.c
ANALOG DEVICES INC AD9910 DRIVER
M: Rodrigo Alencar <rodrigo.alencar@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/ABI/testing/debugfs-iio-ad9910
F: Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9910
F: Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml
F: Documentation/iio/ad9910.rst
F: drivers/iio/frequency/ad9910.c
ANALOG DEVICES INC MAX22007 DRIVER
M: Janani Sunil <janani.sunil@analog.com>
L: linux-iio@vger.kernel.org
@ -4439,6 +4472,15 @@ S: Orphan
F: Documentation/devicetree/bindings/sound/axentia,*
F: sound/soc/atmel/tse850-pcm5142.c
AXIADO SARADC DRIVER
M: Petar Stepanovic <pstepanovic@axiado.com>
M: Akhila Kavi <akavi@axiado.com>
M: Prasad Bolisetty <pbolisetty@axiado.com>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/adc/axiado,ax3000-saradc.yaml
F: drivers/iio/adc/axiado_saradc.c
AXIS ARTPEC ARM64 SoC SUPPORT
M: Jesper Nilsson <jesper.nilsson@axis.com>
M: Lars Persson <lars.persson@axis.com>
@ -12697,6 +12739,7 @@ R: Nuno Sá <nuno.sa@analog.com>
R: Andy Shevchenko <andy@kernel.org>
L: linux-iio@vger.kernel.org
S: Maintained
Q: https://patchwork.kernel.org/project/linux-iio/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git
F: Documentation/ABI/testing/configfs-iio*
F: Documentation/ABI/testing/sysfs-bus-iio*
@ -12709,6 +12752,13 @@ F: include/dt-bindings/iio/
F: include/linux/iio/
F: tools/iio/
IIO CORE KUNIT TESTS
M: Rodrigo Alencar <rodrigo.alencar@analog.com>
L: linux-iio@vger.kernel.org
S: Maintained
F: drivers/iio/test/iio-test-channel-prefix.c
F: drivers/iio/test/iio-test-format.c
IIO UNIT CONVERTER
M: Peter Rosin <peda@lysator.liu.se>
L: linux-iio@vger.kernel.org
@ -16123,6 +16173,15 @@ L: linux-iio@vger.kernel.org
S: Supported
F: drivers/iio/temperature/max30208.c
MAXIM MAX40080 CURRENT SENSE AMPLIFIER DRIVER
M: Ciprian Hegbeli <ciprian.hegbeli@analog.com>
M: Stefan Popa <stefan.popa@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,max40080.yaml
F: drivers/iio/adc/max40080.c
MAXIM MAX7360 KEYPAD LED MFD DRIVER
M: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
S: Maintained
@ -16294,7 +16353,7 @@ M: Ariana Lazar <ariana.lazar@microchip.com>
L: linux-iio@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/iio/dac/microchip,mcp47feb02.yaml
F: drivers/iio/dac/mcp47feb02.c
F: drivers/iio/dac/mcp47feb02*
MCP4821 DAC DRIVER
M: Anshul Dalal <anshulusr@gmail.com>
@ -27241,6 +27300,13 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/adc/ti,ads1119.yaml
F: drivers/iio/adc/ti-ads1119.c
TI ADS112C04 ADC DRIVER
M: Kyle Hsieh <kylehsieh1995@gmail.com>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/adc/ti,ads112c04.yaml
F: drivers/iio/adc/ti-ads112c04.c
TI ADS112C14 ADC DRIVER
M: David Lechner <dlechner@baylibre.com>
L: linux-iio@vger.kernel.org
@ -29098,6 +29164,12 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml
F: drivers/iio/light/veml6030.c
VISHAY VEML6031X00 AMBIENT LIGHT SENSOR DRIVER
M: Javier Carrasco <javier.carrasco.cruz@gmail.com>
S: Maintained
F: Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml
F: drivers/iio/light/veml6031x00.c
VISHAY VEML6046X00 RGBIR COLOR SENSOR DRIVER
M: Andreas Klinger <ak@it-klinger.de>
S: Maintained

View File

@ -7,13 +7,14 @@
menu "Accelerometers"
config ADIS16201
tristate "Analog Devices ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer"
tristate "ADIS16201 Digital Inclinometer and similar"
depends on SPI
select IIO_ADIS_LIB
select IIO_ADIS_LIB_BUFFER if IIO_BUFFER
help
Say Y here to build support for Analog Devices adis16201 dual-axis
digital inclinometer and accelerometer.
Say Y here to build support for Analog Devices Digital Inclinometers:
- ADIS16201
- ADIS16203
To compile this driver as a module, say M here: the module will
be called adis16201.

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer
* ADIS16201 Digital Inclinometer and similar
*
* Copyright 2010 Analog Devices Inc.
*/
@ -63,6 +63,7 @@
#define ADIS16201_DIAG_STAT_REG 0x3C
#define ADIS16201_DIAG_STAT_ALARM2 BIT(9)
#define ADIS16201_DIAG_STAT_ALARM1 BIT(8)
#define ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT 5
#define ADIS16201_DIAG_STAT_SPI_FAIL_BIT 3
#define ADIS16201_DIAG_STAT_FLASH_UPT_FAIL_BIT 2
/* Power supply above 3.625 V */
@ -87,6 +88,21 @@ enum adis16201_scan {
ADIS16201_SCAN_TEMP,
};
struct adis16201_chip_info {
const char *name;
const struct iio_chan_spec *arr_channels;
const struct adis_data *data;
unsigned int incli_scale_val2;
unsigned int read_bits_incli;
unsigned int num_channels;
u16 write_mask_incli;
};
struct adis16201_state {
struct adis adis;
const struct adis16201_chip_info *info;
};
static const u8 adis16201_addresses[] = {
[ADIS16201_SCAN_ACC_X] = ADIS16201_XACCL_OFFS_REG,
[ADIS16201_SCAN_ACC_Y] = ADIS16201_YACCL_OFFS_REG,
@ -99,7 +115,7 @@ static int adis16201_read_raw(struct iio_dev *indio_dev,
int *val, int *val2,
long mask)
{
struct adis *st = iio_priv(indio_dev);
struct adis16201_state *st = iio_priv(indio_dev);
int ret;
int bits;
u8 addr;
@ -137,7 +153,7 @@ static int adis16201_read_raw(struct iio_dev *indio_dev,
return IIO_VAL_INT_PLUS_NANO;
case IIO_INCLI:
*val = 0;
*val2 = 100000;
*val2 = st->info->incli_scale_val2;
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
@ -157,13 +173,13 @@ static int adis16201_read_raw(struct iio_dev *indio_dev,
bits = 12;
break;
case IIO_INCLI:
bits = 9;
bits = st->info->read_bits_incli;
break;
default:
return -EINVAL;
}
addr = adis16201_addresses[chan->scan_index];
ret = adis_read_reg_16(st, addr, &val16);
ret = adis_read_reg_16(&st->adis, addr, &val16);
if (ret)
return ret;
@ -180,41 +196,49 @@ static int adis16201_write_raw(struct iio_dev *indio_dev,
int val2,
long mask)
{
struct adis *st = iio_priv(indio_dev);
int m;
struct adis16201_state *st = iio_priv(indio_dev);
if (mask != IIO_CHAN_INFO_CALIBBIAS)
return -EINVAL;
switch (chan->type) {
case IIO_ACCEL:
m = GENMASK(11, 0);
val &= GENMASK(11, 0);
break;
case IIO_INCLI:
m = GENMASK(8, 0);
val &= st->info->write_mask_incli;
break;
default:
return -EINVAL;
}
return adis_write_reg_16(st, adis16201_addresses[chan->scan_index],
val & m);
return adis_write_reg_16(&st->adis, adis16201_addresses[chan->scan_index],
val);
}
static const struct iio_chan_spec adis16201_channels[] = {
ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT_REG, ADIS16201_SCAN_SUPPLY, 0,
12),
ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT_REG, ADIS16201_SCAN_TEMP, 0, 12),
ADIS_ACCEL_CHAN(X, ADIS16201_XACCL_OUT_REG, ADIS16201_SCAN_ACC_X,
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
ADIS_ACCEL_CHAN(Y, ADIS16201_YACCL_OUT_REG, ADIS16201_SCAN_ACC_Y,
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC_REG, ADIS16201_SCAN_AUX_ADC, 0, 12),
ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT_REG, ADIS16201_SCAN_INCLI_X,
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 12),
ADIS_INCLI_CHAN(Y, ADIS16201_YINCL_OUT_REG, ADIS16201_SCAN_INCLI_Y,
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 12),
IIO_CHAN_SOFT_TIMESTAMP(7)
ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT_REG, ADIS16201_SCAN_SUPPLY, 0,
12),
ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC_REG, ADIS16201_SCAN_AUX_ADC, 0, 12),
ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT_REG, ADIS16201_SCAN_TEMP, 0, 12),
IIO_CHAN_SOFT_TIMESTAMP(7),
};
static const struct iio_chan_spec adis16203_channels[] = {
ADIS_INCLI_CHAN(X, ADIS16201_XINCL_OUT_REG, ADIS16201_SCAN_INCLI_X,
BIT(IIO_CHAN_INFO_CALIBBIAS), 0, 14),
ADIS_SUPPLY_CHAN(ADIS16201_SUPPLY_OUT_REG, ADIS16201_SCAN_SUPPLY, 0, 12),
ADIS_AUX_ADC_CHAN(ADIS16201_AUX_ADC_REG, ADIS16201_SCAN_AUX_ADC, 0, 12),
ADIS_TEMP_CHAN(ADIS16201_TEMP_OUT_REG, ADIS16201_SCAN_TEMP, 0, 12),
IIO_CHAN_SOFT_TIMESTAMP(7),
};
static const struct iio_info adis16201_info = {
@ -224,6 +248,7 @@ static const struct iio_info adis16201_info = {
};
static const char * const adis16201_status_error_msgs[] = {
[ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT] = "Self test failure",
[ADIS16201_DIAG_STAT_SPI_FAIL_BIT] = "SPI failure",
[ADIS16201_DIAG_STAT_FLASH_UPT_FAIL_BIT] = "Flash update failed",
[ADIS16201_DIAG_STAT_POWER_HIGH_BIT] = "Power supply above 3.625V",
@ -254,10 +279,49 @@ static const struct adis_data adis16201_data = {
BIT(ADIS16201_DIAG_STAT_POWER_LOW_BIT),
};
static const struct adis_data adis16203_data = {
.read_delay = 20,
.msc_ctrl_reg = ADIS16201_MSC_CTRL_REG,
.glob_cmd_reg = ADIS16201_GLOB_CMD_REG,
.diag_stat_reg = ADIS16201_DIAG_STAT_REG,
.self_test_mask = ADIS16201_MSC_CTRL_SELF_TEST_EN,
.self_test_reg = ADIS16201_MSC_CTRL_REG,
.self_test_no_autoclear = true,
.timeouts = &adis16201_timeouts,
.status_error_msgs = adis16201_status_error_msgs,
.status_error_mask = BIT(ADIS16203_DIAG_STAT_SELFTEST_FAIL_BIT) |
BIT(ADIS16201_DIAG_STAT_SPI_FAIL_BIT) |
BIT(ADIS16201_DIAG_STAT_FLASH_UPT_FAIL_BIT) |
BIT(ADIS16201_DIAG_STAT_POWER_HIGH_BIT) |
BIT(ADIS16201_DIAG_STAT_POWER_LOW_BIT),
};
static const struct adis16201_chip_info adis16201_chip_data = {
.arr_channels = adis16201_channels,
.incli_scale_val2 = 100000,
.write_mask_incli = GENMASK(8, 0),
.read_bits_incli = 9,
.num_channels = ARRAY_SIZE(adis16201_channels),
.name = "adis16201",
.data = &adis16201_data,
};
static const struct adis16201_chip_info adis16203_chip_data = {
.arr_channels = adis16203_channels,
.incli_scale_val2 = 25000,
.write_mask_incli = GENMASK(13, 0),
.read_bits_incli = 14,
.num_channels = ARRAY_SIZE(adis16203_channels),
.name = "adis16203",
.data = &adis16203_data,
};
static int adis16201_probe(struct spi_device *spi)
{
struct iio_dev *indio_dev;
struct adis *st;
struct adis16201_state *st;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
@ -266,38 +330,57 @@ static int adis16201_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
indio_dev->name = spi->dev.driver->name;
st->info = spi_get_device_match_data(spi);
if (!st->info)
return -ENODATA;
indio_dev->name = st->info->name;
indio_dev->info = &adis16201_info;
indio_dev->channels = adis16201_channels;
indio_dev->num_channels = ARRAY_SIZE(adis16201_channels);
indio_dev->channels = st->info->arr_channels;
indio_dev->num_channels = st->info->num_channels;
indio_dev->modes = INDIO_DIRECT_MODE;
ret = adis_init(st, indio_dev, spi, &adis16201_data);
ret = adis_init(&st->adis, indio_dev, spi, st->info->data);
if (ret)
return ret;
ret = devm_adis_setup_buffer_and_trigger(st, indio_dev, NULL);
ret = devm_adis_setup_buffer_and_trigger(&st->adis, indio_dev, NULL);
if (ret)
return ret;
ret = __adis_initial_startup(st);
ret = __adis_initial_startup(&st->adis);
if (ret)
return ret;
return devm_iio_device_register(&spi->dev, indio_dev);
}
static const struct of_device_id adis16201_of_match[] = {
{ .compatible = "adi,adis16201", .data = &adis16201_chip_data },
{ .compatible = "adi,adis16203", .data = &adis16203_chip_data },
{ }
};
MODULE_DEVICE_TABLE(of, adis16201_of_match);
static const struct spi_device_id adis16201_ids[] = {
{ .name = "adis16201", .driver_data = (kernel_ulong_t)&adis16201_chip_data },
{ .name = "adis16203", .driver_data = (kernel_ulong_t)&adis16203_chip_data },
{ }
};
MODULE_DEVICE_TABLE(spi, adis16201_ids);
static struct spi_driver adis16201_driver = {
.driver = {
.name = "adis16201",
.of_match_table = adis16201_of_match,
},
.probe = adis16201_probe,
.id_table = adis16201_ids,
};
module_spi_driver(adis16201_driver);
MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>");
MODULE_DESCRIPTION("Analog Devices ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer");
MODULE_DESCRIPTION("Analog Devices ADIS16201 Inclinometer and similar");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("spi:adis16201");
MODULE_IMPORT_NS("IIO_ADISLIB");

View File

@ -79,6 +79,8 @@ static int adxl313_spi_probe(struct spi_device *spi)
return ret;
chip_data = spi_get_device_match_data(spi);
if (!chip_data)
return -ENODATA;
regmap = devm_regmap_init_spi(spi,
&adxl31x_spi_regmap_config[chip_data->type]);

View File

@ -13,6 +13,7 @@
#include <linux/iio/sysfs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/unaligned.h>
@ -81,6 +82,7 @@
#define ADXL367_SAMPLES_L_MASK GENMASK(7, 0)
#define ADXL367_REG_INT1_MAP 0x2A
#define ADXL367_REG_INT2_MAP 0x2B
#define ADXL367_INT_INACT_MASK BIT(5)
#define ADXL367_INT_ACT_MASK BIT(4)
#define ADXL367_INT_FIFO_WATERMARK_MASK BIT(2)
@ -168,6 +170,8 @@ struct adxl367_state {
enum adxl367_odr odr;
enum adxl367_range range;
u8 int_map_reg;
unsigned int act_threshold;
unsigned int act_time_ms;
unsigned int inact_threshold;
@ -366,8 +370,7 @@ static int adxl367_set_act_interrupt_en(struct adxl367_state *st,
{
unsigned int mask = adxl367_act_int_mask_tbl[act];
return regmap_update_bits(st->regmap, ADXL367_REG_INT1_MAP,
mask, en ? mask : 0);
return regmap_assign_bits(st->regmap, st->int_map_reg, mask, en);
}
static int adxl367_get_act_interrupt_en(struct adxl367_state *st,
@ -378,7 +381,7 @@ static int adxl367_get_act_interrupt_en(struct adxl367_state *st,
unsigned int val;
int ret;
ret = regmap_read(st->regmap, ADXL367_REG_INT1_MAP, &val);
ret = regmap_read(st->regmap, st->int_map_reg, &val);
if (ret)
return ret;
@ -401,9 +404,8 @@ static int adxl367_set_act_en(struct adxl367_state *st,
static int adxl367_set_fifo_watermark_interrupt_en(struct adxl367_state *st,
bool en)
{
return regmap_update_bits(st->regmap, ADXL367_REG_INT1_MAP,
ADXL367_INT_FIFO_WATERMARK_MASK,
en ? ADXL367_INT_FIFO_WATERMARK_MASK : 0);
return regmap_assign_bits(st->regmap, st->int_map_reg,
ADXL367_INT_FIFO_WATERMARK_MASK, en);
}
static int adxl367_get_fifo_mode(struct adxl367_state *st,
@ -631,8 +633,7 @@ static int adxl367_set_odr(struct iio_dev *indio_dev, enum adxl367_odr odr)
static int adxl367_set_temp_adc_en(struct adxl367_state *st, unsigned int reg,
bool en)
{
return regmap_update_bits(st->regmap, reg, ADXL367_ADC_EN_MASK,
en ? ADXL367_ADC_EN_MASK : 0);
return regmap_assign_bits(st->regmap, reg, ADXL367_ADC_EN_MASK, en);
}
static int adxl367_set_temp_adc_reg_en(struct adxl367_state *st,
@ -787,6 +788,13 @@ static bool adxl367_push_fifo_data(struct iio_dev *indio_dev, u8 status,
if (!FIELD_GET(ADXL367_STATUS_FIFO_FULL_MASK, status))
return false;
if (fifo_entries > ADXL367_FIFO_SIZE) {
dev_err_ratelimited(st->dev,
"FIFO entry count %u exceeds FIFO size %u\n",
fifo_entries, ADXL367_FIFO_SIZE);
return true;
}
fifo_entries -= fifo_entries % st->fifo_set_size;
ret = st->ops->read_fifo(st->context, st->fifo_buf, fifo_entries);
@ -1426,6 +1434,36 @@ static int adxl367_setup(struct adxl367_state *st)
return adxl367_set_measure_en(st, true);
}
static int adxl367_set_int_map_reg(struct adxl367_state *st, int irq)
{
int ret;
/*
* Route the mappings to whichever of INT1/INT2 is named in the
* interrupt-names property. -EINVAL (property absent) and -ENODATA
* (name not listed) are not errors; anything else is.
*/
ret = fwnode_irq_get_byname(dev_fwnode(st->dev), "INT1");
if (ret > 0) {
st->int_map_reg = ADXL367_REG_INT1_MAP;
return ret;
}
if (ret != -ENODATA && ret != -EINVAL)
return ret;
ret = fwnode_irq_get_byname(dev_fwnode(st->dev), "INT2");
if (ret > 0) {
st->int_map_reg = ADXL367_REG_INT2_MAP;
return ret;
}
if (ret != -ENODATA && ret != -EINVAL)
return ret;
/* No INT1/INT2 named: default to INT1 and the bus interrupt. */
st->int_map_reg = ADXL367_REG_INT1_MAP;
return irq;
}
int adxl367_probe(struct device *dev, const struct adxl367_ops *ops,
void *context, struct regmap *regmap, int irq)
{
@ -1455,6 +1493,11 @@ int adxl367_probe(struct device *dev, const struct adxl367_ops *ops,
indio_dev->info = &adxl367_info;
indio_dev->modes = INDIO_DIRECT_MODE;
ret = adxl367_set_int_map_reg(st, irq);
if (ret < 0)
return dev_err_probe(st->dev, ret, "Failed to get interrupt\n");
irq = ret;
ret = devm_regulator_bulk_get_enable(st->dev,
ARRAY_SIZE(regulator_names),
regulator_names);

View File

@ -25,6 +25,8 @@ static int adxl372_spi_probe(struct spi_device *spi)
struct regmap *regmap;
chip_info = spi_get_device_match_data(spi);
if (!chip_info)
return -ENODATA;
regmap = devm_regmap_init_spi(spi, &adxl372_spi_regmap_config);
if (IS_ERR(regmap))

View File

@ -966,6 +966,13 @@ static irqreturn_t adxl380_irq_handler(int irq, void *p)
if (ret)
return IRQ_HANDLED;
if (fifo_entries > ADXL380_FIFO_SAMPLES) {
dev_err_ratelimited(st->dev,
"FIFO entry count %u exceeds FIFO size %lu\n",
fifo_entries, ADXL380_FIFO_SAMPLES);
return IRQ_HANDLED;
}
fifo_entries = rounddown(fifo_entries, st->fifo_set_size);
ret = regmap_noinc_read(st->regmap, ADXL380_FIFO_DATA, &st->fifo_buf,
sizeof(*st->fifo_buf) * fifo_entries);

View File

@ -25,6 +25,8 @@ static int adxl380_spi_probe(struct spi_device *spi)
struct regmap *regmap;
chip_data = spi_get_device_match_data(spi);
if (!chip_data)
return -ENODATA;
regmap = devm_regmap_init_spi(spi, &adxl380_spi_regmap_config);
if (IS_ERR(regmap))

View File

@ -28,12 +28,13 @@ static const struct spi_device_id bma220_spi_id[] = {
{ .name = "bma220" },
{ }
};
MODULE_DEVICE_TABLE(spi, bma220_spi_id);
static const struct acpi_device_id bma220_acpi_id[] = {
{ "BMA0220", 0 },
{ }
};
MODULE_DEVICE_TABLE(spi, bma220_spi_id);
MODULE_DEVICE_TABLE(acpi, bma220_acpi_id);
static const struct of_device_id bma220_of_spi_match[] = {
{ .compatible = "bosch,bma220" },

View File

@ -6,8 +6,6 @@
*
* TODO:
* - Support for power management
* - Support events and interrupts
* - Create channel for step count
* - Create channel for sensor time
*/

View File

@ -301,11 +301,10 @@ struct kx022a_data {
__le16 *fifo_buffer;
/* 3 x 16bit accel data + timestamp */
__le16 buffer[8] __aligned(IIO_DMA_MINALIGN);
struct {
__le16 channels[3];
aligned_s64 ts;
} scan;
} scan __aligned(IIO_DMA_MINALIGN);
};
static const struct iio_mount_matrix *
@ -611,14 +610,15 @@ static int kx022a_get_axis(struct kx022a_data *data,
struct iio_chan_spec const *chan,
int *val)
{
__le16 *buf = &data->scan.channels[0];
int ret;
ret = regmap_bulk_read(data->regmap, chan->address, &data->buffer[0],
sizeof(__le16));
ret = regmap_bulk_read(data->regmap, chan->address,
buf, sizeof(*buf));
if (ret)
return ret;
*val = (s16)le16_to_cpu(data->buffer[0]);
*val = (s16)le16_to_cpup(buf);
return IIO_VAL_INT;
}
@ -809,7 +809,7 @@ static int __kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples,
* the timestamps. If we are ran from IRQ, then the
* IRQF_ONESHOT has us covered - but if we are ran by the
* user-space read we need to disable the IRQ to be on a safe
* side. We do this usng synchronous disable so that if the
* side. We do this using synchronous disable so that if the
* IRQ thread is being ran on other CPU we wait for it to be
* finished.
*/
@ -864,7 +864,8 @@ static int __kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples,
for_each_set_bit(bit, idev->active_scan_mask, AXIS_MAX)
chs[bit] = sam[bit];
iio_push_to_buffers_with_timestamp(idev, &data->scan, tstamp);
iio_push_to_buffers_with_ts(idev, &data->scan,
sizeof(data->scan), tstamp);
tstamp += sample_period;
}
@ -1029,12 +1030,13 @@ static irqreturn_t kx022a_trigger_handler(int irq, void *p)
struct kx022a_data *data = iio_priv(idev);
int ret;
ret = regmap_bulk_read(data->regmap, data->chip_info->xout_l, data->buffer,
KX022A_FIFO_SAMPLES_SIZE_BYTES);
ret = regmap_bulk_read(data->regmap, data->chip_info->xout_l,
data->scan.channels, KX022A_FIFO_SAMPLES_SIZE_BYTES);
if (ret < 0)
goto err_read;
iio_push_to_buffers_with_timestamp(idev, data->buffer, data->timestamp);
iio_push_to_buffers_with_ts(idev, &data->scan, sizeof(data->scan),
data->timestamp);
err_read:
iio_trigger_notify_done(idev->trig);

View File

@ -65,7 +65,7 @@
#define KX022A_MASK_IEN BIT(5)
#define KX022A_MASK_IPOL BIT(4)
#define KX022A_IPOL_LOW 0
#define KX022A_IPOL_HIGH KX022A_MASK_IPOL1
#define KX022A_IPOL_HIGH KX022A_MASK_IPOL
#define KX022A_MASK_ITYP BIT(3)
#define KX022A_ITYP_PULSE KX022A_MASK_ITYP
#define KX022A_ITYP_LEVEL 0

View File

@ -1547,6 +1547,7 @@ static void kxcjk1013_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
pm_runtime_dont_use_autosuspend(&client->dev);
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);

View File

@ -18,6 +18,8 @@
* TODO: orientation events
*/
#include <linux/array_size.h>
#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
@ -110,8 +112,7 @@ struct mma8452_data {
u8 data_cfg;
const struct mma_chip_info *chip_info;
int sleep_val;
struct regulator *vdd_reg;
struct regulator *vddio_reg;
struct regulator_bulk_data regs[2];
/* Ensure correct alignment of time stamp when present */
struct {
@ -222,15 +223,15 @@ static int mma8452_drdy(struct mma8452_data *data)
static int mma8452_set_runtime_pm_state(struct i2c_client *client, bool on)
{
#ifdef CONFIG_PM
struct device *dev = &client->dev;
int ret;
if (on)
ret = pm_runtime_resume_and_get(&client->dev);
ret = pm_runtime_resume_and_get(dev);
else
ret = pm_runtime_put_autosuspend(&client->dev);
ret = pm_runtime_put_autosuspend(dev);
if (ret < 0) {
dev_err(&client->dev,
"failed to change power state to %d\n", on);
dev_err(dev, "failed to change power state to %d\n", on);
return ret;
}
@ -495,14 +496,14 @@ static int mma8452_read_raw(struct iio_dev *indio_dev,
int i, ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (!iio_device_claim_direct(indio_dev))
case IIO_CHAN_INFO_RAW: {
IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
if (IIO_DEV_ACQUIRE_FAILED(claim))
return -EBUSY;
mutex_lock(&data->lock);
guard(mutex)(&data->lock);
ret = mma8452_read(data, buffer);
mutex_unlock(&data->lock);
iio_device_release_direct(indio_dev);
if (ret < 0)
return ret;
@ -511,6 +512,7 @@ static int mma8452_read_raw(struct iio_dev *indio_dev,
chan->scan_type.realbits - 1);
return IIO_VAL_INT;
}
case IIO_CHAN_INFO_SCALE:
i = data->data_cfg & MMA8452_DATA_CFG_FS_MASK;
*val = data->chip_info->mma_scales[i][0];
@ -599,36 +601,30 @@ static int mma8452_change_config(struct mma8452_data *data, u8 reg, u8 val)
int ret;
int is_active;
mutex_lock(&data->lock);
guard(mutex)(&data->lock);
is_active = mma8452_is_active(data);
if (is_active < 0) {
ret = is_active;
goto fail;
}
if (is_active < 0)
return is_active;
/* config can only be changed when in standby */
if (is_active > 0) {
ret = mma8452_standby(data);
if (ret < 0)
goto fail;
return ret;
}
ret = i2c_smbus_write_byte_data(data->client, reg, val);
if (ret < 0)
goto fail;
return ret;
if (is_active > 0) {
ret = mma8452_active(data);
if (ret < 0)
goto fail;
return ret;
}
ret = 0;
fail:
mutex_unlock(&data->lock);
return ret;
return 0;
}
static int mma8452_set_power_mode(struct mma8452_data *data, u8 mode)
@ -777,14 +773,11 @@ static int mma8452_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
int ret;
if (!iio_device_claim_direct(indio_dev))
IIO_DEV_ACQUIRE_DIRECT_MODE(indio_dev, claim);
if (IIO_DEV_ACQUIRE_FAILED(claim))
return -EBUSY;
ret = __mma8452_write_raw(indio_dev, chan, val, val2, mask);
iio_device_release_direct(indio_dev);
return ret;
return __mma8452_write_raw(indio_dev, chan, val, val2, mask);
}
static int mma8452_get_event_regs(struct mma8452_data *data,
@ -1552,7 +1545,7 @@ static int mma8452_probe(struct i2c_client *client)
struct iio_dev *indio_dev;
int ret;
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
@ -1562,32 +1555,21 @@ static int mma8452_probe(struct i2c_client *client)
data->chip_info = i2c_get_match_data(client);
if (!data->chip_info)
return dev_err_probe(&client->dev, -ENODEV,
"unknown device model\n");
return dev_err_probe(dev, -ENODEV, "unknown device model\n");
ret = iio_read_mount_matrix(&client->dev, &data->orientation);
ret = iio_read_mount_matrix(dev, &data->orientation);
if (ret)
return ret;
data->vdd_reg = devm_regulator_get(&client->dev, "vdd");
if (IS_ERR(data->vdd_reg))
return dev_err_probe(&client->dev, PTR_ERR(data->vdd_reg),
"failed to get VDD regulator!\n");
data->vddio_reg = devm_regulator_get(&client->dev, "vddio");
if (IS_ERR(data->vddio_reg))
return dev_err_probe(&client->dev, PTR_ERR(data->vddio_reg),
"failed to get VDDIO regulator!\n");
ret = regulator_enable(data->vdd_reg);
data->regs[0].supply = "vdd";
data->regs[1].supply = "vddio";
ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(data->regs), data->regs);
if (ret)
return dev_err_probe(dev, ret, "failed to enable VDD regulator!\n");
return dev_err_probe(dev, ret, "failed to get regulators\n");
ret = regulator_enable(data->vddio_reg);
if (ret) {
dev_err_probe(dev, ret, "failed to enable VDDIO regulator!\n");
goto disable_regulator_vdd;
}
ret = regulator_bulk_enable(ARRAY_SIZE(data->regs), data->regs);
if (ret)
return dev_err_probe(dev, ret, "failed to enable regulators\n");
ret = i2c_smbus_read_byte_data(client, MMA8452_WHO_AM_I);
if (ret < 0)
@ -1608,7 +1590,7 @@ static int mma8452_probe(struct i2c_client *client)
goto disable_regulators;
}
dev_info(&client->dev, "registering %s accelerometer; ID 0x%x\n",
dev_info(dev, "registering %s accelerometer; ID 0x%x\n",
data->chip_info->name, data->chip_info->chip_id);
i2c_set_clientdata(client, indio_dev);
@ -1641,10 +1623,10 @@ static int mma8452_probe(struct i2c_client *client)
if (client->irq) {
int irq2;
irq2 = fwnode_irq_get_byname(dev_fwnode(&client->dev), "INT2");
irq2 = fwnode_irq_get_byname(dev_fwnode(dev), "INT2");
if (irq2 == client->irq) {
dev_dbg(&client->dev, "using interrupt line INT2\n");
dev_dbg(dev, "using interrupt line INT2\n");
} else {
ret = i2c_smbus_write_byte_data(client,
MMA8452_CTRL_REG5,
@ -1652,7 +1634,7 @@ static int mma8452_probe(struct i2c_client *client)
if (ret < 0)
goto disable_regulators;
dev_dbg(&client->dev, "using interrupt line INT1\n");
dev_dbg(dev, "using interrupt line INT1\n");
}
ret = i2c_smbus_write_byte_data(client,
@ -1689,14 +1671,13 @@ static int mma8452_probe(struct i2c_client *client)
goto buffer_cleanup;
}
ret = pm_runtime_set_active(&client->dev);
ret = pm_runtime_set_active(dev);
if (ret < 0)
goto free_irq;
pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev,
MMA8452_AUTO_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(&client->dev);
pm_runtime_enable(dev);
pm_runtime_set_autosuspend_delay(dev, MMA8452_AUTO_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(dev);
ret = iio_device_register(indio_dev);
if (ret < 0)
@ -1722,10 +1703,7 @@ static int mma8452_probe(struct i2c_client *client)
mma8452_trigger_cleanup(indio_dev);
disable_regulators:
regulator_disable(data->vddio_reg);
disable_regulator_vdd:
regulator_disable(data->vdd_reg);
regulator_bulk_disable(ARRAY_SIZE(data->regs), data->regs);
return ret;
}
@ -1734,11 +1712,12 @@ static void mma8452_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct mma8452_data *data = iio_priv(indio_dev);
struct device *dev = &client->dev;
iio_device_unregister(indio_dev);
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
pm_runtime_disable(dev);
pm_runtime_set_suspended(dev);
if (client->irq)
free_irq(client->irq, indio_dev);
@ -1747,8 +1726,7 @@ static void mma8452_remove(struct i2c_client *client)
mma8452_trigger_cleanup(indio_dev);
mma8452_standby(iio_priv(indio_dev));
regulator_disable(data->vddio_reg);
regulator_disable(data->vdd_reg);
regulator_bulk_disable(ARRAY_SIZE(data->regs), data->regs);
}
#ifdef CONFIG_PM
@ -1758,23 +1736,16 @@ static int mma8452_runtime_suspend(struct device *dev)
struct mma8452_data *data = iio_priv(indio_dev);
int ret;
mutex_lock(&data->lock);
ret = mma8452_standby(data);
mutex_unlock(&data->lock);
scoped_guard(mutex, &data->lock)
ret = mma8452_standby(data);
if (ret < 0) {
dev_err(&data->client->dev, "powering off device failed\n");
dev_err(dev, "powering off device failed\n");
return -EAGAIN;
}
ret = regulator_disable(data->vddio_reg);
ret = regulator_bulk_disable(ARRAY_SIZE(data->regs), data->regs);
if (ret) {
dev_err(dev, "failed to disable VDDIO regulator\n");
return ret;
}
ret = regulator_disable(data->vdd_reg);
if (ret) {
dev_err(dev, "failed to disable VDD regulator\n");
dev_err(dev, "failed to disable regulators\n");
return ret;
}
@ -1787,16 +1758,9 @@ static int mma8452_runtime_resume(struct device *dev)
struct mma8452_data *data = iio_priv(indio_dev);
int ret, sleep_val;
ret = regulator_enable(data->vdd_reg);
ret = regulator_bulk_enable(ARRAY_SIZE(data->regs), data->regs);
if (ret) {
dev_err(dev, "failed to enable VDD regulator\n");
return ret;
}
ret = regulator_enable(data->vddio_reg);
if (ret) {
dev_err(dev, "failed to enable VDDIO regulator\n");
regulator_disable(data->vdd_reg);
dev_err(dev, "failed to enable regulators\n");
return ret;
}
@ -1814,8 +1778,7 @@ static int mma8452_runtime_resume(struct device *dev)
return 0;
runtime_resume_failed:
regulator_disable(data->vddio_reg);
regulator_disable(data->vdd_reg);
regulator_bulk_disable(ARRAY_SIZE(data->regs), data->regs);
return ret;
}

View File

@ -500,6 +500,7 @@ static void mma9551_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
pm_runtime_dont_use_autosuspend(&client->dev);
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);

View File

@ -1136,6 +1136,7 @@ static void mma9553_remove(struct i2c_client *client)
iio_device_unregister(indio_dev);
pm_runtime_dont_use_autosuspend(&client->dev);
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);

View File

@ -1462,6 +1462,8 @@ static int sca3000_probe(struct spi_device *spi)
st->us = spi;
mutex_init(&st->lock);
st->info = spi_get_device_match_data(spi);
if (!st->info)
return -ENODATA;
indio_dev->name = st->info->name;
indio_dev->info = &sca3000_info;

View File

@ -105,7 +105,7 @@ config AD4080
called ad4080.
config AD4130
tristate "Analog Device AD4130 ADC Driver"
tristate "Analog Devices AD4130 ADC Driver"
depends on SPI
depends on GPIOLIB
select IIO_BUFFER
@ -121,7 +121,7 @@ config AD4130
called ad4130.
config AD4134
tristate "Analog Device AD4134 ADC Driver"
tristate "Analog Devices AD4134 ADC Driver"
depends on SPI
select REGMAP_SPI
select CRC8
@ -133,7 +133,7 @@ config AD4134
called ad4134_spi.
config AD4170_4
tristate "Analog Device AD4170-4 ADC Driver"
tristate "Analog Devices AD4170-4 ADC Driver"
depends on SPI
select REGMAP_SPI
select IIO_BUFFER
@ -164,7 +164,7 @@ config AD4691
called ad4691.
config AD4695
tristate "Analog Device AD4695 ADC Driver"
tristate "Analog Devices AD4695 ADC Driver"
depends on SPI
select IIO_BUFFER
select IIO_BUFFER_DMAENGINE
@ -179,7 +179,7 @@ config AD4695
called ad4695.
config AD4851
tristate "Analog Device AD4851 DAS Driver"
tristate "Analog Devices AD4851 DAS Driver"
depends on SPI
depends on PWM
select REGMAP_SPI
@ -347,7 +347,7 @@ config AD7380
called ad7380.
config AD7405
tristate "Analog Device AD7405 ADC Driver"
tristate "Analog Devices AD7405 ADC Driver"
depends on IIO_BACKEND
help
Say yes here to build support for Analog Devices AD7405, ADUM7701,
@ -431,6 +431,21 @@ config AD7766
To compile this driver as a module, choose M here: the module will be
called ad7766.
config AD7768
tristate "Analog Devices AD7768/AD7768-4 ADC driver"
depends on SPI
select REGULATOR
select AUXILIARY_BUS
select IIO_BUFFER
select IIO_BACKEND
select REGMAP
help
Say yes here to build support for Analog Devices AD7768 and AD7768-4
SPI analog to digital converters.
To compile this driver as a module, choose M here: the module will be
called ad7768.
config AD7768_1
tristate "Analog Devices AD7768-1 ADC driver"
depends on SPI
@ -576,20 +591,22 @@ config AD9467
called ad9467.
config ADE9000
tristate "Analog Devices ADE9000 Multiphase Energy, and Power Quality Monitoring IC Driver"
tristate "Analog Devices Multiphase Energy and Power Quality Monitoring IC Driver"
depends on SPI
select REGMAP_SPI
select IIO_BUFFER
select IIO_KFIFO_BUF
help
Say yes here to build support for the Analog Devices ADE9000,
a highly accurate, multiphase energy and power quality monitoring
integrated circuit.
Say yes here to build support for the following Analog Devices
highly accurate, multiphase energy and power quality monitoring
integrated circuits:
- ADE9000
- ADE9078
The device features high-precision analog-to-digital converters
The devices feature high-precision analog-to-digital converters
and digital signal processing to compute RMS values, power factor,
frequency, and harmonic analysis. It supports SPI communication
and provides buffered data output through the IIO framework.
frequency, and harmonic analysis. They support SPI communication
and provide buffered data output through the IIO framework.
To compile this driver as a module, choose M here: the module will
be called ade9000.
@ -653,6 +670,17 @@ config AT91_SAMA5D2_ADC
To compile this driver as a module, choose M here: the module will be
called at91-sama5d2_adc.
config AXIADO_SARADC
tristate "Axiado SARADC driver"
depends on ARCH_AXIADO || COMPILE_TEST
select REGMAP_MMIO
help
Say yes here to build support for the SARADC found in Axiado
SoCs.
To compile this driver as a module, choose M here: the module
will be called axiado_saradc.
config AXP20X_ADC
tristate "X-Powers AXP20X and AXP22X ADC driver"
depends on MFD_AXP20X
@ -1116,6 +1144,17 @@ config MAX34408
To compile this driver as a module, choose M here: the module will be
called max34408.
config MAX40080
tristate "Analog Devices MAX40080 Current Sense Amplifier"
depends on I2C
help
Say yes here to build support for the Analog Devices MAX40080
bidirectional current-sense amplifier with a 12-bit ADC and an I2C
interface.
To compile this driver as a module, choose M here: the module will be
called max40080.
config MAX77541_ADC
tristate "Analog Devices MAX77541 ADC driver"
depends on MFD_MAX77541
@ -1551,6 +1590,8 @@ config RZT2H_ADC
tristate "Renesas RZ/T2H / RZ/N2H ADC driver"
depends on ARCH_RENESAS || COMPILE_TEST
select IIO_ADC_HELPER
select IIO_BUFFER
select IIO_KFIFO_BUF
help
Say yes here to build support for the ADC found in Renesas
RZ/T2H / RZ/N2H SoCs.
@ -1801,11 +1842,14 @@ config TI_ADS1018
called ti-ads1018.
config TI_ADS1100
tristate "Texas Instruments ADS1100 and ADS1000 ADC"
tristate "Texas Instruments ADS1100 and similar single channel I2C ADC"
depends on I2C
help
If you say yes here you get support for Texas Instruments ADS1100 and
ADS1000 ADC chips.
If you say yes here you get support for TI single channel I2C Analog
Devices.
* ADS1000 12-Bit, 128 SPS Analog-to-Digital Converter
* ADS1100 16-Bit, 128 SPS Analog-to-Digital Converter
* ADS1110 16-Bit, 240 SPS Analog-to-Digital Converter
This driver can also be built as a module. If so, the module will be
called ti-ads1100.
@ -1822,6 +1866,16 @@ config TI_ADS1119
This driver can also be built as a module. If so, the module will be
called ti-ads1119.
config TI_ADS112C04
tristate "Texas Instruments ADS112C04 ADC"
depends on I2C
help
If you say yes here you get support for Texas Instruments
ADS112C04 (16-bit) I2C analog to digital converters.
This driver can also be built as a module. If so, the module will be
called ti-ads112c04.
config TI_ADS112C14
tristate "Texas Instruments ADS112C14/ADS122C14"
depends on I2C

View File

@ -39,6 +39,7 @@ obj-$(CONFIG_AD7606_IFACE_SPI) += ad7606_spi.o
obj-$(CONFIG_AD7606) += ad7606.o
obj-$(CONFIG_AD7625) += ad7625.o
obj-$(CONFIG_AD7766) += ad7766.o
obj-$(CONFIG_AD7768) += ad7768.o
obj-$(CONFIG_AD7768_1) += ad7768-1.o
obj-$(CONFIG_AD7779) += ad7779.o
obj-$(CONFIG_AD7780) += ad7780.o
@ -55,6 +56,7 @@ obj-$(CONFIG_ADI_AXI_ADC) += adi-axi-adc.o
obj-$(CONFIG_ASPEED_ADC) += aspeed_adc.o
obj-$(CONFIG_AT91_ADC) += at91_adc.o
obj-$(CONFIG_AT91_SAMA5D2_ADC) += at91-sama5d2_adc.o
obj-$(CONFIG_AXIADO_SARADC) += axiado_saradc.o
obj-$(CONFIG_AXP20X_ADC) += axp20x_adc.o
obj-$(CONFIG_AXP288_ADC) += axp288_adc.o
obj-$(CONFIG_BCM_IPROC_ADC) += bcm_iproc_adc.o
@ -95,6 +97,7 @@ obj-$(CONFIG_MAX1241) += max1241.o
obj-$(CONFIG_MAX1363) += max1363.o
obj-$(CONFIG_MAX14001) += max14001.o
obj-$(CONFIG_MAX34408) += max34408.o
obj-$(CONFIG_MAX40080) += max40080.o
obj-$(CONFIG_MAX77541_ADC) += max77541-adc.o
obj-$(CONFIG_MAX9611) += max9611.o
obj-$(CONFIG_MCP320X) += mcp320x.o
@ -155,6 +158,7 @@ obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o
obj-$(CONFIG_TI_ADS1018) += ti-ads1018.o
obj-$(CONFIG_TI_ADS1100) += ti-ads1100.o
obj-$(CONFIG_TI_ADS1119) += ti-ads1119.o
obj-$(CONFIG_TI_ADS112C04) += ti-ads112c04.o
obj-$(CONFIG_TI_ADS112C14) += ti-ads112c14.o
obj-$(CONFIG_TI_ADS124S08) += ti-ads124s08.o
obj-$(CONFIG_TI_ADS1298) += ti-ads1298.o

View File

@ -137,6 +137,7 @@
#define AD4880_CHIP_ID 0x0059
#define AD4883_CHIP_ID 0x005B
#define AD4884_CHIP_ID 0x005C
#define AD4885_CHIP_ID 0x005D
#define AD4080_MAX_CHANNELS 2
@ -145,6 +146,10 @@
#define AD4080_MAX_SAMP_FREQ 40000000
#define AD4080_MIN_SAMP_FREQ 1250000
/* debugfs direct_reg_access channel windowing: 0x0RR = ch0, 0x1RR = ch1 */
#define AD4080_DEBUGFS_REG_CH_MSK GENMASK(15, 8)
#define AD4080_DEBUGFS_REG_OFFSET_MSK GENMASK(7, 0)
enum ad4080_filter_type {
FILTER_NONE,
SINC_1,
@ -210,11 +215,16 @@ static int ad4080_reg_access(struct iio_dev *indio_dev, unsigned int reg,
unsigned int writeval, unsigned int *readval)
{
struct ad4080_state *st = iio_priv(indio_dev);
unsigned int ch = FIELD_GET(AD4080_DEBUGFS_REG_CH_MSK, reg);
unsigned int offset = FIELD_GET(AD4080_DEBUGFS_REG_OFFSET_MSK, reg);
if (ch >= st->info->num_channels)
return -EINVAL;
if (readval)
return regmap_read(st->regmap[0], reg, readval);
return regmap_read(st->regmap[ch], offset, readval);
return regmap_write(st->regmap[0], reg, writeval);
return regmap_write(st->regmap[ch], offset, writeval);
}
static int ad4080_get_scale(struct ad4080_state *st, int *val, int *val2)
@ -552,6 +562,11 @@ static const struct iio_chan_spec ad4884_channels[] = {
AD4880_CHANNEL_DEFINE(16, 16, 1),
};
static const struct iio_chan_spec ad4885_channels[] = {
AD4880_CHANNEL_DEFINE(16, 16, 0),
AD4880_CHANNEL_DEFINE(16, 16, 1),
};
static const struct ad4080_chip_info ad4080_chip_info = {
.name = "ad4080",
.product_id = AD4080_CHIP_ID,
@ -672,6 +687,16 @@ static const struct ad4080_chip_info ad4884_chip_info = {
.lvds_cnv_clk_cnt_max = 2,
};
static const struct ad4080_chip_info ad4885_chip_info = {
.name = "ad4885",
.product_id = AD4885_CHIP_ID,
.scale_table = ad4080_scale_table,
.num_scales = ARRAY_SIZE(ad4080_scale_table),
.num_channels = 2,
.channels = ad4885_channels,
.lvds_cnv_clk_cnt_max = 8,
};
static int ad4080_setup_channel(struct ad4080_state *st, unsigned int ch)
{
struct device *dev = regmap_get_device(st->regmap[ch]);
@ -685,7 +710,8 @@ static int ad4080_setup_channel(struct ad4080_state *st, unsigned int ch)
return ret;
ret = regmap_write(st->regmap[ch], AD4080_REG_INTERFACE_CONFIG_A,
AD4080_INTERFACE_CONFIG_A_SDO_ENABLE);
AD4080_INTERFACE_CONFIG_A_SDO_ENABLE |
AD4080_INTERFACE_CONFIG_A_ADDR_ASC);
if (ret)
return ret;
@ -881,6 +907,7 @@ static const struct spi_device_id ad4080_id[] = {
{ .name = "ad4880", .driver_data = (kernel_ulong_t)&ad4880_chip_info },
{ .name = "ad4883", .driver_data = (kernel_ulong_t)&ad4883_chip_info },
{ .name = "ad4884", .driver_data = (kernel_ulong_t)&ad4884_chip_info },
{ .name = "ad4885", .driver_data = (kernel_ulong_t)&ad4885_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ad4080_id);
@ -898,6 +925,7 @@ static const struct of_device_id ad4080_of_match[] = {
{ .compatible = "adi,ad4880", &ad4880_chip_info },
{ .compatible = "adi,ad4883", &ad4883_chip_info },
{ .compatible = "adi,ad4884", &ad4884_chip_info },
{ .compatible = "adi,ad4885", &ad4885_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ad4080_of_match);

View File

@ -496,4 +496,3 @@ module_spi_driver(ad4134_driver);
MODULE_AUTHOR("Marcelo Schmitt <marcelo.schmitt@analog.com>");
MODULE_DESCRIPTION("Analog Devices AD4134 SPI driver");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("IIO_AD4134");

View File

@ -1801,8 +1801,7 @@ static int ad7173_fw_parse_channel_config(struct iio_dev *indio_dev)
indio_dev->num_channels = num_channels;
st->num_channels = num_channels;
chan_arr = devm_kcalloc(dev, sizeof(*indio_dev->channels),
st->num_channels, GFP_KERNEL);
chan_arr = devm_kcalloc(dev, sizeof(*chan_arr), st->num_channels, GFP_KERNEL);
if (!chan_arr)
return -ENOMEM;

View File

@ -1406,6 +1406,9 @@ static int ad7192_probe(struct spi_device *spi)
st->int_vref_mv = ret == -ENODEV ? avdd_mv : ret / MILLI;
st->chip_info = spi_get_device_match_data(spi);
if (!st->chip_info)
return -ENODATA;
indio_dev->name = st->chip_info->name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = st->chip_info->info;

View File

@ -456,7 +456,11 @@ static const struct ad7606_bus_info ad7616_bus_info = {
static int ad7606_spi_probe(struct spi_device *spi)
{
const struct ad7606_bus_info *bus_info = spi_get_device_match_data(spi);
const struct ad7606_bus_info *bus_info;
bus_info = spi_get_device_match_data(spi);
if (!bus_info)
return -ENODATA;
return ad7606_probe(&spi->dev, spi->irq, NULL,
bus_info->chip_info, bus_info->bops);

View File

@ -1829,6 +1829,9 @@ static int ad7768_probe(struct spi_device *spi)
}
st->chip = spi_get_device_match_data(spi);
if (!st->chip)
return -ENODATA;
st->spi = spi;
st->regmap = devm_regmap_init_spi(spi, &ad7768_regmap_config);

1921
drivers/iio/adc/ad7768.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -242,14 +242,6 @@
#define ADE9000_LAST_PAGE_BIT BIT(15)
#define ADE9000_MIDDLE_PAGE_BIT BIT(7)
/*
* Full scale Codes referred from Datasheet. Respective digital codes are
* produced when ADC inputs are at full scale.
*/
#define ADE9000_RMS_FULL_SCALE_CODES 52866837
#define ADE9000_WATT_FULL_SCALE_CODES 20694066
#define ADE9000_PCF_FULL_SCALE_CODES 74770000
/* Phase and channel definitions */
#define ADE9000_PHASE_A_NR 0
#define ADE9000_PHASE_B_NR 1
@ -290,7 +282,29 @@ enum ade9000_wfb_cfg {
#define ADE9000_ADDR_ADJUST(addr, chan) \
(((chan) == 0 ? 0 : (chan) == 1 ? 2 : 4) << 4 | (addr))
/**
* struct ade9000_chip_info - part-specific configuration
* @name: IIO device name reported to userspace
* @channels: channel specification for this part
* @num_channels: number of entries in @channels
* @rms_full_scale_codes: digital code produced at full-scale RMS input
* @watt_full_scale_codes: digital code produced at full-scale power input
* @pcf_full_scale_codes: digital code produced at full-scale xI_PCF/xV_PCF input
*
* The full-scale codes are taken from the respective datasheets and are used to
* derive the IIO scale of the raw measurement channels.
*/
struct ade9000_chip_info {
const char *name;
const struct iio_chan_spec *channels;
unsigned int num_channels;
unsigned int rms_full_scale_codes;
unsigned int watt_full_scale_codes;
unsigned int pcf_full_scale_codes;
};
struct ade9000_state {
const struct ade9000_chip_info *info;
struct completion reset_completion;
struct mutex lock; /* Protects SPI transactions */
u8 wf_src;
@ -488,6 +502,7 @@ static const struct iio_chan_spec_ext_info ade9000_ext_info[] = {
.scan_index = -1 \
}
/* With swell/dip (sag) events - ADE9000 only */
#define ADE9000_ALTVOLTAGE_RMS_CHANNEL(num) { \
.type = IIO_ALTVOLTAGE, \
.channel = num, \
@ -503,6 +518,20 @@ static const struct iio_chan_spec_ext_info ade9000_ext_info[] = {
.scan_index = -1 \
}
/* Without swell/dip events - parts lacking DIP_LVL/SWELL_LVL hardware */
#define ADE9000_ALTVOLTAGE_RMS_CHANNEL_NO_EVENTS(num) { \
.type = IIO_ALTVOLTAGE, \
.channel = num, \
.address = ADE9000_ADDR_ADJUST(ADE9000_REG_AVRMS, num), \
.channel2 = IIO_MOD_RMS, \
.modified = 1, \
.indexed = 1, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_CALIBBIAS), \
.scan_index = -1 \
}
#define ADE9000_POWER_ACTIVE_CHANNEL(num) { \
.type = IIO_POWER, \
.channel = num, \
@ -584,43 +613,82 @@ static const struct iio_chan_spec_ext_info ade9000_ext_info[] = {
.scan_index = -1 \
}
static const struct iio_chan_spec ade9000_channels[] = {
/* Phase A channels */
ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_A_NR),
ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_A_NR),
ADE9000_ALTCURRENT_RMS_CHANNEL(ADE9000_PHASE_A_NR),
ADE9000_ALTVOLTAGE_RMS_CHANNEL(ADE9000_PHASE_A_NR),
ADE9000_POWER_ACTIVE_CHANNEL(ADE9000_PHASE_A_NR),
ADE9000_POWER_REACTIVE_CHANNEL(ADE9000_PHASE_A_NR),
ADE9000_POWER_APPARENT_CHANNEL(ADE9000_PHASE_A_NR),
ADE9000_ENERGY_ACTIVE_CHANNEL(ADE9000_PHASE_A_NR, ADE9000_REG_AWATTHR_LO),
ADE9000_ENERGY_APPARENT_CHANNEL(ADE9000_PHASE_A_NR, ADE9000_REG_AVAHR_LO),
ADE9000_ENERGY_REACTIVE_CHANNEL(ADE9000_PHASE_A_NR, ADE9000_REG_AFVARHR_LO),
ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_A_NR),
/* Phase B channels */
ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_B_NR),
ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_B_NR),
ADE9000_ALTCURRENT_RMS_CHANNEL(ADE9000_PHASE_B_NR),
ADE9000_ALTVOLTAGE_RMS_CHANNEL(ADE9000_PHASE_B_NR),
ADE9000_POWER_ACTIVE_CHANNEL(ADE9000_PHASE_B_NR),
ADE9000_POWER_REACTIVE_CHANNEL(ADE9000_PHASE_B_NR),
ADE9000_POWER_APPARENT_CHANNEL(ADE9000_PHASE_B_NR),
ADE9000_ENERGY_ACTIVE_CHANNEL(ADE9000_PHASE_B_NR, ADE9000_REG_BWATTHR_LO),
ADE9000_ENERGY_APPARENT_CHANNEL(ADE9000_PHASE_B_NR, ADE9000_REG_BVAHR_LO),
ADE9000_ENERGY_REACTIVE_CHANNEL(ADE9000_PHASE_B_NR, ADE9000_REG_BFVARHR_LO),
ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_B_NR),
/* Phase C channels */
ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_C_NR),
ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_C_NR),
ADE9000_ALTCURRENT_RMS_CHANNEL(ADE9000_PHASE_C_NR),
ADE9000_ALTVOLTAGE_RMS_CHANNEL(ADE9000_PHASE_C_NR),
ADE9000_POWER_ACTIVE_CHANNEL(ADE9000_PHASE_C_NR),
ADE9000_POWER_REACTIVE_CHANNEL(ADE9000_PHASE_C_NR),
ADE9000_POWER_APPARENT_CHANNEL(ADE9000_PHASE_C_NR),
ADE9000_ENERGY_ACTIVE_CHANNEL(ADE9000_PHASE_C_NR, ADE9000_REG_CWATTHR_LO),
ADE9000_ENERGY_APPARENT_CHANNEL(ADE9000_PHASE_C_NR, ADE9000_REG_CVAHR_LO),
ADE9000_ENERGY_REACTIVE_CHANNEL(ADE9000_PHASE_C_NR, ADE9000_REG_CFVARHR_LO),
ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_C_NR),
/*
* Declare a full channel array. @altvoltage_rms picks the RMS voltage channel
* variant so parts without dip/swell hardware (e.g. ADE9078) omit those events.
*/
#define ADE9000_DECLARE_CHANNELS(_name, altvoltage_rms) \
static const struct iio_chan_spec _name[] = { \
/* Phase A channels */ \
ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_A_NR), \
ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_A_NR), \
ADE9000_ALTCURRENT_RMS_CHANNEL(ADE9000_PHASE_A_NR), \
altvoltage_rms(ADE9000_PHASE_A_NR), \
ADE9000_POWER_ACTIVE_CHANNEL(ADE9000_PHASE_A_NR), \
ADE9000_POWER_REACTIVE_CHANNEL(ADE9000_PHASE_A_NR), \
ADE9000_POWER_APPARENT_CHANNEL(ADE9000_PHASE_A_NR), \
ADE9000_ENERGY_ACTIVE_CHANNEL(ADE9000_PHASE_A_NR, \
ADE9000_REG_AWATTHR_LO), \
ADE9000_ENERGY_APPARENT_CHANNEL(ADE9000_PHASE_A_NR, \
ADE9000_REG_AVAHR_LO), \
ADE9000_ENERGY_REACTIVE_CHANNEL(ADE9000_PHASE_A_NR, \
ADE9000_REG_AFVARHR_LO), \
ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_A_NR), \
/* Phase B channels */ \
ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_B_NR), \
ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_B_NR), \
ADE9000_ALTCURRENT_RMS_CHANNEL(ADE9000_PHASE_B_NR), \
altvoltage_rms(ADE9000_PHASE_B_NR), \
ADE9000_POWER_ACTIVE_CHANNEL(ADE9000_PHASE_B_NR), \
ADE9000_POWER_REACTIVE_CHANNEL(ADE9000_PHASE_B_NR), \
ADE9000_POWER_APPARENT_CHANNEL(ADE9000_PHASE_B_NR), \
ADE9000_ENERGY_ACTIVE_CHANNEL(ADE9000_PHASE_B_NR, \
ADE9000_REG_BWATTHR_LO), \
ADE9000_ENERGY_APPARENT_CHANNEL(ADE9000_PHASE_B_NR, \
ADE9000_REG_BVAHR_LO), \
ADE9000_ENERGY_REACTIVE_CHANNEL(ADE9000_PHASE_B_NR, \
ADE9000_REG_BFVARHR_LO), \
ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_B_NR), \
/* Phase C channels */ \
ADE9000_CURRENT_CHANNEL(ADE9000_PHASE_C_NR), \
ADE9000_VOLTAGE_CHANNEL(ADE9000_PHASE_C_NR), \
ADE9000_ALTCURRENT_RMS_CHANNEL(ADE9000_PHASE_C_NR), \
altvoltage_rms(ADE9000_PHASE_C_NR), \
ADE9000_POWER_ACTIVE_CHANNEL(ADE9000_PHASE_C_NR), \
ADE9000_POWER_REACTIVE_CHANNEL(ADE9000_PHASE_C_NR), \
ADE9000_POWER_APPARENT_CHANNEL(ADE9000_PHASE_C_NR), \
ADE9000_ENERGY_ACTIVE_CHANNEL(ADE9000_PHASE_C_NR, \
ADE9000_REG_CWATTHR_LO), \
ADE9000_ENERGY_APPARENT_CHANNEL(ADE9000_PHASE_C_NR, \
ADE9000_REG_CVAHR_LO), \
ADE9000_ENERGY_REACTIVE_CHANNEL(ADE9000_PHASE_C_NR, \
ADE9000_REG_CFVARHR_LO), \
ADE9000_POWER_FACTOR_CHANNEL(ADE9000_PHASE_C_NR), \
}
ADE9000_DECLARE_CHANNELS(ade9000_channels, ADE9000_ALTVOLTAGE_RMS_CHANNEL);
ADE9000_DECLARE_CHANNELS(ade9078_channels, ADE9000_ALTVOLTAGE_RMS_CHANNEL_NO_EVENTS);
/*
* Full-scale codes referred from the respective datasheets. These are the
* digital codes produced when the ADC inputs are at full scale.
*/
static const struct ade9000_chip_info ade9000_chip_info = {
.name = "ade9000",
.channels = ade9000_channels,
.num_channels = ARRAY_SIZE(ade9000_channels),
.rms_full_scale_codes = 52866837,
.watt_full_scale_codes = 20694066,
.pcf_full_scale_codes = 74770000,
};
static const struct ade9000_chip_info ade9078_chip_info = {
.name = "ade9078",
.channels = ade9078_channels,
.num_channels = ARRAY_SIZE(ade9078_channels),
.rms_full_scale_codes = 52866837,
.watt_full_scale_codes = 20823646,
.pcf_full_scale_codes = 74680000,
};
static const struct reg_sequence ade9000_initialization_sequence[] = {
@ -1064,7 +1132,7 @@ static int ade9000_read_raw(struct iio_dev *indio_dev,
case ADE9000_REG_CI_PCF:
case ADE9000_REG_CV_PCF:
*val = 1;
*val2 = ADE9000_PCF_FULL_SCALE_CODES;
*val2 = st->info->pcf_full_scale_codes;
return IIO_VAL_FRACTIONAL;
case ADE9000_REG_AIRMS:
case ADE9000_REG_AVRMS:
@ -1073,14 +1141,14 @@ static int ade9000_read_raw(struct iio_dev *indio_dev,
case ADE9000_REG_CIRMS:
case ADE9000_REG_CVRMS:
*val = 1;
*val2 = ADE9000_RMS_FULL_SCALE_CODES;
*val2 = st->info->rms_full_scale_codes;
return IIO_VAL_FRACTIONAL;
default:
return -EINVAL;
}
case IIO_POWER:
*val = 1;
*val2 = ADE9000_WATT_FULL_SCALE_CODES;
*val2 = st->info->watt_full_scale_codes;
return IIO_VAL_FRACTIONAL;
default:
break;
@ -1692,6 +1760,10 @@ static int ade9000_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
st->info = spi_get_device_match_data(spi);
if (!st->info)
return -ENODEV;
regmap = devm_regmap_init(dev, NULL, st, &ade9000_regmap_config);
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), "Unable to allocate ADE9000 regmap");
@ -1726,7 +1798,7 @@ static int ade9000_probe(struct spi_device *spi)
if (ret)
return ret;
indio_dev->name = "ade9000";
indio_dev->name = st->info->name;
indio_dev->info = &ade9000_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->setup_ops = &ade9000_buffer_ops;
@ -1736,8 +1808,8 @@ static int ade9000_probe(struct spi_device *spi)
return dev_err_probe(&spi->dev, ret,
"Failed to get and enable vdd regulator\n");
indio_dev->channels = ade9000_channels;
indio_dev->num_channels = ARRAY_SIZE(ade9000_channels);
indio_dev->channels = st->info->channels;
indio_dev->num_channels = st->info->num_channels;
ret = devm_iio_kfifo_buffer_setup(dev, indio_dev,
&ade9000_buffer_ops);
@ -1768,13 +1840,15 @@ static int ade9000_probe(struct spi_device *spi)
};
static const struct spi_device_id ade9000_id[] = {
{ .name = "ade9000" },
{ .name = "ade9000", .driver_data = (kernel_ulong_t)&ade9000_chip_info },
{ .name = "ade9078", .driver_data = (kernel_ulong_t)&ade9078_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ade9000_id);
static const struct of_device_id ade9000_of_match[] = {
{ .compatible = "adi,ade9000" },
{ .compatible = "adi,ade9000", .data = &ade9000_chip_info },
{ .compatible = "adi,ade9078", .data = &ade9078_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ade9000_of_match);

View File

@ -47,6 +47,9 @@
#define ADI_AXI_ADC_CTRL_DDR_EDGESEL_MASK BIT(1)
#define ADI_AXI_ADC_REG_CNTRL_3 0x004c
/* Bit 8 is common to all AXI ADC cores; bits 7-0 are per-HDL-project. */
#define ADI_AXI_ADC_CNTRL_3_CRC_EN_MASK BIT(8)
#define AXI_AD485X_CNTRL_3_OS_EN_MSK BIT(2)
#define AXI_AD485X_CNTRL_3_PACKET_FORMAT_MSK GENMASK(1, 0)
#define AXI_AD485X_PACKET_FORMAT_20BIT 0x0
@ -596,6 +599,22 @@ static int axi_adc_reg_access(struct iio_backend *back, unsigned int reg,
return regmap_write(st->regmap, reg, writeval);
}
static int axi_adc_crc_enable(struct iio_backend *back)
{
struct adi_axi_adc_state *st = iio_backend_get_priv(back);
return regmap_set_bits(st->regmap, ADI_AXI_ADC_REG_CNTRL_3,
ADI_AXI_ADC_CNTRL_3_CRC_EN_MASK);
}
static int axi_adc_crc_disable(struct iio_backend *back)
{
struct adi_axi_adc_state *st = iio_backend_get_priv(back);
return regmap_clear_bits(st->regmap, ADI_AXI_ADC_REG_CNTRL_3,
ADI_AXI_ADC_CNTRL_3_CRC_EN_MASK);
}
static const struct regmap_config axi_adc_regmap_config = {
.val_bits = 32,
.reg_bits = 32,
@ -644,6 +663,8 @@ static const struct iio_backend_ops adi_axi_adc_ops = {
.num_lanes_set = axi_adc_num_lanes_set,
.debugfs_reg_access = iio_backend_debugfs_ptr(axi_adc_reg_access),
.debugfs_print_chan_status = iio_backend_debugfs_ptr(axi_adc_debugfs_print_chan_status),
.crc_enable = axi_adc_crc_enable,
.crc_disable = axi_adc_crc_disable,
};
static const struct iio_backend_info adi_axi_adc_generic = {
@ -714,6 +735,10 @@ static int adi_axi_adc_probe(struct platform_device *pdev)
if (!st)
return -ENOMEM;
ret = devm_mutex_init(dev, &st->lock);
if (ret)
return ret;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);

View File

@ -2016,6 +2016,8 @@ static void at91_adc_dma_init(struct at91_adc_state *st)
unsigned int pages = DIV_ROUND_UP(AT91_HWFIFO_MAX_SIZE *
sample_size * 2, PAGE_SIZE);
struct device *dma_dev;
if (st->dma_st.dma_chan)
return;
@ -2026,7 +2028,8 @@ static void at91_adc_dma_init(struct at91_adc_state *st)
goto dma_exit;
}
st->dma_st.rx_buf = dma_alloc_coherent(st->dma_st.dma_chan->device->dev,
dma_dev = dmaengine_get_dma_device(st->dma_st.dma_chan);
st->dma_st.rx_buf = dma_alloc_coherent(dma_dev,
pages * PAGE_SIZE,
&st->dma_st.rx_dma_buf,
GFP_KERNEL);
@ -2054,7 +2057,7 @@ static void at91_adc_dma_init(struct at91_adc_state *st)
return;
dma_free_area:
dma_free_coherent(st->dma_st.dma_chan->device->dev, pages * PAGE_SIZE,
dma_free_coherent(dma_dev, pages * PAGE_SIZE,
st->dma_st.rx_buf, st->dma_st.rx_dma_buf);
dma_chan_disable:
dma_release_channel(st->dma_st.dma_chan);
@ -2078,7 +2081,7 @@ static void at91_adc_dma_disable(struct at91_adc_state *st)
/* wait for all transactions to be terminated first*/
dmaengine_terminate_sync(st->dma_st.dma_chan);
dma_free_coherent(st->dma_st.dma_chan->device->dev, pages * PAGE_SIZE,
dma_free_coherent(dmaengine_get_dma_device(st->dma_st.dma_chan), pages * PAGE_SIZE,
st->dma_st.rx_buf, st->dma_st.rx_dma_buf);
dma_release_channel(st->dma_st.dma_chan);
st->dma_st.dma_chan = NULL;
@ -2487,6 +2490,7 @@ static void at91_adc_remove(struct platform_device *pdev)
pm_runtime_disable(st->dev);
pm_runtime_set_suspended(st->dev);
pm_runtime_dont_use_autosuspend(st->dev);
clk_disable_unprepare(st->per_clk);
regulator_disable(st->vref);

View File

@ -0,0 +1,277 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2021-2026 Axiado Corporation
*/
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/cleanup.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/math.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/types.h>
#include <linux/units.h>
#include <linux/iio/iio.h>
/* Register offsets */
#define AX_SARADC_GLOBAL_CTRL_REG 0x0004
#define AX_SARADC_MANUAL_CTRL_REG 0x0008
#define AX_SARADC_DOUT_REG 0x001C
/* GLOBAL_CTRL register fields */
#define AX_SARADC_GLOBAL_CTRL_CH_EN_MASK GENMASK(31, 16)
#define AX_SARADC_GLOBAL_CTRL_SAMPLE_MASK GENMASK(6, 5)
#define AX_SARADC_GLOBAL_CTRL_MODE_MASK GENMASK(4, 3)
#define AX_SARADC_GLOBAL_CTRL_PD BIT(2)
#define AX_SARADC_GLOBAL_CTRL_ENABLE BIT(0)
/* GLOBAL_CTRL SAMPLE_MASK field value: 0 selects 16 samples. */
#define AX_SARADC_GLOBAL_CTRL_SAMPLE_16 0
/* GLOBAL_CTRL MODE_MASK field value: 1 selects manual mode. */
#define AX_SARADC_GLOBAL_CTRL_MODE_MANUAL 1
/* MANUAL_CTRL register fields */
#define AX_SARADC_MANUAL_CTRL_ENABLE BIT(0)
#define AX_SARADC_MANUAL_CTRL_CH_SEL_MASK GENMASK(4, 1)
#define AX_RESOLUTION_BITS 10
#define AX_SARADC_CONV_CYCLES 13
#define AX_SARADC_CONV_DELAY_MARGIN_US 10
struct axiado_saradc {
struct regmap *regmap;
struct mutex lock; /* Serializes ADC conversions. */
unsigned long clk_rate;
int vref_uV;
};
/*
* Registers contain transient control, status, and conversion data,
* so accesses must always go directly to hardware.
*/
static const struct regmap_config axiado_saradc_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
.max_register = AX_SARADC_DOUT_REG,
.val_format_endian = REGMAP_ENDIAN_LITTLE,
};
static int axiado_saradc_conversion(struct axiado_saradc *info,
struct iio_chan_spec const *chan, int *val)
{
unsigned long usecs;
unsigned int regval;
int ret;
guard(mutex)(&info->lock);
/* Select the channel to be used and trigger conversion. */
ret = regmap_write(info->regmap, AX_SARADC_MANUAL_CTRL_REG,
AX_SARADC_MANUAL_CTRL_ENABLE |
FIELD_PREP(AX_SARADC_MANUAL_CTRL_CH_SEL_MASK, chan->channel));
if (ret)
return ret;
/* Hardware requires 13 conversion cycles at clk_rate. */
usecs = DIV_ROUND_UP(AX_SARADC_CONV_CYCLES * USEC_PER_SEC, info->clk_rate);
fsleep(usecs + AX_SARADC_CONV_DELAY_MARGIN_US);
ret = regmap_read(info->regmap, AX_SARADC_DOUT_REG, &regval);
/* Best effort to stop manual conversion. */
regmap_write(info->regmap, AX_SARADC_MANUAL_CTRL_REG, 0);
if (ret)
return ret;
*val = regval & GENMASK(AX_RESOLUTION_BITS - 1, 0);
return 0;
}
static int axiado_saradc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct axiado_saradc *info = iio_priv(indio_dev);
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = axiado_saradc_conversion(info, chan, val);
if (ret)
return ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
*val = info->vref_uV / (MICRO / MILLI);
*val2 = AX_RESOLUTION_BITS;
return IIO_VAL_FRACTIONAL_LOG2;
default:
return -EINVAL;
}
}
static const struct iio_info axiado_saradc_iio_info = {
.read_raw = axiado_saradc_read_raw,
};
struct axiado_saradc_soc_data {
const char *name;
unsigned int num_channels;
};
static const struct axiado_saradc_soc_data ax3000_saradc_data = {
.name = "ax3000_saradc",
.num_channels = 16,
};
static const struct axiado_saradc_soc_data ax3005_saradc_data = {
.name = "ax3005_saradc",
.num_channels = 8,
};
#define AX_SARADC_CH(_index) \
{ \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = (_index), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.datasheet_name = "adc" #_index, \
}
static const struct iio_chan_spec axiado_saradc_iio_channels[] = {
AX_SARADC_CH(0),
AX_SARADC_CH(1),
AX_SARADC_CH(2),
AX_SARADC_CH(3),
AX_SARADC_CH(4),
AX_SARADC_CH(5),
AX_SARADC_CH(6),
AX_SARADC_CH(7),
AX_SARADC_CH(8),
AX_SARADC_CH(9),
AX_SARADC_CH(10),
AX_SARADC_CH(11),
AX_SARADC_CH(12),
AX_SARADC_CH(13),
AX_SARADC_CH(14),
AX_SARADC_CH(15),
};
static void axiado_saradc_disable(void *map)
{
regmap_write(map, AX_SARADC_GLOBAL_CTRL_REG, AX_SARADC_GLOBAL_CTRL_PD);
}
static int axiado_saradc_probe(struct platform_device *pdev)
{
const struct axiado_saradc_soc_data *soc_data;
struct device *dev = &pdev->dev;
struct axiado_saradc *info;
struct iio_dev *indio_dev;
void __iomem *regs;
struct regmap *map;
struct clk *clk;
u32 regval;
int ret;
indio_dev = devm_iio_device_alloc(dev, sizeof(*info));
if (!indio_dev)
return -ENOMEM;
info = iio_priv(indio_dev);
regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(regs))
return PTR_ERR(regs);
map = devm_regmap_init_mmio(dev, regs, &axiado_saradc_regmap_config);
if (IS_ERR(map))
return PTR_ERR(map);
info->regmap = map;
clk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(clk))
return PTR_ERR(clk);
info->clk_rate = clk_get_rate(clk);
if (!info->clk_rate)
return dev_err_probe(dev, -EINVAL, "invalid clock rate\n");
ret = devm_regulator_get_enable_read_voltage(dev, "vref");
if (ret < 0)
return dev_err_probe(dev, ret, "failed to get vref voltage\n");
info->vref_uV = ret;
soc_data = device_get_match_data(dev);
if (!soc_data)
return dev_err_probe(dev, -ENODATA, "failed to get match data\n");
ret = devm_mutex_init(dev, &info->lock);
if (ret)
return ret;
regval = FIELD_PREP(AX_SARADC_GLOBAL_CTRL_CH_EN_MASK,
GENMASK(soc_data->num_channels - 1, 0)) |
FIELD_PREP(AX_SARADC_GLOBAL_CTRL_SAMPLE_MASK,
AX_SARADC_GLOBAL_CTRL_SAMPLE_16) |
FIELD_PREP(AX_SARADC_GLOBAL_CTRL_MODE_MASK,
AX_SARADC_GLOBAL_CTRL_MODE_MANUAL) |
AX_SARADC_GLOBAL_CTRL_ENABLE;
ret = regmap_write(map, AX_SARADC_GLOBAL_CTRL_REG, regval);
if (ret)
return ret;
ret = devm_add_action_or_reset(dev, axiado_saradc_disable, map);
if (ret)
return ret;
indio_dev->name = soc_data->name;
indio_dev->info = &axiado_saradc_iio_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = axiado_saradc_iio_channels;
indio_dev->num_channels = soc_data->num_channels;
return devm_iio_device_register(dev, indio_dev);
}
static const struct of_device_id axiado_saradc_match[] = {
{
.compatible = "axiado,ax3000-saradc",
.data = &ax3000_saradc_data,
},
{
.compatible = "axiado,ax3005-saradc",
.data = &ax3005_saradc_data,
},
{ }
};
MODULE_DEVICE_TABLE(of, axiado_saradc_match);
static struct platform_driver axiado_saradc_driver = {
.driver = {
.name = "axiado-saradc",
.of_match_table = axiado_saradc_match,
},
.probe = axiado_saradc_probe,
};
module_platform_driver(axiado_saradc_driver);
MODULE_AUTHOR("Axiado Corporation");
MODULE_DESCRIPTION("Axiado SARADC driver");
MODULE_LICENSE("GPL");

View File

@ -3,14 +3,18 @@
* Copyright 2016 Broadcom
*/
#include <linux/module.h>
#include <linux/io.h>
#include <linux/array_size.h>
#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/types.h>
#include <linux/iio/iio.h>
@ -106,7 +110,6 @@ do { \
struct iproc_adc_priv {
struct regmap *regmap;
struct clk *adc_clk;
struct mutex mutex;
int irqno;
int chan_val;
@ -448,6 +451,11 @@ static void iproc_adc_disable(struct iio_dev *indio_dev)
}
}
static void iproc_adc_disable_action(void *indio_dev)
{
iproc_adc_disable(indio_dev);
}
static int iproc_adc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
@ -506,35 +514,31 @@ static int iproc_adc_probe(struct platform_device *pdev)
{
struct iproc_adc_priv *adc_priv;
struct iio_dev *indio_dev = NULL;
struct device *dev = &pdev->dev;
struct clk *adc_clk;
int ret;
indio_dev = devm_iio_device_alloc(&pdev->dev,
sizeof(*adc_priv));
indio_dev = devm_iio_device_alloc(dev, sizeof(*adc_priv));
if (!indio_dev)
return -ENOMEM;
adc_priv = iio_priv(indio_dev);
platform_set_drvdata(pdev, indio_dev);
mutex_init(&adc_priv->mutex);
ret = devm_mutex_init(dev, &adc_priv->mutex);
if (ret)
return ret;
init_completion(&adc_priv->completion);
adc_priv->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
"adc-syscon");
if (IS_ERR(adc_priv->regmap)) {
dev_err(&pdev->dev, "failed to get handle for tsc syscon\n");
ret = PTR_ERR(adc_priv->regmap);
return ret;
}
if (IS_ERR(adc_priv->regmap))
return dev_err_probe(dev, PTR_ERR(adc_priv->regmap),
"failed to get handle for tsc syscon\n");
adc_priv->adc_clk = devm_clk_get(&pdev->dev, "tsc_clk");
if (IS_ERR(adc_priv->adc_clk)) {
dev_err(&pdev->dev,
"failed getting clock tsc_clk\n");
ret = PTR_ERR(adc_priv->adc_clk);
return ret;
}
adc_clk = devm_clk_get_enabled(dev, "tsc_clk");
if (IS_ERR(adc_clk))
return dev_err_probe(dev, PTR_ERR(adc_clk), "failed to enable clock\n");
adc_priv->irqno = platform_get_irq(pdev, 0);
if (adc_priv->irqno < 0)
@ -542,32 +546,23 @@ static int iproc_adc_probe(struct platform_device *pdev)
ret = regmap_clear_bits(adc_priv->regmap, IPROC_REGCTL2,
IPROC_ADC_AUXIN_SCAN_ENA);
if (ret) {
dev_err(&pdev->dev, "failed to write IPROC_REGCTL2 %d\n", ret);
return ret;
}
if (ret)
return dev_err_probe(dev, ret, "failed to write IPROC_REGCTL2\n");
ret = devm_request_threaded_irq(&pdev->dev, adc_priv->irqno,
ret = devm_request_threaded_irq(dev, adc_priv->irqno,
iproc_adc_interrupt_handler,
iproc_adc_interrupt_thread,
IRQF_SHARED, "iproc-adc", indio_dev);
if (ret) {
dev_err(&pdev->dev, "request_irq error %d\n", ret);
if (ret)
return ret;
}
ret = clk_prepare_enable(adc_priv->adc_clk);
if (ret) {
dev_err(&pdev->dev,
"clk_prepare_enable failed %d\n", ret);
return ret;
}
ret = iproc_adc_enable(indio_dev);
if (ret) {
dev_err(&pdev->dev, "failed to enable adc %d\n", ret);
goto err_adc_enable;
}
if (ret)
return ret;
ret = devm_add_action_or_reset(dev, iproc_adc_disable_action, indio_dev);
if (ret)
return ret;
indio_dev->name = "iproc-static-adc";
indio_dev->info = &iproc_adc_iio_info;
@ -575,30 +570,7 @@ static int iproc_adc_probe(struct platform_device *pdev)
indio_dev->channels = iproc_adc_iio_channels;
indio_dev->num_channels = ARRAY_SIZE(iproc_adc_iio_channels);
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(&pdev->dev, "iio_device_register failed:err %d\n", ret);
goto err_clk;
}
return 0;
err_clk:
iproc_adc_disable(indio_dev);
err_adc_enable:
clk_disable_unprepare(adc_priv->adc_clk);
return ret;
}
static void iproc_adc_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct iproc_adc_priv *adc_priv = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
iproc_adc_disable(indio_dev);
clk_disable_unprepare(adc_priv->adc_clk);
return devm_iio_device_register(dev, indio_dev);
}
static const struct of_device_id iproc_adc_of_match[] = {
@ -609,7 +581,6 @@ MODULE_DEVICE_TABLE(of, iproc_adc_of_match);
static struct platform_driver iproc_adc_driver = {
.probe = iproc_adc_probe,
.remove = iproc_adc_remove,
.driver = {
.name = "iproc-static-adc",
.of_match_table = iproc_adc_of_match,

View File

@ -9,9 +9,11 @@
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/driver.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/regulator/consumer.h>
#include <linux/units.h>
#include "ltc2497.h"
@ -19,24 +21,54 @@
#define LTC2497_DIFF 0
#define LTC2497_SIGN BIT(3)
static int ltc2497core_wait_conv(struct ltc2497core_driverdata *ddata)
/*
* Output-rate modes, indexed by ltc2497core_driverdata.speed_2x
* (0 = 1x, the power-on default; 1 = 2x, LTC2499 only). The advertised
* sampling_frequency and the conversion-time budget are two views of the same
* mode, so they are kept in lock-step here.
*/
static const int ltc2497core_samp_freq_avail[] = {
6, 800000, /* 1x: ~6.8 Hz (1 / t_CONV_1 typ 146.9ms) */
13, 600000, /* 2x: ~13.6 Hz (1 / t_CONV_2 typ 73.6ms) */
};
static const unsigned int ltc2497core_conv_time_ms_tbl[] = {
LTC2497_CONV_TIME_1X_MS, /* 1x */
LTC2499_CONV_TIME_2X_MS, /* 2x */
};
static unsigned int ltc2497core_conv_time_ms(struct ltc2497core_driverdata *ddata,
u8 address)
{
/*
* SPD is ignored by the part during a temperature measurement: it
* always converts at 1x, so budget the 1x time regardless of the
* selected voltage-channel mode.
*/
if (address == LTC2497_TEMP_ADDR)
return ltc2497core_conv_time_ms_tbl[0];
return ltc2497core_conv_time_ms_tbl[ddata->speed_2x];
}
static int ltc2497core_wait_conv(struct ltc2497core_driverdata *ddata,
unsigned int conv_time_ms)
{
s64 time_elapsed;
time_elapsed = ktime_ms_delta(ktime_get(), ddata->time_prev);
if (time_elapsed < LTC2497_CONVERSION_TIME_MS) {
if (time_elapsed < conv_time_ms) {
/* delay if conversion time not passed
* since last read or write
*/
if (msleep_interruptible(
LTC2497_CONVERSION_TIME_MS - time_elapsed))
if (msleep_interruptible(conv_time_ms - time_elapsed))
return -ERESTARTSYS;
return 0;
}
if (time_elapsed - LTC2497_CONVERSION_TIME_MS <= 0) {
if (time_elapsed - conv_time_ms <= 0) {
/* We're in automatic mode -
* so the last reading is still not outdated
*/
@ -48,9 +80,18 @@ static int ltc2497core_wait_conv(struct ltc2497core_driverdata *ddata)
static int ltc2497core_read(struct ltc2497core_driverdata *ddata, u8 address, int *val)
{
unsigned int conv_time_ms = ltc2497core_conv_time_ms(ddata, address);
int ret;
ret = ltc2497core_wait_conv(ddata);
/*
* Wait for the conversion currently in flight, whose duration was fixed
* by the mode active when it was started (ddata->conv_time_prev). This
* can be longer than the freshly selected mode's time - e.g. a 1x
* conversion is still running when the first 2x read arrives after a
* sampling_frequency change - and reprogramming the device before it
* finishes would be NACKed (-EIO).
*/
ret = ltc2497core_wait_conv(ddata, ddata->conv_time_prev);
if (ret < 0)
return ret;
@ -60,7 +101,17 @@ static int ltc2497core_read(struct ltc2497core_driverdata *ddata, u8 address, in
return ret;
ddata->addr_prev = address;
if (msleep_interruptible(LTC2497_CONVERSION_TIME_MS))
/*
* The reprogram above starts a conversion in the new mode.
* Record its start time and duration before sleeping, so that if
* msleep_interruptible() is interrupted the conversion state is
* already consistent: the next retry then waits only the time
* remaining from the real start instead of from a stale
* time_prev, which would let it reprogram/read too early.
*/
ddata->time_prev = ktime_get();
ddata->conv_time_prev = conv_time_ms;
if (msleep_interruptible(conv_time_ms))
return -ERESTARTSYS;
}
@ -69,6 +120,8 @@ static int ltc2497core_read(struct ltc2497core_driverdata *ddata, u8 address, in
return ret;
ddata->time_prev = ktime_get();
/* The read above auto-starts the next conversion in the current mode. */
ddata->conv_time_prev = conv_time_ms;
return ret;
}
@ -95,74 +148,209 @@ static int ltc2497core_read_raw(struct iio_dev *indio_dev,
if (ret < 0)
return ret;
*val = ret / 1000;
*val2 = ddata->chip_info->resolution + 1;
switch (chan->type) {
case IIO_TEMP:
/*
* raw is normalised to 2^(resolution + 1), i.e.
* raw = 2 * DATAOUT24, so the PTAT scale (datasheet
* Vref / 1570 per Kelvin) doubles its denominator and,
* in m°C, becomes Vref_uV / 3140000.
*/
*val = ret;
*val2 = 3140000;
return IIO_VAL_FRACTIONAL;
case IIO_VOLTAGE:
*val = ret / (MICRO / MILLI);
*val2 = ddata->chip_info->resolution + 1;
return IIO_VAL_FRACTIONAL_LOG2;
default:
return -EINVAL;
}
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_OFFSET:
switch (chan->type) {
case IIO_TEMP:
ret = regulator_get_voltage(ddata->ref);
if (ret < 0)
return ret;
if (ret == 0)
return -EINVAL;
/*
* 0 °C == 273.15 K must map to raw + offset such that
* (raw + offset) * scale == 0 m°C, i.e.
* offset = -273150 / scale
* = -273150 * 3140000 / Vref_uV
* Computed in 64-bit to avoid overflow.
*/
*val = div_s64(ABSOLUTE_ZERO_MILLICELSIUS * 3140000LL, ret);
return IIO_VAL_INT;
default:
return -EINVAL;
}
case IIO_CHAN_INFO_SAMP_FREQ:
/*
* Only advertised on the voltage channels of parts with a speed
* mode; the sampling frequency is a property of the selected 1x/2x
* mode, not of an individual conversion.
*/
mutex_lock(&ddata->lock);
*val = ltc2497core_samp_freq_avail[ddata->speed_2x * 2];
*val2 = ltc2497core_samp_freq_avail[ddata->speed_2x * 2 + 1];
mutex_unlock(&ddata->lock);
return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
}
#define LTC2497_CHAN(_chan, _addr, _ds_name) { \
static int ltc2497core_read_avail(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
const int **vals, int *type, int *length,
long mask)
{
switch (mask) {
case IIO_CHAN_INFO_SAMP_FREQ:
*vals = ltc2497core_samp_freq_avail;
*type = IIO_VAL_INT_PLUS_MICRO;
*length = ARRAY_SIZE(ltc2497core_samp_freq_avail);
return IIO_AVAIL_LIST;
default:
return -EINVAL;
}
}
static int ltc2497core_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct ltc2497core_driverdata *ddata = iio_priv(indio_dev);
unsigned int i;
bool speed_2x;
switch (mask) {
case IIO_CHAN_INFO_SAMP_FREQ:
/* Match the (val, val2) pair against the advertised rates. */
for (i = 0; i < ARRAY_SIZE(ltc2497core_samp_freq_avail); i += 2) {
if (val == ltc2497core_samp_freq_avail[i] &&
val2 == ltc2497core_samp_freq_avail[i + 1])
break;
}
if (i == ARRAY_SIZE(ltc2497core_samp_freq_avail))
return -EINVAL;
speed_2x = i / 2;
mutex_lock(&ddata->lock);
ddata->speed_2x = speed_2x;
/*
* The new speed only takes effect once the second command byte
* is reprogrammed, so force the next read to reprogram rather
* than reuse the value already latched for this address.
* LTC2497_CONFIG_DEFAULT is not a valid channel/temperature
* address, so it is a safe re-arm sentinel (as used at probe).
*
* A conversion started under the old speed may still be in
* flight; its own duration (conv_time_prev), not the new mode's,
* still gates the next reprogram, so the timing state is left
* untouched here.
*/
ddata->addr_prev = LTC2497_CONFIG_DEFAULT;
mutex_unlock(&ddata->lock);
return 0;
default:
return -EINVAL;
}
}
#define LTC2497_CHAN(_chan, _addr, _ds_name, _extra_mask) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = (_chan), \
.address = (_addr | (_chan / 2) | ((_chan & 1) ? LTC2497_SIGN : 0)), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | (_extra_mask), \
.info_mask_shared_by_type_available = (_extra_mask), \
.datasheet_name = (_ds_name), \
}
#define LTC2497_CHAN_DIFF(_chan, _addr) { \
#define LTC2497_CHAN_DIFF(_chan, _addr, _extra_mask) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = (_chan) * 2 + ((_addr) & LTC2497_SIGN ? 1 : 0), \
.channel2 = (_chan) * 2 + ((_addr) & LTC2497_SIGN ? 0 : 1),\
.address = (_addr | _chan), \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | (_extra_mask), \
.info_mask_shared_by_type_available = (_extra_mask), \
.differential = 1, \
}
static const struct iio_chan_spec ltc2497core_channel[] = {
LTC2497_CHAN(0, LTC2497_SGL, "CH0"),
LTC2497_CHAN(1, LTC2497_SGL, "CH1"),
LTC2497_CHAN(2, LTC2497_SGL, "CH2"),
LTC2497_CHAN(3, LTC2497_SGL, "CH3"),
LTC2497_CHAN(4, LTC2497_SGL, "CH4"),
LTC2497_CHAN(5, LTC2497_SGL, "CH5"),
LTC2497_CHAN(6, LTC2497_SGL, "CH6"),
LTC2497_CHAN(7, LTC2497_SGL, "CH7"),
LTC2497_CHAN(8, LTC2497_SGL, "CH8"),
LTC2497_CHAN(9, LTC2497_SGL, "CH9"),
LTC2497_CHAN(10, LTC2497_SGL, "CH10"),
LTC2497_CHAN(11, LTC2497_SGL, "CH11"),
LTC2497_CHAN(12, LTC2497_SGL, "CH12"),
LTC2497_CHAN(13, LTC2497_SGL, "CH13"),
LTC2497_CHAN(14, LTC2497_SGL, "CH14"),
LTC2497_CHAN(15, LTC2497_SGL, "CH15"),
LTC2497_CHAN_DIFF(0, LTC2497_DIFF),
LTC2497_CHAN_DIFF(1, LTC2497_DIFF),
LTC2497_CHAN_DIFF(2, LTC2497_DIFF),
LTC2497_CHAN_DIFF(3, LTC2497_DIFF),
LTC2497_CHAN_DIFF(4, LTC2497_DIFF),
LTC2497_CHAN_DIFF(5, LTC2497_DIFF),
LTC2497_CHAN_DIFF(6, LTC2497_DIFF),
LTC2497_CHAN_DIFF(7, LTC2497_DIFF),
LTC2497_CHAN_DIFF(0, LTC2497_DIFF | LTC2497_SIGN),
LTC2497_CHAN_DIFF(1, LTC2497_DIFF | LTC2497_SIGN),
LTC2497_CHAN_DIFF(2, LTC2497_DIFF | LTC2497_SIGN),
LTC2497_CHAN_DIFF(3, LTC2497_DIFF | LTC2497_SIGN),
LTC2497_CHAN_DIFF(4, LTC2497_DIFF | LTC2497_SIGN),
LTC2497_CHAN_DIFF(5, LTC2497_DIFF | LTC2497_SIGN),
LTC2497_CHAN_DIFF(6, LTC2497_DIFF | LTC2497_SIGN),
LTC2497_CHAN_DIFF(7, LTC2497_DIFF | LTC2497_SIGN),
};
/*
* SPD is ignored by the part during a temperature measurement, so the
* temperature channel carries no sampling-frequency attribute.
*/
#define LTC2497_TEMP_CHANNEL { \
.type = IIO_TEMP, \
.address = LTC2497_TEMP_ADDR, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_OFFSET), \
}
/*
* Parts with a speed mode advertise sampling_frequency on their voltage
* channels; the two tables are otherwise identical.
*/
#define LTC2497_DEFINE_CHANNELS(_name, _extra_mask) \
static const struct iio_chan_spec _name[] = { \
LTC2497_CHAN(0, LTC2497_SGL, "CH0", _extra_mask), \
LTC2497_CHAN(1, LTC2497_SGL, "CH1", _extra_mask), \
LTC2497_CHAN(2, LTC2497_SGL, "CH2", _extra_mask), \
LTC2497_CHAN(3, LTC2497_SGL, "CH3", _extra_mask), \
LTC2497_CHAN(4, LTC2497_SGL, "CH4", _extra_mask), \
LTC2497_CHAN(5, LTC2497_SGL, "CH5", _extra_mask), \
LTC2497_CHAN(6, LTC2497_SGL, "CH6", _extra_mask), \
LTC2497_CHAN(7, LTC2497_SGL, "CH7", _extra_mask), \
LTC2497_CHAN(8, LTC2497_SGL, "CH8", _extra_mask), \
LTC2497_CHAN(9, LTC2497_SGL, "CH9", _extra_mask), \
LTC2497_CHAN(10, LTC2497_SGL, "CH10", _extra_mask), \
LTC2497_CHAN(11, LTC2497_SGL, "CH11", _extra_mask), \
LTC2497_CHAN(12, LTC2497_SGL, "CH12", _extra_mask), \
LTC2497_CHAN(13, LTC2497_SGL, "CH13", _extra_mask), \
LTC2497_CHAN(14, LTC2497_SGL, "CH14", _extra_mask), \
LTC2497_CHAN(15, LTC2497_SGL, "CH15", _extra_mask), \
LTC2497_CHAN_DIFF(0, LTC2497_DIFF, _extra_mask), \
LTC2497_CHAN_DIFF(1, LTC2497_DIFF, _extra_mask), \
LTC2497_CHAN_DIFF(2, LTC2497_DIFF, _extra_mask), \
LTC2497_CHAN_DIFF(3, LTC2497_DIFF, _extra_mask), \
LTC2497_CHAN_DIFF(4, LTC2497_DIFF, _extra_mask), \
LTC2497_CHAN_DIFF(5, LTC2497_DIFF, _extra_mask), \
LTC2497_CHAN_DIFF(6, LTC2497_DIFF, _extra_mask), \
LTC2497_CHAN_DIFF(7, LTC2497_DIFF, _extra_mask), \
LTC2497_CHAN_DIFF(0, LTC2497_DIFF | LTC2497_SIGN, _extra_mask), \
LTC2497_CHAN_DIFF(1, LTC2497_DIFF | LTC2497_SIGN, _extra_mask), \
LTC2497_CHAN_DIFF(2, LTC2497_DIFF | LTC2497_SIGN, _extra_mask), \
LTC2497_CHAN_DIFF(3, LTC2497_DIFF | LTC2497_SIGN, _extra_mask), \
LTC2497_CHAN_DIFF(4, LTC2497_DIFF | LTC2497_SIGN, _extra_mask), \
LTC2497_CHAN_DIFF(5, LTC2497_DIFF | LTC2497_SIGN, _extra_mask), \
LTC2497_CHAN_DIFF(6, LTC2497_DIFF | LTC2497_SIGN, _extra_mask), \
LTC2497_CHAN_DIFF(7, LTC2497_DIFF | LTC2497_SIGN, _extra_mask), \
LTC2497_TEMP_CHANNEL, \
}
LTC2497_DEFINE_CHANNELS(ltc2497core_channel, 0);
LTC2497_DEFINE_CHANNELS(ltc2497core_channel_samp_freq, BIT(IIO_CHAN_INFO_SAMP_FREQ));
static const struct iio_info ltc2497core_info = {
.read_raw = ltc2497core_read_raw,
.read_avail = ltc2497core_read_avail,
.write_raw = ltc2497core_write_raw,
};
int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev)
@ -182,8 +370,15 @@ int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev)
indio_dev->info = &ltc2497core_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = ltc2497core_channel;
indio_dev->num_channels = ARRAY_SIZE(ltc2497core_channel);
if (ddata->chip_info->has_speed_mode)
indio_dev->channels = ltc2497core_channel_samp_freq;
else
indio_dev->channels = ltc2497core_channel;
/* Only the ltc2499 has a temperature channel; it is the last entry. */
if (ddata->chip_info->has_temp)
indio_dev->num_channels = ARRAY_SIZE(ltc2497core_channel);
else
indio_dev->num_channels = ARRAY_SIZE(ltc2497core_channel) - 1;
ret = ddata->result_and_measure(ddata, LTC2497_CONFIG_DEFAULT, NULL);
if (ret < 0)
@ -209,6 +404,8 @@ int ltc2497core_probe(struct device *dev, struct iio_dev *indio_dev)
ddata->addr_prev = LTC2497_CONFIG_DEFAULT;
ddata->time_prev = ktime_get();
/* Power-on default mode is 1x; a conversion is already in flight. */
ddata->conv_time_prev = LTC2497_CONV_TIME_1X_MS;
mutex_init(&ddata->lock);

View File

@ -84,6 +84,46 @@ static int ltc2497_result_and_measure(struct ltc2497core_driverdata *ddata,
return 0;
}
/*
* Parts with a second config byte (LTC2499: internal PTAT sensor and/or
* the 2x speed mode) latch their converter configuration from that byte
* and only re-evaluate it when EN2 is set; a single byte, or a second
* byte with EN2 = 0, means "keep previous". A one-byte channel select
* therefore cannot pull the device back out of temperature mode, so a
* voltage read after a temperature read would keep returning the PTAT
* result. Always drive the second byte with EN2 set on these parts:
* - temperature read: IM = 1 (SPD is ignored by the part in
* temperature mode and is left 0 here);
* - voltage read: IM = 0 (external input), plus SPD when 2x is
* selected.
* FA = FB = 0 keeps the power-on simultaneous 50/60Hz rejection, whose
* worst-case conversion time the driver's wait already covers.
*
* The byte could be skipped while the latched configuration is already
* the one wanted; it is sent on every conversion for simplicity.
*/
if (ddata->chip_info->has_temp || ddata->chip_info->has_speed_mode) {
u8 cmd[2];
if (address == LTC2497_TEMP_ADDR) {
cmd[0] = LTC2497_ENABLE | LTC2497_CONFIG_DEFAULT;
cmd[1] = LTC2499_EN2 | LTC2499_IM;
} else {
cmd[0] = LTC2497_ENABLE | address;
cmd[1] = LTC2499_EN2;
if (ddata->speed_2x)
cmd[1] |= LTC2499_SPD;
}
ret = i2c_master_send(st->client, cmd, sizeof(cmd));
if (ret < 0) {
dev_err(&st->client->dev, "i2c transfer failed: %pe\n",
ERR_PTR(ret));
return ret;
}
return 0;
}
ret = i2c_smbus_write_byte(st->client,
LTC2497_ENABLE | address);
if (ret)
@ -137,6 +177,8 @@ static const struct ltc2497_chip_info ltc2497_info[] = {
[TYPE_LTC2499] = {
.resolution = 24,
.name = "ltc2499",
.has_temp = true,
.has_speed_mode = true,
},
};

View File

@ -2,11 +2,35 @@
#define LTC2497_ENABLE 0xA0
#define LTC2497_CONFIG_DEFAULT LTC2497_ENABLE
#define LTC2497_CONVERSION_TIME_MS 150ULL
/*
* Conversion-time bounds used to gate reads. Each value is the datasheet
* t_CONV maximum, rounded UP to the next whole millisecond.
*
* The 2x mode (LTC2499_SPD, LTC2499 only) disables the offset auto-calibration
* to roughly double the output rate; adding the 2x wait time is what makes the
* SPD control actually faster.
*/
#define LTC2497_CONV_TIME_1X_MS 150ULL /* ceil(t_CONV_1 simult. max 149.9) */
#define LTC2499_CONV_TIME_2X_MS 76ULL /* ceil(t_CONV_2 simult. max 75.1) */
/*
* Sentinel passed as `address` to result_and_measure() to request a
* temperature conversion instead of a voltage channel. Valid channel
* addresses fit in 5 bits (0x00–0x1F), so 0xFF is unambiguous.
*/
#define LTC2497_TEMP_ADDR 0xFF
/* Second config-byte bits (LTC2499 / LTC2493 only) */
#define LTC2499_EN2 BIT(7) /* enable second config byte */
#define LTC2499_IM BIT(6) /* 1 = measure internal temp sensor */
#define LTC2499_SPD BIT(3) /* 1 = 2x output rate (offset cal off) */
struct ltc2497_chip_info {
u32 resolution;
const char *name;
u32 resolution;
bool has_temp;
bool has_speed_mode; /* SPD bit in the 2nd config byte (LTC2499/LTC2493) */
};
struct ltc2497core_driverdata {
@ -16,6 +40,9 @@ struct ltc2497core_driverdata {
struct mutex lock;
const struct ltc2497_chip_info *chip_info;
u8 addr_prev;
bool speed_2x; /* SPD: false = 1x (default), true = 2x */
/* Conversion time (ms) of the conversion currently in flight. */
unsigned int conv_time_prev;
int (*result_and_measure)(struct ltc2497core_driverdata *ddata,
u8 address, int *val);
};

View File

@ -117,6 +117,8 @@ static int max11205_probe(struct spi_device *spi)
ad_sd_init(&st->sd, indio_dev, spi, &max11205_sigma_delta_info);
st->chip_info = spi_get_device_match_data(spi);
if (!st->chip_info)
return -ENODATA;
indio_dev->name = st->chip_info->name;
indio_dev->modes = INDIO_DIRECT_MODE;

View File

@ -366,6 +366,7 @@ static const struct spi_device_id max14001_id_table[] = {
{ .name = "max14002", .driver_data = (kernel_ulong_t)&max14002_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, max14001_id_table);
static const struct of_device_id max14001_of_match[] = {
{ .compatible = "adi,max14001", .data = &max14001_chip_info },

574
drivers/iio/adc/max40080.c Normal file
View File

@ -0,0 +1,574 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* MAX40080 Digital Current-Sense Amplifier driver
*
* Copyright 2026 Analog Devices, Inc.
*
* Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/MAX40080.pdf
*/
#include <linux/array_size.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/cleanup.h>
#include <linux/i2c.h>
#include <linux/iopoll.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/property.h>
#include <linux/time.h>
#include <linux/types.h>
#include <linux/units.h>
#include <asm/byteorder.h>
#include <linux/iio/iio.h>
#define MAX40080_REG_CFG 0x00
#define MAX40080_CFG_MODE_MSK GENMASK(2, 0)
#define MAX40080_CFG_PEC_EN_MSK BIT(5)
#define MAX40080_CFG_RANGE_MSK BIT(6)
#define MAX40080_CFG_FILTER_MSK GENMASK(14, 12)
#define MAX40080_REG_FIFO_CFG 0x0A
#define MAX40080_FIFO_CFG_STORE_IV_MSK GENMASK(1, 0)
#define MAX40080_REG_IV 0x10
/* Current is a 13-bit two's-complement value (magnitude + sign bit). */
#define MAX40080_IV_I_MSK GENMASK(12, 0)
#define MAX40080_IV_I_SIGN_BIT 12
#define MAX40080_IV_V_MAG_MSK GENMASK(27, 16)
#define MAX40080_IV_VALID_MSK BIT(31)
/* CFG.mode field values. */
#define MAX40080_CFG_MODE_STDBY 0x00
#define MAX40080_CFG_MODE_SINGLE 0x02
/* CFG.range field values. */
#define MAX40080_CFG_RANGE_50mV 0
#define MAX40080_CFG_RANGE_10mV 1
/* FIFO_CFG.store_iv field values. */
#define MAX40080_FIFO_CFG_STORE_IV 0x02
#define MAX40080_ADC_RES_BITS 12
#define MAX40080_INTER_VREF_mV 1250
#define MAX40080_V_BUFF_GAIN 30
#define MAX40080_CSA_50mV_GAIN 25
#define MAX40080_CSA_10mV_GAIN 125
/*
* The RANGE field (CFG bit 6) selects one of two current-sense full-scale
* ranges (the MAX40080 supports exactly two: +/-50 mV and +/-10 mV). Indexed
* by the CFG.range field value.
*/
static const int max40080_csa_gain[] = {
[MAX40080_CFG_RANGE_50mV] = MAX40080_CSA_50mV_GAIN,
[MAX40080_CFG_RANGE_10mV] = MAX40080_CSA_10mV_GAIN,
};
struct max40080_state {
struct i2c_client *client;
/* Serializes read-modify-write access to the CFG register. */
struct mutex lock;
u32 shunt_resistor_uOhm;
/* Cached configuration: the selected RANGE index and oversampling ratio. */
unsigned int range;
int oversampling_ratio;
/*
* Precomputed current scale (mA per code) for each RANGE setting, as
* {integer, nano} pairs for IIO_VAL_INT_PLUS_NANO. The range is
* selected by writing the corresponding scale.
*/
int current_scale[2][2];
};
static const int max40080_oversampling_avail[] = { 1, 8, 16, 32, 64, 128 };
static int max40080_update_bits(struct max40080_state *st, u8 reg,
u16 mask, u16 val)
{
int tmp;
tmp = i2c_smbus_read_word_data(st->client, reg);
if (tmp < 0)
return tmp;
tmp = (tmp & ~mask) | (val & mask);
return i2c_smbus_write_word_data(st->client, reg, tmp);
}
/*
* In single-measurement mode the device sits idle until it receives an SMBus
* Quick Command, then performs exactly one current and one voltage conversion
* and returns to idle. Triggering on demand this way (rather than running the
* FIFO continuously in active mode) means each read returns a fresh, coherent
* current/voltage pair instead of the oldest queued FIFO entry.
*/
static int max40080_trigger_measurement(struct max40080_state *st)
{
return i2c_smbus_xfer(st->client->adapter, st->client->addr,
st->client->flags, I2C_SMBUS_WRITE, 0,
I2C_SMBUS_QUICK, NULL);
}
/*
* A single measurement holds the matched current/voltage pair in one 32-bit
* word (MAX40080_REG_IV). Reading all four bytes in one transaction returns
* both from the same conversion; reading the separate current (0x0C) and
* voltage (0x0E) registers would decorrelate the two channels.
*
* Unlike the word accesses used elsewhere, this is a plain I2C block read: the
* SMBus layer does not append or verify a PEC byte for it even when PEC is
* otherwise enabled for the device, so this transfer is not PEC protected.
*/
static int max40080_read_iv_once(struct max40080_state *st, u32 *iv)
{
__le32 buf = 0;
int ret;
ret = i2c_smbus_read_i2c_block_data(st->client, MAX40080_REG_IV,
sizeof(buf), (u8 *)&buf);
if (ret < 0)
return ret;
*iv = le32_to_cpu(buf);
return 0;
}
static int max40080_read_iv(struct max40080_state *st, u32 *iv)
{
u32 tmp = 0;
int ret, io_ret;
guard(mutex)(&st->lock);
ret = max40080_trigger_measurement(st);
if (ret < 0)
return ret;
/*
* Wait for the conversion to complete by polling the FIFO valid bit
* (or bail out on an I2C error). Polling the device's own status makes
* this independent of the actual conversion time, which varies with the
* oversampling ratio and the bus speed. The timeout is only a safety
* ceiling: the worst case is the maximum 128x averaging on both the
* current and voltage channels at the slowest 15 ksps base rate plus
* the inter-channel switching time, i.e. roughly 20 ms; 50 ms leaves
* ample margin.
*/
ret = read_poll_timeout(max40080_read_iv_once, io_ret,
io_ret || (tmp & MAX40080_IV_VALID_MSK),
500, 50 * USEC_PER_MSEC, false, st, &tmp);
if (io_ret)
return io_ret;
/*
* Propagate the last-read value even on timeout so the caller can
* inspect it for debugging.
*/
*iv = tmp;
return ret;
}
static int max40080_get_current(struct max40080_state *st, int *val)
{
u32 iv;
int ret;
ret = max40080_read_iv(st, &iv);
if (ret)
return ret;
*val = sign_extend32(FIELD_GET(MAX40080_IV_I_MSK, iv),
MAX40080_IV_I_SIGN_BIT);
return 0;
}
static int max40080_get_voltage(struct max40080_state *st, int *val)
{
u32 iv;
int ret;
ret = max40080_read_iv(st, &iv);
if (ret)
return ret;
*val = FIELD_GET(MAX40080_IV_V_MAG_MSK, iv);
return 0;
}
static int max40080_set_range(struct max40080_state *st, unsigned int range)
{
int ret;
ret = max40080_update_bits(st, MAX40080_REG_CFG, MAX40080_CFG_RANGE_MSK,
FIELD_PREP(MAX40080_CFG_RANGE_MSK, range));
if (ret)
return ret;
WRITE_ONCE(st->range, range);
return 0;
}
/*
* Precompute the current scale (mA per code) for each RANGE setting as
* {integer, nano} pairs. The shunt drop for a full-scale code is
* Vref[mV] / (BIT(ADC_RES_BITS) * gain)
* and current = Vshunt / Rshunt, so with Rshunt in micro-ohms the scale in
* mA/code is
* Vref[mV] * NANO * MICRO / (BIT(ADC_RES_BITS) * gain * Rshunt[uOhm])
* expressed as an integer part plus a nano fractional part.
*/
static void max40080_calc_current_scale(struct max40080_state *st)
{
u64 numerator, denominator;
u32 rem;
for (unsigned int i = 0; i < ARRAY_SIZE(max40080_csa_gain); i++) {
numerator = (u64)MAX40080_INTER_VREF_mV * NANO * MICRO;
denominator = BIT_ULL(MAX40080_ADC_RES_BITS) * max40080_csa_gain[i] *
st->shunt_resistor_uOhm;
numerator = div64_u64(numerator, denominator);
st->current_scale[i][0] = div_u64_rem(numerator, NANO, &rem);
st->current_scale[i][1] = rem;
}
}
/*
* max40080_oversampling_avail[] is ordered so that its index is the FILTER
* field value (index 0 = no averaging, index 1 = 8x, ...). Return that index
* for an exact match, or -EINVAL for a value that is not on the list.
*/
static int max40080_oversampling_to_filter(int val)
{
for (unsigned int i = 0; i < ARRAY_SIZE(max40080_oversampling_avail); i++) {
if (max40080_oversampling_avail[i] == val)
return i;
}
return -EINVAL;
}
static int max40080_set_oversampling_ratio(struct max40080_state *st, int val)
{
int filter;
int ret;
filter = max40080_oversampling_to_filter(val);
if (filter < 0)
return filter;
ret = max40080_update_bits(st, MAX40080_REG_CFG, MAX40080_CFG_FILTER_MSK,
FIELD_PREP(MAX40080_CFG_FILTER_MSK, filter));
if (ret)
return ret;
WRITE_ONCE(st->oversampling_ratio, val);
return 0;
}
static int max40080_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct max40080_state *st = iio_priv(indio_dev);
unsigned int range;
int ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (chan->type == IIO_CURRENT) {
ret = max40080_get_current(st, val);
if (ret)
return ret;
} else if (chan->type == IIO_VOLTAGE) {
ret = max40080_get_voltage(st, val);
if (ret)
return ret;
}
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
if (chan->type == IIO_CURRENT) {
/*
* The selectable current-sense range is exposed through
* scale: each RANGE setting has its own precomputed
* mA-per-code value. Userspace picks the range by
* writing the matching scale.
*
* Use READ_ONCE to ensure the compiler reads st->range
* exactly once, so val and val2 come from the same
* setting even if a concurrent write changes st->range.
*/
range = READ_ONCE(st->range);
*val = st->current_scale[range][0];
*val2 = st->current_scale[range][1];
return IIO_VAL_INT_PLUS_NANO;
}
/* voltage[mV] = raw * Vref[mV] * buffer_gain / BIT(ADC_RES_BITS) */
*val = MAX40080_INTER_VREF_mV * MAX40080_V_BUFF_GAIN;
*val2 = MAX40080_ADC_RES_BITS;
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
*val = READ_ONCE(st->oversampling_ratio);
return IIO_VAL_INT;
default:
return -EINVAL;
}
}
static int max40080_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct max40080_state *st = iio_priv(indio_dev);
guard(mutex)(&st->lock);
switch (mask) {
case IIO_CHAN_INFO_SCALE:
/* Only the current channel has a selectable range/scale. */
if (chan->type != IIO_CURRENT)
return -EINVAL;
for (unsigned int i = 0; i < ARRAY_SIZE(max40080_csa_gain); i++) {
if (val == st->current_scale[i][0] &&
val2 == st->current_scale[i][1])
return max40080_set_range(st, i);
}
return -EINVAL;
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
return max40080_set_oversampling_ratio(st, val);
default:
return -EINVAL;
}
}
static int max40080_write_raw_get_fmt(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
long mask)
{
switch (mask) {
case IIO_CHAN_INFO_SCALE:
return IIO_VAL_INT_PLUS_NANO;
default:
return IIO_VAL_INT;
}
}
static int max40080_read_avail(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
const int **vals, int *type, int *length,
long info)
{
struct max40080_state *st = iio_priv(indio_dev);
switch (info) {
case IIO_CHAN_INFO_SCALE:
if (chan->type != IIO_CURRENT)
return -EINVAL;
*vals = (int *)st->current_scale;
*length = ARRAY_SIZE(max40080_csa_gain) * 2;
*type = IIO_VAL_INT_PLUS_NANO;
return IIO_AVAIL_LIST;
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
*vals = max40080_oversampling_avail;
*length = ARRAY_SIZE(max40080_oversampling_avail);
*type = IIO_VAL_INT;
return IIO_AVAIL_LIST;
default:
return -EINVAL;
}
}
static int max40080_reg_access(struct iio_dev *indio_dev, unsigned int reg,
unsigned int write_val, unsigned int *read_val)
{
struct max40080_state *st = iio_priv(indio_dev);
int val;
if (read_val) {
val = i2c_smbus_read_word_data(st->client, reg);
if (val < 0)
return val;
*read_val = val;
return 0;
}
return i2c_smbus_write_word_data(st->client, reg, write_val);
}
static const struct iio_info max40080_info = {
.read_raw = max40080_read_raw,
.write_raw = max40080_write_raw,
.write_raw_get_fmt = max40080_write_raw_get_fmt,
.read_avail = max40080_read_avail,
.debugfs_reg_access = &max40080_reg_access,
};
static const struct iio_chan_spec max40080_channels[] = {
{
.type = IIO_CURRENT,
.indexed = 1,
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
.info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.info_mask_shared_by_all_available =
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
},
{
.type = IIO_VOLTAGE,
.indexed = 1,
.channel = 0,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
.info_mask_shared_by_all_available =
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
},
};
/*
* Configure the device from the cached state. The device powers up in standby
* with PEC enabled (CFG POR = 0x0060), so PEC is kept enabled throughout.
*/
static int max40080_init(struct max40080_state *st)
{
u16 fifo_cfg, cfg;
int ret, filter;
filter = max40080_oversampling_to_filter(st->oversampling_ratio);
if (filter < 0)
return filter;
/*
* Put the device in standby before (re)configuring the FIFO: the FIFO
* configuration register can only be written while the device is not
* converting.
*/
cfg = FIELD_PREP(MAX40080_CFG_MODE_MSK, MAX40080_CFG_MODE_STDBY) |
FIELD_PREP(MAX40080_CFG_PEC_EN_MSK, 1);
ret = i2c_smbus_write_word_data(st->client, MAX40080_REG_CFG, cfg);
if (ret)
return ret;
/* Store a matched current+voltage pair per conversion. */
fifo_cfg = FIELD_PREP(MAX40080_FIFO_CFG_STORE_IV_MSK, MAX40080_FIFO_CFG_STORE_IV);
ret = i2c_smbus_write_word_data(st->client, MAX40080_REG_FIFO_CFG,
fifo_cfg);
if (ret)
return ret;
/*
* Use single-measurement mode: the device stays idle and converts once
* per SMBus Quick Command (see max40080_trigger_measurement()), so each
* read returns a fresh sample rather than a queued FIFO entry.
*/
cfg = FIELD_PREP(MAX40080_CFG_MODE_MSK, MAX40080_CFG_MODE_SINGLE) |
FIELD_PREP(MAX40080_CFG_PEC_EN_MSK, 1) |
FIELD_PREP(MAX40080_CFG_RANGE_MSK, st->range) |
FIELD_PREP(MAX40080_CFG_FILTER_MSK, filter);
return i2c_smbus_write_word_data(st->client, MAX40080_REG_CFG, cfg);
}
static int max40080_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
const char *propname;
struct iio_dev *indio_dev;
struct max40080_state *st;
int ret;
/*
* The device powers up with PEC enabled (CFG POR = 0x0060) and rejects
* unprotected transactions, so PEC support is mandatory, along with
* word access, the I2C block read used for the current/voltage pair,
* and the Quick Command used to trigger a conversion.
*/
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_I2C_BLOCK |
I2C_FUNC_SMBUS_QUICK |
I2C_FUNC_SMBUS_PEC))
return -EOPNOTSUPP;
client->flags |= I2C_CLIENT_PEC;
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
st->client = client;
ret = devm_mutex_init(dev, &st->lock);
if (ret)
return ret;
propname = "shunt-resistor-micro-ohms";
ret = device_property_read_u32(dev, propname, &st->shunt_resistor_uOhm);
if (ret)
return dev_err_probe(dev, ret, "can't read %s\n", propname);
if (!st->shunt_resistor_uOhm)
return dev_err_probe(dev, -EINVAL, "%s must be non-zero\n", propname);
max40080_calc_current_scale(st);
/* Defaults: 50 mV range, no averaging. */
st->range = MAX40080_CFG_RANGE_50mV;
st->oversampling_ratio = 1;
indio_dev->name = "max40080";
indio_dev->info = &max40080_info;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->channels = max40080_channels;
indio_dev->num_channels = ARRAY_SIZE(max40080_channels);
ret = max40080_init(st);
if (ret)
return ret;
return devm_iio_device_register(dev, indio_dev);
}
static const struct i2c_device_id max40080_i2c_ids[] = {
{ .name = "max40080" },
{ }
};
MODULE_DEVICE_TABLE(i2c, max40080_i2c_ids);
static const struct of_device_id max40080_of_match[] = {
{ .compatible = "adi,max40080" },
{ }
};
MODULE_DEVICE_TABLE(of, max40080_of_match);
static struct i2c_driver max40080_driver = {
.driver = {
.name = "max40080",
.of_match_table = max40080_of_match,
},
.probe = max40080_probe,
.id_table = max40080_i2c_ids,
};
module_i2c_driver(max40080_driver);
MODULE_AUTHOR("Ciprian Hegbeli <ciprian.hegbeli@analog.com>");
MODULE_AUTHOR("Stefan Popa <stefan.popa@analog.com>");
MODULE_DESCRIPTION("Analog Devices MAX40080 current-sense amplifier driver");
MODULE_LICENSE("GPL");

View File

@ -721,6 +721,8 @@ static int mcp3911_probe(struct spi_device *spi)
adc = iio_priv(indio_dev);
adc->spi = spi;
adc->chip = spi_get_device_match_data(spi);
if (!adc->chip)
return -ENODATA;
ret = devm_regulator_get_enable_read_voltage(dev, "vref");
if (ret < 0 && ret != -ENODEV)

View File

@ -739,7 +739,7 @@ static int meson_sar_adc_clk_init(struct iio_dev *indio_dev,
{
struct meson_sar_adc_priv *priv = iio_priv(indio_dev);
struct device *dev = indio_dev->dev.parent;
struct clk_init_data init;
struct clk_init_data init = { };
const char *clk_parents[1];
init.name = devm_kasprintf(dev, GFP_KERNEL, "%s#adc_div", dev_name(dev));

Some files were not shown because too many files have changed in this diff Show More