mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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:
commit
2670329311
23
Documentation/ABI/testing/debugfs-iio-ad9910
Normal file
23
Documentation/ABI/testing/debugfs-iio-ad9910
Normal 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.
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
9
Documentation/ABI/testing/sysfs-bus-iio-adc
Normal file
9
Documentation/ABI/testing/sysfs-bus-iio-adc
Normal 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.
|
||||
31
Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9910
Normal file
31
Documentation/ABI/testing/sysfs-bus-iio-frequency-ad9910
Normal 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.
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -443,7 +443,7 @@ examples:
|
|||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
adc@0 {
|
||||
adc@0 {
|
||||
compatible = "adi,ad4111";
|
||||
reg = <0>;
|
||||
|
||||
|
|
|
|||
|
|
@ -238,9 +238,9 @@ examples:
|
|||
};
|
||||
|
||||
regulators {
|
||||
vcm_reg: vcm-output {
|
||||
regulator-name = "ad7768-1-vcm";
|
||||
};
|
||||
vcm_reg: vcm-output {
|
||||
regulator-name = "ad7768-1-vcm";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
270
Documentation/devicetree/bindings/iio/adc/adi,ad7768.yaml
Normal file
270
Documentation/devicetree/bindings/iio/adc/adi,ad7768.yaml
Normal 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;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
...
|
||||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
65
Documentation/devicetree/bindings/iio/adc/adi,max40080.yaml
Normal file
65
Documentation/devicetree/bindings/iio/adc/adi,max40080.yaml
Normal 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>;
|
||||
};
|
||||
};
|
||||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ properties:
|
|||
- const: mediatek,mt7986-auxadc
|
||||
- items:
|
||||
- enum:
|
||||
- mediatek,mt6572-auxadc
|
||||
- mediatek,mt6893-auxadc
|
||||
- mediatek,mt8183-auxadc
|
||||
- mediatek,mt8186-auxadc
|
||||
|
|
|
|||
|
|
@ -56,6 +56,6 @@ examples:
|
|||
clocks = <&ccu1 CLK_APB3_ADC0>;
|
||||
vref-supply = <®_vdda>;
|
||||
resets = <&rgu 40>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
149
Documentation/devicetree/bindings/iio/adc/ti,ads112c04.yaml
Normal file
149
Documentation/devicetree/bindings/iio/adc/ti,ads112c04.yaml
Normal 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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
@ -65,15 +65,15 @@ examples:
|
|||
#size-cells = <0>;
|
||||
|
||||
adc@1 {
|
||||
reg = <1>;
|
||||
compatible = "ti,ads1298";
|
||||
label = "ads1298-1-ecg";
|
||||
avdd-supply = <®_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 = <®_iso_5v_a>;
|
||||
clocks = <&clk_ads1298>;
|
||||
interrupt-parent = <&gpio0>;
|
||||
interrupts = <78 IRQ_TYPE_EDGE_FALLING>;
|
||||
spi-max-frequency = <20000000>;
|
||||
spi-cpha;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
254
Documentation/devicetree/bindings/iio/dac/adi,ad5529r.yaml
Normal file
254
Documentation/devicetree/bindings/iio/dac/adi,ad5529r.yaml
Normal 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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
145
Documentation/devicetree/bindings/iio/dac/adi,ad5710r.yaml
Normal file
145
Documentation/devicetree/bindings/iio/dac/adi,ad5710r.yaml
Normal 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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -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";
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
209
Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml
Normal file
209
Documentation/devicetree/bindings/iio/frequency/adi,ad9910.yaml
Normal 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";
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -45,6 +45,6 @@ examples:
|
|||
compatible = "amstaos,tsl2591";
|
||||
reg = <0x29>;
|
||||
interrupts = <20 IRQ_TYPE_EDGE_FALLING>;
|
||||
};
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ examples:
|
|||
#size-cells = <0>;
|
||||
|
||||
light@39 {
|
||||
compatible = "onnn,noa1305";
|
||||
reg = <0x39>;
|
||||
compatible = "onnn,noa1305";
|
||||
reg = <0x39>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ examples:
|
|||
#size-cells = <0>;
|
||||
|
||||
light-sensor@29 {
|
||||
compatible = "amstaos,tsl2581";
|
||||
reg = <0x29>;
|
||||
compatible = "amstaos,tsl2581";
|
||||
reg = <0x29>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
...
|
||||
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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: |
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
275
Documentation/iio/ad7768.rst
Normal file
275
Documentation/iio/ad7768.rst
Normal 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
|
||||
792
Documentation/iio/ad9910.rst
Normal file
792
Documentation/iio/ad9910.rst
Normal 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
|
||||
|
|
@ -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
|
||||
====================
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
====================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
====================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
====================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
====================
|
||||
|
|
|
|||
|
|
@ -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
|
||||
====================
|
||||
|
|
|
|||
|
|
@ -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. |
|
||||
+---------------------------------------------------+----------------------------------------------------------+
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ Industrial I/O Kernel Drivers
|
|||
ad7380
|
||||
ad7606
|
||||
ad7625
|
||||
ad7768
|
||||
ad7944
|
||||
ad9910
|
||||
ade9000
|
||||
adf41513
|
||||
adis16475
|
||||
|
|
|
|||
74
MAINTAINERS
74
MAINTAINERS
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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" },
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@
|
|||
*
|
||||
* TODO:
|
||||
* - Support for power management
|
||||
* - Support events and interrupts
|
||||
* - Create channel for step count
|
||||
* - Create channel for sensor time
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
1921
drivers/iio/adc/ad7768.c
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
277
drivers/iio/adc/axiado_saradc.c
Normal file
277
drivers/iio/adc/axiado_saradc.c
Normal 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, ®val);
|
||||
|
||||
/* 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");
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 = <c2497core_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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
574
drivers/iio/adc/max40080.c
Normal 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");
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue
Block a user