IIO: New device support, features and cleanup for the 7.2 cycle.

Like many areas of the kernel IIO has seen a lot of new contributors
 though in this case that is not all AI driven, but also reflects and annual
 surge of student contributions from usp.br. We also have several new
 regular reviewers who are helping with the surge (thanks to all our
 active reviewers!)
 
 Given there was a lot of cases of similar improvements applied to
 different drivers, I have grouped those into a special section (various
 drivers) to avoid mass duplication.
 
 New device support
 ------------------
 
 adi,ad4130
 - Add support for AD4129-4, AD4129-8, AD4130-4, AD4131-4 and AD4131-8
   after reworking the driver to be suitable for multiple device support.
 adi,ad4080
 - Support the AD4880 and AD4884 dual-channel parts. Interesting parts
   as have two separate data pipelines (including SPI buses interfaces),
   but the only current backend IP combines the two so they cannot be
   treated as independent devices.
 adi,ad5706r
 - New driver for this 4 channel current output DAC.
 adi,ad4691
 - New driver supporting this family of ADCs. Support for AD4691, AD4692,
   AD4693 and AD4694 which support either 8 or 16 channels with different
   max sampling rates. Feature rich driver including SPI offload support.
 adi,ltc2983
 - Add support for the ADT7604 in which the same sensor die as the
   LTC2984 is used for leak detection (liquid coverage of a sense area).
 allwinner,adc
 - Support for A523 SoCs. Similar to existing parts but with an additional
   clock.  Includes adding support for non contiguous channel lookup
   for in kernel use (fwnode_xlate callback).
 broadcomm,apds9999
 - New driver for the APDS9999 Ambient Light, RGB and proximity sensor.
 memsic,mmc5983
 - New driver for this 3-axis magnetometer.
 taos,tsl2772
 - Add support for the AVAGO APDS9900 and APDS9901 Ambient Light and
   Proximity sensors. which are very similar to existing part with slightly
   different integration time choices.  Includes removal of driver for these
   parts from drivers/misc.
 vishay,veml3328
 - New driver for this RGB+IR light sensor.
 
 Features
 --------
 
 IIO Core
 - Support for IEEE 754 floating point values in buffer scan elements.
 - Support quaternion axis representation (missing the scaler part)
 microchip,mcp4821
 - Add configurable gain control
 qcom,pm8xxx-xoadc
 - Add per channel labels.
 st,lsm6dsx
 - Support for rotation sensing on the LSM6DSV and LSM6DSV16X using
   both floating point and new quaterionaxis rotation modifier.
 
 MAINTAINERS update
 ------------------
 
 IIO top level entry
 - Include Documentation/driver-api/iio/
 adi,*
 - Top level ADI entry maintainer switch from Lars-Peter Clausen to Nuno Sá
   reflecting what has been the reality for some time. Thanks to Lars-Peter
   who was very active for many years, but has moved on to other things.
   Also add the linux@analog.com email list to ensure we don't get a gap
   in future.
 - Maintainer updates to reflect Cosmin Tanislav having moved on - thanks
   to Marcelo Schmitt for taking these over.
 sensiron,scd30
 - Replace maintainer (Tomasz Duszynski) with Maxwell Doose.
 
 Cleanups, minor fixes and hardening.
 ------------------------------------
 
 Documentation
 - Add missing powerdown modes to ABI docs.
 - Use modern helpers for buffer definition in the examples.
 core
 - Rework of the handling of timestamps so that the offset is cached at
   buffer resize time (during enabling) rather than based on assumption
   that relied in the timestamp being last and the largest element and
   so always 8 bytes before end of the scan. Underlying problem was
   triggered by scans with repeated type elements such as quaternions
   with each element more than 2 bytes - Giving a 16 byte+ aligned channel
   with result that a following timestamp may be 16 bytes from end of scan,
   rather than 8. Note that for the bosch,bno55 a compatibility hack means
   that it will duplicate the timestamp putting  a second copy at previously
   incorrect location.
 - Tidy up use of kernel types in buffer code to not use int64_t given all
   calls use s64.
 various drivers
 - Drop unused driver_data in device id tables - includes cleanup of various
   drivers that had only one choice where it can be hard coded elsewhere.
 - Move to named initializers for many i2c_device_id and platform_device_id
   tables (I have no idea how we go into habit of using named initializers
   for only a subset of the table types - e.g. of_device_id).
 - Make IIO_CHAN_SOFT_TIMESTAMP() macro a compound literal allowing simple
   use in various drivers that do dynamic channel definitions. Use it in
   all such cases.
 - Use dev_err_probe() and local dev variables to tidy up older drivers.
 - Switch more drivers to devm_mutex_init() to provide minor debug benefits.
 - Reorder code to put MODULE_DEVICE_TABLE() next to the tables.
 - Lots of use of cleanup.h magic to improve code flow, often including
   related refactors such as introducing helpers.
 - Replacement of usleep_range() with fsleep()
 - Reduce logging noise where functions either provide their own extensive
   reports on error, or where a clear error code is returned to userspace.
 - Minor spelling and style fixes (improving bracket usage, not using
   __packed etc)
 hid-sensors-*
 - Drop helpers for setting channel bit masks in favor of a compound
   literal at the call site.  Also general cleanup of surrounding code.
 hid-sensors-magn
 - Use u32 rather than bare unsigned for types.
 hid-sensors-rotation
 - Make sue of ext_scan_type handling for static case rather than duplicate
   chan_info structures.
 adi,ad3552r
 - Use field_get() to replace open coded equivalent.
 adi,ad4170
 - Switch from switch to table lookup for GPIO modes.
 adi,ad5686
 - Apply IWYU principal to included a consistent set of headers.
 - Deduplicate regmaps for AD5684 and AD5693 as identical.
 - Switch from an enum value in driver data and array look up to pointers
   to separate structures, improving readabilty and avoiding issues with
   0 value when using helpers to deal with different firmware types.
 - Add of_match_id table to SPI driver rather than relying on fallback to
   spi_device_id table.
 - Introduce some helpers for powerdown mask control.
 - Add helpers for control sync simplifying a couple of corner cases.
 - Docs fixes.
 - Add an ops structure to simplify future addition of operations beyond
   read and write.
 adi,ad7191
 - Switch to best practice of using device_property_present() to detect
   if an optional property is there rather than error values on querying
   the property.
 adi,ad7280a
 - Use local variables to improve readability of breaking up chan-address.
 adi,ad7825
 - Cleanup a type mismatch in clamp() call.
 adi,ad799x
 - Include improvements
 - Local dev variable to shorten code lines.
 - Cache regulator voltage at probe (these never change in practice)
 - Convert to devm for all unwind handling.
 adi,ad9832
 - Improve include relevance including replacing kernel.h with more specific
   headers.
 - Simplify some maths.
 adi,ad9834
 - Improve include relevance including replacing kernel.h with more specific
   headers.
 adi,adt7316
 - Add a comment to avoid future 'fixes' for error handling during the
   odd sequence used to flip from I2C mode to SPI mode.
 adi,adxl*
 - Documentation consistency improvements.
 asahi-kasei,ak8975
 - Fix missing runtime pm calls for buffered capture.
 - Fix missing pm_runtime_put_autosuspend() in an error path that would leave
   the device stuck on.
 - Close a potential uninitialized kernel stack leak.
 - Extensive driver modernization including: header relevance, fsleep()
   various minor bugs, dropping duplicate error messages and avoiding
   magic lengths for buffers.
 - Replace opencoded polling with iopoll().
 - Add error checking to gpio reads.
 avia,hx711
 - Move scale computation from global data to per device avoiding problems
   if multiple devices present.
 - General binding text cleanup.
 bosch,bmg160
 - Add missing mount-matrix entry to binding.
 bosch,bno55
 - Terminate error strings with newlines.
 devantech,srf08
 - Replace sprintf() with sysfs_emit() and sysfs_emit_at() to make intent
   clearer.
 freescale,mma8452
 - Add missing return value check.
 - Fix potential probe ordering issue by switching to non devm irq request.
 linear,ltc2309
 - Add chip specific read delays.
 - Improve chip_info structure, adding __counted_by_ptr marking and
   reorganizing to improve packing.
 linear,ltc2983
 - Fix a firmware combination where default n_wires of 2 bypasses exclusion
   of adi,current-rotate whereas explicitly setting it to 2 does not.
 - Fix potential race with completion reinit.
 - Improve error message wording consistency.
 - Use fwnode_property_present() to detect optional properties rather
   than fragile return value checking.
 microchip,mcp3422
 - Use of GENMASK(), FIELD_GET(), FIELD_PREP() to improve readability and
   generally modernize driver.
 microchip,mcp47feb02
 - Fix binding example to use a possible I2C address.
 - Fix binding bounds on channel number.
 - Standardize binding example indentation
 nxp,saradc
 - Increase chances of recovering from a failure in the interrupt handler
   by notifying the trigger that it can reenable even when the read failed.
 - Use field_get() to replace opencoded equivalent.
 qualcomm,*
 - Standardize on Qualcomm company naming in Kconfig.
 richtek,rtq6056
 - Add i2c_device_id table for legacy instantiation.
 samsung,ssp
 - Replace custom timestamp channel macro with main one.
 sciosense,ens210
 - Now scoped_guard() has been reworked, no need for a return
   that can never be reached.
 sensiron,scd30
 - Constify command lookup table.
 - Sanity check for NULL buffer of non zero size being provided to
   sc30_i2c_command()
 sensortek,stk3310
 - Include  more appropriate headers.
 - Ensure interrupt in appropriate mode after resume.
 - Structure definition improvements.
 - Use size_of() to replace opencoded sizes.
 siliconimage,si1133
 - Resolve counter related issues on timeout error paths.
 - Unused macro removal, improved macro definitions,.
 - Include relevance improvements.
 st,lsm6dsx
 - Fix an issue with applying invalid data check to wrong type of sample.
 taos,tcs3472
 - Try to powerdown chip on probe failure.
 - Devm usage and dropping of remove() callback.
 - Various other minor cleanup.
 taos,tsl2591
 - Dead code removal.
 - Simplify tsl2591_persist functions using a look up table.
 ti,ads1298
 - Fix wrong comment on timeout (and minor code improvement)
 - Drop unnecessary CONFIG2 write during init.
 ti,ads7950
 - Check ret rather that ret < 0 for spi_setup() call.
 - Use fully devm managed resources including moving to
   devm_regulator_get_enable_read_voltage() at probe time rather than
   querying evey time.
 - Using spi_optimize_message() to reduce CPU usage.
 ti,ads8688
 - User read_avail() callback rather than open coding handling of
   available attributes.
 ti,opt3001
 - Header relevance improvements
 - Use GENMASK for field definitions to improve readability.
 vishay,vcnl4000
 - Switch from enum in device_data to individual names structures
   impmroving code readabililty.
 - Move to devm handling for remainder of probe.
 vishay,veml6030
 - Drop pointless read of current Iteration Time index as it is not used.
 xilinx,ams
 - Fix potential out of bound channel lookup.
 - Replace some large switch statements with table lookups.
 yamaha,yas530
 - Put label in chip info structure to avoid look up in i2c_device_id table.
 
 Drop
 ----
 
 iio-trig-interrupt.
 - Not used for some time and no support for modern firmware bindings or
   in kernel users. So drop it.
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCgAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAmolp9kRHGppYzIzQGtl
 cm5lbC5vcmcACgkQVIU0mcT0FoieAxAArpdsc3rjgjeFxymnbXPWqjohz/XCg3Ps
 XXxbyaLCvphsJ7P7vsp7acX0vIdi+mqPLU+6Vl67OolFVKM3+84PMoHY3s0wbbMj
 xDgcI6zR4kwGUpGry9FKr3/UQaSNLo7ahYq7UZKJA8vCoHd11AUzh8TCz/myrdnK
 Ju6I+FScj6L8lkftaGgYqzHEOoKXQtXaUrYbUFQR/vm9/FlgEkF5qP4pcVxBfAox
 OtO9jjQOpOAZnTEEbjy6mmEVyuIzOAjLQFxPBzaUuWtZv51P5OZGOS0WNYvt4zvK
 ziaRPgTIShjUVGkQmhmZ3AjmrYmRjWMhyR58BAyYgqbN/OAwtaJEou8UCDeVQxst
 B3Tj10VrxuHCEmXvy7ex5SqsKBQ1BHuz3bS8u2znEFp7RcxIorXllRLckpdIFyIa
 LDyO6krus1mBhLVQ1LVhQNlpi6KKvVD3fcV/14fUoG/ZAP6ta3cdA7jybp1k4aNs
 PYdlTuJn9jLhRrjHEFaM9hT3St/MRSJ3/rFj4rEHufs3w7iATKWwR9YqcNG8VNFN
 rGz0aB72J1FxevP3/n5MfXkYUZTmw776Oy/IfB2swXMpH23L2+3b8+ZJUy2HJbBJ
 69sjgvEiFkhsJBI8eLe6pEWoD6wkq6KDamcYcgnUNPu8AaC45DLPuGHEPyjzk/AX
 vuc+ysTUb70=
 =AW+z
 -----END PGP SIGNATURE-----

Merge tag 'iio-for-7.2a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio into work-testing

IIO: New device support, features and cleanup for the 7.2 cycle.

Like many areas of the kernel IIO has seen a lot of new contributors
though in this case that is not all AI driven, but also reflects and annual
surge of student contributions from usp.br. We also have several new
regular reviewers who are helping with the surge (thanks to all our
active reviewers!)

Given there was a lot of cases of similar improvements applied to
different drivers, I have grouped those into a special section (various
drivers) to avoid mass duplication.

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

adi,ad4130
- Add support for AD4129-4, AD4129-8, AD4130-4, AD4131-4 and AD4131-8
  after reworking the driver to be suitable for multiple device support.
adi,ad4080
- Support the AD4880 and AD4884 dual-channel parts. Interesting parts
  as have two separate data pipelines (including SPI buses interfaces),
  but the only current backend IP combines the two so they cannot be
  treated as independent devices.
adi,ad5706r
- New driver for this 4 channel current output DAC.
adi,ad4691
- New driver supporting this family of ADCs. Support for AD4691, AD4692,
  AD4693 and AD4694 which support either 8 or 16 channels with different
  max sampling rates. Feature rich driver including SPI offload support.
adi,ltc2983
- Add support for the ADT7604 in which the same sensor die as the
  LTC2984 is used for leak detection (liquid coverage of a sense area).
allwinner,adc
- Support for A523 SoCs. Similar to existing parts but with an additional
  clock.  Includes adding support for non contiguous channel lookup
  for in kernel use (fwnode_xlate callback).
broadcomm,apds9999
- New driver for the APDS9999 Ambient Light, RGB and proximity sensor.
memsic,mmc5983
- New driver for this 3-axis magnetometer.
taos,tsl2772
- Add support for the AVAGO APDS9900 and APDS9901 Ambient Light and
  Proximity sensors. which are very similar to existing part with slightly
  different integration time choices.  Includes removal of driver for these
  parts from drivers/misc.
vishay,veml3328
- New driver for this RGB+IR light sensor.

Features
--------

IIO Core
- Support for IEEE 754 floating point values in buffer scan elements.
- Support quaternion axis representation (missing the scaler part)
microchip,mcp4821
- Add configurable gain control
qcom,pm8xxx-xoadc
- Add per channel labels.
st,lsm6dsx
- Support for rotation sensing on the LSM6DSV and LSM6DSV16X using
  both floating point and new quaterionaxis rotation modifier.

MAINTAINERS update
------------------

IIO top level entry
- Include Documentation/driver-api/iio/
adi,*
- Top level ADI entry maintainer switch from Lars-Peter Clausen to Nuno Sá
  reflecting what has been the reality for some time. Thanks to Lars-Peter
  who was very active for many years, but has moved on to other things.
  Also add the linux@analog.com email list to ensure we don't get a gap
  in future.
- Maintainer updates to reflect Cosmin Tanislav having moved on - thanks
  to Marcelo Schmitt for taking these over.
sensiron,scd30
- Replace maintainer (Tomasz Duszynski) with Maxwell Doose.

Cleanups, minor fixes and hardening.
------------------------------------

Documentation
- Add missing powerdown modes to ABI docs.
- Use modern helpers for buffer definition in the examples.
core
- Rework of the handling of timestamps so that the offset is cached at
  buffer resize time (during enabling) rather than based on assumption
  that relied in the timestamp being last and the largest element and
  so always 8 bytes before end of the scan. Underlying problem was
  triggered by scans with repeated type elements such as quaternions
  with each element more than 2 bytes - Giving a 16 byte+ aligned channel
  with result that a following timestamp may be 16 bytes from end of scan,
  rather than 8. Note that for the bosch,bno55 a compatibility hack means
  that it will duplicate the timestamp putting  a second copy at previously
  incorrect location.
- Tidy up use of kernel types in buffer code to not use int64_t given all
  calls use s64.
various drivers
- Drop unused driver_data in device id tables - includes cleanup of various
  drivers that had only one choice where it can be hard coded elsewhere.
- Move to named initializers for many i2c_device_id and platform_device_id
  tables (I have no idea how we go into habit of using named initializers
  for only a subset of the table types - e.g. of_device_id).
- Make IIO_CHAN_SOFT_TIMESTAMP() macro a compound literal allowing simple
  use in various drivers that do dynamic channel definitions. Use it in
  all such cases.
- Use dev_err_probe() and local dev variables to tidy up older drivers.
- Switch more drivers to devm_mutex_init() to provide minor debug benefits.
- Reorder code to put MODULE_DEVICE_TABLE() next to the tables.
- Lots of use of cleanup.h magic to improve code flow, often including
  related refactors such as introducing helpers.
- Replacement of usleep_range() with fsleep()
- Reduce logging noise where functions either provide their own extensive
  reports on error, or where a clear error code is returned to userspace.
- Minor spelling and style fixes (improving bracket usage, not using
  __packed etc)
hid-sensors-*
- Drop helpers for setting channel bit masks in favor of a compound
  literal at the call site.  Also general cleanup of surrounding code.
hid-sensors-magn
- Use u32 rather than bare unsigned for types.
hid-sensors-rotation
- Make sue of ext_scan_type handling for static case rather than duplicate
  chan_info structures.
adi,ad3552r
- Use field_get() to replace open coded equivalent.
adi,ad4170
- Switch from switch to table lookup for GPIO modes.
adi,ad5686
- Apply IWYU principal to included a consistent set of headers.
- Deduplicate regmaps for AD5684 and AD5693 as identical.
- Switch from an enum value in driver data and array look up to pointers
  to separate structures, improving readabilty and avoiding issues with
  0 value when using helpers to deal with different firmware types.
- Add of_match_id table to SPI driver rather than relying on fallback to
  spi_device_id table.
- Introduce some helpers for powerdown mask control.
- Add helpers for control sync simplifying a couple of corner cases.
- Docs fixes.
- Add an ops structure to simplify future addition of operations beyond
  read and write.
adi,ad7191
- Switch to best practice of using device_property_present() to detect
  if an optional property is there rather than error values on querying
  the property.
adi,ad7280a
- Use local variables to improve readability of breaking up chan-address.
adi,ad7825
- Cleanup a type mismatch in clamp() call.
adi,ad799x
- Include improvements
- Local dev variable to shorten code lines.
- Cache regulator voltage at probe (these never change in practice)
- Convert to devm for all unwind handling.
adi,ad9832
- Improve include relevance including replacing kernel.h with more specific
  headers.
- Simplify some maths.
adi,ad9834
- Improve include relevance including replacing kernel.h with more specific
  headers.
adi,adt7316
- Add a comment to avoid future 'fixes' for error handling during the
  odd sequence used to flip from I2C mode to SPI mode.
adi,adxl*
- Documentation consistency improvements.
asahi-kasei,ak8975
- Fix missing runtime pm calls for buffered capture.
- Fix missing pm_runtime_put_autosuspend() in an error path that would leave
  the device stuck on.
- Close a potential uninitialized kernel stack leak.
- Extensive driver modernization including: header relevance, fsleep()
  various minor bugs, dropping duplicate error messages and avoiding
  magic lengths for buffers.
- Replace opencoded polling with iopoll().
- Add error checking to gpio reads.
avia,hx711
- Move scale computation from global data to per device avoiding problems
  if multiple devices present.
- General binding text cleanup.
bosch,bmg160
- Add missing mount-matrix entry to binding.
bosch,bno55
- Terminate error strings with newlines.
devantech,srf08
- Replace sprintf() with sysfs_emit() and sysfs_emit_at() to make intent
  clearer.
freescale,mma8452
- Add missing return value check.
- Fix potential probe ordering issue by switching to non devm irq request.
linear,ltc2309
- Add chip specific read delays.
- Improve chip_info structure, adding __counted_by_ptr marking and
  reorganizing to improve packing.
linear,ltc2983
- Fix a firmware combination where default n_wires of 2 bypasses exclusion
  of adi,current-rotate whereas explicitly setting it to 2 does not.
- Fix potential race with completion reinit.
- Improve error message wording consistency.
- Use fwnode_property_present() to detect optional properties rather
  than fragile return value checking.
microchip,mcp3422
- Use of GENMASK(), FIELD_GET(), FIELD_PREP() to improve readability and
  generally modernize driver.
microchip,mcp47feb02
- Fix binding example to use a possible I2C address.
- Fix binding bounds on channel number.
- Standardize binding example indentation
nxp,saradc
- Increase chances of recovering from a failure in the interrupt handler
  by notifying the trigger that it can reenable even when the read failed.
- Use field_get() to replace opencoded equivalent.
qualcomm,*
- Standardize on Qualcomm company naming in Kconfig.
richtek,rtq6056
- Add i2c_device_id table for legacy instantiation.
samsung,ssp
- Replace custom timestamp channel macro with main one.
sciosense,ens210
- Now scoped_guard() has been reworked, no need for a return
  that can never be reached.
sensiron,scd30
- Constify command lookup table.
- Sanity check for NULL buffer of non zero size being provided to
  sc30_i2c_command()
sensortek,stk3310
- Include  more appropriate headers.
- Ensure interrupt in appropriate mode after resume.
- Structure definition improvements.
- Use size_of() to replace opencoded sizes.
siliconimage,si1133
- Resolve counter related issues on timeout error paths.
- Unused macro removal, improved macro definitions,.
- Include relevance improvements.
st,lsm6dsx
- Fix an issue with applying invalid data check to wrong type of sample.
taos,tcs3472
- Try to powerdown chip on probe failure.
- Devm usage and dropping of remove() callback.
- Various other minor cleanup.
taos,tsl2591
- Dead code removal.
- Simplify tsl2591_persist functions using a look up table.
ti,ads1298
- Fix wrong comment on timeout (and minor code improvement)
- Drop unnecessary CONFIG2 write during init.
ti,ads7950
- Check ret rather that ret < 0 for spi_setup() call.
- Use fully devm managed resources including moving to
  devm_regulator_get_enable_read_voltage() at probe time rather than
  querying evey time.
- Using spi_optimize_message() to reduce CPU usage.
ti,ads8688
- User read_avail() callback rather than open coding handling of
  available attributes.
ti,opt3001
- Header relevance improvements
- Use GENMASK for field definitions to improve readability.
vishay,vcnl4000
- Switch from enum in device_data to individual names structures
  impmroving code readabililty.
- Move to devm handling for remainder of probe.
vishay,veml6030
- Drop pointless read of current Iteration Time index as it is not used.
xilinx,ams
- Fix potential out of bound channel lookup.
- Replace some large switch statements with table lookups.
yamaha,yas530
- Put label in chip info structure to avoid look up in i2c_device_id table.

Drop
----

iio-trig-interrupt.
- Not used for some time and no support for modern firmware bindings or
  in kernel users. So drop it.

* tag 'iio-for-7.2a' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/jic23/iio: (266 commits)
  iio: adc: nxp-sar-adc: harden buffer ISR against per-channel read failure
  iio: chemical: scd30: Replace manual locking with RAII locking
  iio: light: tsl2591: remove unneeded tsl2591_compatible_als_persist_cycle()
  iio: dac: ad5686: create bus ops struct
  iio: dac: ad5686: cleanup doc header of local structs
  iio: dac: ad5686: add control_sync() for single-channel devices
  iio: dac: ad5686: add helpers to handle powerdown masks
  iio: dac: ad5686: add of_match table to the spi driver
  iio: dac: ad5686: drop enum id
  iio: dac: ad5686: remove redundant register definition
  iio: dac: ad5686: refactor include headers
  iio: adc: ad4080: fix AD4880 chip ID
  iio: light: veml3328: add support for new device
  dt-bindings: iio: light: veml6030: add veml3328
  docs: iio: adc: ad4691: add driver documentation
  iio: adc: ad4691: add oversampling support
  iio: adc: ad4691: add SPI offload support
  iio: adc: ad4691: add triggered buffer support
  iio: adc: ad4691: add initial driver for AD4691 family
  dt-bindings: iio: adc: add AD4691 family
  ...
This commit is contained in:
Greg Kroah-Hartman 2026-06-08 21:32:52 +02:00
commit 47b56cc367
369 changed files with 9344 additions and 5144 deletions

View File

@ -764,10 +764,13 @@ Contact: linux-iio@vger.kernel.org
Description:
Specifies the output powerdown mode.
DAC output stage is disconnected from the amplifier and
500ohm_to_gnd: connected to ground via a 500Ohm resistor,
1kohm_to_gnd: connected to ground via an 1kOhm resistor,
2.5kohm_to_gnd: connected to ground via a 2.5kOhm resistor,
3.85kohm_to_gnd: connected to ground via a 3.85kOhm resistor,
6kohm_to_gnd: connected to ground via a 6kOhm resistor,
7.7kohm_to_gnd: connected to ground via a 7.7kOhm 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,
42kohm_to_gnd: connected to ground via a 42kOhm resistor,
@ -1510,21 +1513,24 @@ Contact: linux-iio@vger.kernel.org
Description:
Description of the scan element data storage within the buffer
and hence the form in which it is read from user-space.
Form is [be|le]:[s|u]bits/storagebits[>>shift].
be or le specifies big or little endian. s or u specifies if
signed (2's complement) or unsigned. bits is the number of bits
of data and storagebits is the space (after padding) that it
occupies in the buffer. shift if specified, is the shift that
needs to be applied prior to masking out unused bits. Some
devices put their data in the middle of the transferred elements
with additional information on both sides. Note that some
devices will have additional information in the unused bits
so to get a clean value, the bits value must be used to mask
the buffer output value appropriately. The storagebits value
also specifies the data alignment. So s48/64>>2 will be a
signed 48 bit integer stored in a 64 bit location aligned to
a 64 bit boundary. To obtain the clean value, shift right 2
and apply a mask to zero the top 16 bits of the result.
Form is [be|le]:[f|s|u]bits/storagebits[>>shift].
be or le specifies big or little endian. f means floating-point
(IEEE 754 binary format), s means signed (2's complement), u means
unsigned. bits is the number of bits of data and storagebits is the
space (after padding) that it occupies in the buffer; when using a
floating-point format, bits must be one of the width values defined
in the IEEE 754 standard for binary interchange formats (e.g. 16
indicates the binary16 format for half-precision numbers). shift,
if specified, is the shift that needs to be applied prior to
masking out unused bits. Some devices put their data in the middle
of the transferred elements with additional information on both
sides. Note that some devices will have additional information in
the unused bits, so to get a clean value the bits value must be
used to mask the buffer output value appropriately. The storagebits
value also specifies the data alignment. So s48/64>>2 will be a
signed 48 bit integer stored in a 64 bit location aligned to a 64
bit boundary. To obtain the clean value, shift right 2 and apply a
mask to zero the top 16 bits of the result.
For other storage combinations this attribute will be extended
appropriately.
@ -1752,6 +1758,21 @@ Description:
measurement from channel Y. Units after application of scale and
offset are milliamps.
What: /sys/bus/iio/devices/iio:deviceX/in_rot_quaternionaxis_raw
KernelVersion: 7.1
Contact: linux-iio@vger.kernel.org
Description:
Raw value of {x, y, z} components of the quaternion vector. These
components represent the axis about which a rotation occurs, and are
subject to the following constraints:
- the quaternion vector is normalized, i.e. w^2 + x^2 + y^2 + z^2 = 1
- the rotation angle is within the [-pi, pi] range, i.e. the w
component (which represents the amount of rotation) is non-negative
These constraints allow the w value to be calculated from the other
components: w = sqrt(1 - (x^2 + y^2 + z^2)).
What: /sys/.../iio:deviceX/in_energy_en
What: /sys/.../iio:deviceX/in_distance_en
What: /sys/.../iio:deviceX/in_velocity_sqrt(x^2+y^2+z^2)_en
@ -1959,6 +1980,23 @@ Description:
Raw (unscaled no offset etc.) resistance reading.
Units after application of scale and offset are ohms.
What: /sys/bus/iio/devices/iio:deviceX/in_coverageY_raw
KernelVersion: 7.2
Contact: linux-iio@vger.kernel.org
Description:
Raw (unscaled no offset etc.) coverage reading. Used for sensors
that report fractional coverage as a percentage, such as leak
detectors where the value represents what portion of the sensing
element is wetted. Units after application of scale and offset are
percent.
What: /sys/bus/iio/devices/iio:deviceX/in_coverageY_scale
KernelVersion: 7.2
Contact: linux-iio@vger.kernel.org
Description:
Scale to be applied to in_coverageY_raw to obtain coverage
in percent.
What: /sys/bus/iio/devices/iio:deviceX/heater_enable
KernelVersion: 4.1.0
Contact: linux-iio@vger.kernel.org

View File

@ -18,7 +18,11 @@ description: |
service a wide variety of precision, wide bandwidth data acquisition
applications.
The AD4880 is a dual-channel variant with two independent ADC channels,
each with its own SPI configuration interface.
https://www.analog.com/media/en/technical-documentation/data-sheets/ad4080.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/ad4880.pdf
$ref: /schemas/spi/spi-peripheral-props.yaml#
@ -34,9 +38,16 @@ properties:
- adi,ad4086
- adi,ad4087
- adi,ad4088
- adi,ad4880
- adi,ad4884
reg:
maxItems: 1
minItems: 1
maxItems: 2
description:
SPI chip select(s). For single-channel devices, one chip select.
For multi-channel devices like AD4880, two chip selects are required
as each channel has its own SPI configuration interface.
spi-max-frequency:
description: Configuration of the SPI bus.
@ -60,7 +71,10 @@ properties:
vrefin-supply: true
io-backends:
maxItems: 1
minItems: 1
items:
- description: Backend for channel A (primary)
- description: Backend for channel B (secondary)
adi,lvds-cnv-enable:
description: Enable the LVDS signal type on the CNV pin. Default is CMOS.
@ -81,6 +95,27 @@ required:
- vdd33-supply
- vrefin-supply
allOf:
- if:
properties:
compatible:
contains:
enum:
- adi,ad4880
- adi,ad4884
then:
properties:
reg:
minItems: 2
io-backends:
minItems: 2
else:
properties:
reg:
maxItems: 1
io-backends:
maxItems: 1
additionalProperties: false
examples:
@ -101,4 +136,21 @@ examples:
io-backends = <&iio_backend>;
};
};
- |
spi {
#address-cells = <1>;
#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>;
};
};
...

View File

@ -5,19 +5,30 @@
$id: http://devicetree.org/schemas/iio/adc/adi,ad4130.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD4130 ADC device driver
title: Analog Devices AD4130 family ADCs
maintainers:
- Cosmin Tanislav <cosmin.tanislav@analog.com>
description: |
Bindings for the Analog Devices AD4130 ADC. Datasheet can be found here:
Bindings for the Analog Devices AD4130 family ADCs.
Datasheets can be found here:
https://www.analog.com/media/en/technical-documentation/data-sheets/AD4129-4.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/AD4129-8.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/AD4130-4.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/AD4130-8.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/AD4131-4.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/AD4131-8.pdf
properties:
compatible:
enum:
- adi,ad4129-4
- adi,ad4129-8
- adi,ad4130-4
- adi,ad4130
- adi,ad4131-4
- adi,ad4131-8
reg:
maxItems: 1
@ -32,6 +43,10 @@ properties:
interrupts:
maxItems: 1
description: |
Data Ready / FIFO interrupt. For devices with FIFO support, the
interrupt polarity specified here is inverted when the device enters
FIFO mode, and normal for data ready.
interrupt-names:
description: |

View File

@ -0,0 +1,180 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/adc/adi,ad4691.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD4691 Family Multichannel SAR ADCs
maintainers:
- Radu Sabau <radu.sabau@analog.com>
description: |
The AD4691 family are high-speed, low-power, multichannel successive
approximation register (SAR) analog-to-digital converters (ADCs) with
an SPI-compatible serial interface. The ADC supports CNV Burst Mode,
where an external PWM drives the CNV pin, and Manual Mode, where CNV
is directly tied to the SPI chip-select.
Datasheets:
* https://www.analog.com/en/products/ad4691.html
* https://www.analog.com/en/products/ad4692.html
* https://www.analog.com/en/products/ad4693.html
* https://www.analog.com/en/products/ad4694.html
$ref: /schemas/spi/spi-peripheral-props.yaml#
properties:
compatible:
enum:
- adi,ad4691
- adi,ad4692
- adi,ad4693
- adi,ad4694
reg:
maxItems: 1
spi-max-frequency:
maximum: 40000000
spi-cpol: true
spi-cpha: true
avdd-supply:
description: Analog power supply (4.5V to 5.5V).
vdd-supply:
description:
External 1.8V digital core supply. When present, the internal LDO is
disabled (LDO_EN = 0). Mutually exclusive with ldo-in-supply.
ldo-in-supply:
description:
LDO input supply (2.4V to 5.5V). When present and vdd-supply is absent,
the internal LDO generates 1.8V VDD from this input (LDO_EN = 1).
Mutually exclusive with vdd-supply.
vio-supply:
description: I/O voltage supply (1.71V to 1.89V or VDD).
ref-supply:
description: External reference voltage supply (2.4V to 5.25V).
refin-supply:
description: Internal reference buffer input supply.
reset-gpios:
description:
GPIO line controlling the hardware reset pin (active-low).
maxItems: 1
pwms:
description:
PWM connected to the CNV pin. When present, selects CNV Burst Mode where
the PWM drives the conversion rate. When absent, Manual Mode is used
(CNV tied to SPI CS).
maxItems: 1
interrupts:
description:
Interrupt lines connected to the ADC GP pins. Each GP pin can be
physically wired to an interrupt-capable input on the SoC.
maxItems: 4
interrupt-names:
description: Names of the interrupt lines, matching the GP pin names.
minItems: 1
maxItems: 4
items:
enum:
- gp0
- gp1
- gp2
- gp3
gpio-controller: true
'#gpio-cells':
const: 2
'#trigger-source-cells':
description:
This node can act as a trigger source. The single cell in a consumer
reference specifies the GP pin number (0-3) used as the trigger output.
const: 1
required:
- compatible
- reg
- avdd-supply
- vio-supply
allOf:
# vdd-supply and ldo-in-supply are mutually exclusive, one is required:
# either an external 1.8V VDD is provided or the internal LDO is fed from
# ldo-in-supply to generate VDD.
- oneOf:
- required:
- vdd-supply
- required:
- ldo-in-supply
# ref-supply and refin-supply are mutually exclusive, one is required
- oneOf:
- required:
- ref-supply
- required:
- refin-supply
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/gpio/gpio.h>
/* AD4692 in CNV Burst Mode with SPI offload */
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ad4692";
reg = <0>;
spi-cpol;
spi-cpha;
spi-max-frequency = <40000000>;
avdd-supply = <&avdd_supply>;
ldo-in-supply = <&avdd_supply>;
vio-supply = <&vio_supply>;
ref-supply = <&ref_5v>;
reset-gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
pwms = <&pwm_gen 0 0>;
#trigger-source-cells = <1>;
};
};
- |
#include <dt-bindings/gpio/gpio.h>
/* AD4692 in Manual Mode (CNV tied to SPI CS) */
spi {
#address-cells = <1>;
#size-cells = <0>;
adc@0 {
compatible = "adi,ad4692";
reg = <0>;
spi-cpol;
spi-cpha;
spi-max-frequency = <31250000>;
avdd-supply = <&avdd_supply>;
ldo-in-supply = <&avdd_supply>;
vio-supply = <&vio_supply>;
refin-supply = <&refin_supply>;
reset-gpios = <&gpio0 15 GPIO_ACTIVE_LOW>;
};
};

View File

@ -14,6 +14,7 @@ properties:
oneOf:
- enum:
- allwinner,sun20i-d1-gpadc
- allwinner,sun55i-a523-gpadc
- items:
- enum:
- allwinner,sun50i-h616-gpadc
@ -29,7 +30,12 @@ properties:
const: 0
clocks:
maxItems: 1
minItems: 1
maxItems: 2
clock-names:
minItems: 1
maxItems: 2
interrupts:
maxItems: 1
@ -40,6 +46,30 @@ properties:
resets:
maxItems: 1
allOf:
- if:
properties:
compatible:
enum:
- allwinner,sun55i-a523-gpadc
then:
properties:
clocks:
items:
- description: Bus clock
- description: Module clock
clock-names:
items:
- const: bus
- const: mod
required:
- clock-names
else:
properties:
clocks:
maxItems: 1
clock-names: false
patternProperties:
"^channel@[0-9a-f]+$":
$ref: adc.yaml

View File

@ -10,14 +10,9 @@ maintainers:
- Andreas Klinger <ak@it-klinger.de>
description: |
Bit-banging driver using two GPIOs:
- sck-gpio gives a clock to the sensor with 24 cycles for data retrieval
and up to 3 cycles for selection of the input channel and gain for the
next measurement
- dout-gpio is the sensor data the sensor responds to the clock
Specifications about the driver can be found at:
http://www.aviaic.com/ENProducts.aspx
The HX711 is a 24-bit ADC with selectable gain (32/64/128) and two
differential input channels. Channel A supports gain 64 and 128;
channel B supports gain 32.
properties:
compatible:
@ -26,23 +21,23 @@ properties:
sck-gpios:
description:
Definition of the GPIO for the clock (output). In the datasheet it is
named PD_SCK
GPIO for the clock output (PD_SCK in the datasheet).
maxItems: 1
dout-gpios:
description:
Definition of the GPIO for the data-out sent by the sensor in
response to the clock (input).
See Documentation/devicetree/bindings/gpio/gpio.txt for information
on how to specify a consumer gpio.
GPIO for the data output from the sensor (DOUT in the datasheet).
maxItems: 1
avdd-supply:
description:
Definition of the regulator used as analog supply
Analog supply voltage (AVDD).
clock-frequency:
description:
Controls the SCK bit-bang timing. The value is used to derive the
delay between SCK edges; keep the SCK high time below 60 us to
avoid triggering chip power-down mode.
minimum: 20000
maximum: 2500000
default: 400000

View File

@ -78,6 +78,10 @@ patternProperties:
reg:
maxItems: 1
label:
description: |
Unique name to identify which channel this is.
qcom,decimation:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
@ -130,36 +134,47 @@ examples:
vcoin: adc-channel@0 {
reg = <0x00 0x00>;
label = "vcoin";
};
vbat: adc-channel@1 {
reg = <0x00 0x01>;
label = "vbat";
};
dcin: adc-channel@2 {
reg = <0x00 0x02>;
label = "dcin";
};
ichg: adc-channel@3 {
reg = <0x00 0x03>;
label = "ichg";
};
vph_pwr: adc-channel@4 {
reg = <0x00 0x04>;
label = "vph_pwr";
};
usb_vbus: adc-channel@a {
reg = <0x00 0x0a>;
label = "usb_vbus";
};
die_temp: adc-channel@b {
reg = <0x00 0x0b>;
label = "die_temp";
};
ref_625mv: adc-channel@c {
reg = <0x00 0x0c>;
label = "ref_625mv";
};
ref_1250mv: adc-channel@d {
reg = <0x00 0x0d>;
label = "ref_1250mv";
};
ref_325mv: adc-channel@e {
reg = <0x00 0x0e>;
label = "ref_325mv";
};
ref_muxoff: adc-channel@f {
reg = <0x00 0x0f>;
label = "ref_muxoff";
};
};
};

View File

@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Sensirion SCD30 carbon dioxide sensor
maintainers:
- Tomasz Duszynski <tomasz.duszynski@octakon.com>
- Maxwell Doose <m32285159@gmail.com>
description: |
Air quality sensor capable of measuring co2 concentration, temperature

View File

@ -0,0 +1,105 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/dac/adi,ad5706r.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices AD5706R 4-Channel Current Output DAC
maintainers:
- Alexis Czezar Torreno <alexisczezar.torreno@analog.com>
description: |
The AD5706R is a 4-channel, 16-bit resolution, current output
digital-to-analog converter (DAC) with programmable output current
ranges (50mA, 150mA, 200mA, 300mA), an integrated 2.5V voltage
reference, and load DAC, A/B toggle, and dither functions.
Datasheet:
https://www.analog.com/en/products/ad5706r.html
properties:
compatible:
enum:
- adi,ad5706r
reg:
maxItems: 1
avdd-supply:
description: Analog power supply (2.9V to 3.6V).
iovdd-supply:
description: Logic power supply (1.14V to 1.89V).
pvdd0-supply:
description: Power supply for IDAC0 channel (1.65V to AVDD).
pvdd1-supply:
description: Power supply for IDAC1 channel (1.65V to AVDD).
pvdd2-supply:
description: Power supply for IDAC2 channel (1.65V to AVDD).
pvdd3-supply:
description: Power supply for IDAC3 channel (1.65V to AVDD).
vref-supply:
description:
Optional external 2.5V voltage reference. If not provided, the
internal 2.5V reference is used.
pwms:
maxItems: 1
description:
Optional PWM connected to the LDAC/TGP/DCK pin for hardware
triggered DAC updates, toggle, or dither clock generation.
reset-gpios:
maxItems: 1
description:
GPIO connected to the active low RESET pin. If not provided,
software reset is used.
enable-gpios:
maxItems: 1
description:
GPIO connected to the active low OUT_EN pin. Controls whether
the current outputs are enabled or in high-Z/ground state.
required:
- compatible
- reg
- avdd-supply
- iovdd-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>;
dac@0 {
compatible = "adi,ad5706r";
reg = <0>;
avdd-supply = <&avdd>;
iovdd-supply = <&iovdd>;
pvdd0-supply = <&pvdd>;
pvdd1-supply = <&pvdd>;
pvdd2-supply = <&pvdd>;
pvdd3-supply = <&pvdd>;
vref-supply = <&vref>;
spi-max-frequency = <50000000>;
pwms = <&pwm0 0 1000000 0>;
reset-gpios = <&gpio0 10 GPIO_ACTIVE_LOW>;
enable-gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
};
};
...

View File

@ -161,8 +161,8 @@ patternProperties:
properties:
reg:
description: The channel number.
minItems: 1
maxItems: 8
minimum: 0
maximum: 7
label:
description: Unique name to identify which channel this is.
@ -280,23 +280,23 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
dac@0 {
compatible = "microchip,mcp47feb02";
reg = <0>;
vdd-supply = <&vdac_vdd>;
vref-supply = <&vref_reg>;
dac@60 {
compatible = "microchip,mcp47feb02";
reg = <0x60>;
vdd-supply = <&vdac_vdd>;
vref-supply = <&vref_reg>;
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
label = "Adjustable_voltage_ch0";
};
#address-cells = <1>;
#size-cells = <0>;
channel@0 {
reg = <0>;
label = "Adjustable_voltage_ch0";
};
channel@1 {
reg = <0x1>;
label = "Adjustable_voltage_ch1";
};
};
channel@1 {
reg = <0x1>;
label = "Adjustable_voltage_ch1";
};
};
};
...

View File

@ -26,6 +26,9 @@ properties:
vdd-supply: true
vddio-supply: true
mount-matrix:
description: an optional 3x3 mounting rotation matrix.
spi-max-frequency:
maximum: 10000000
@ -56,6 +59,9 @@ examples:
reg = <0x69>;
interrupt-parent = <&gpio6>;
interrupts = <18 IRQ_TYPE_EDGE_RISING>;
mount-matrix = "0", "1", "0",
"1", "0", "0",
"0", "0", "1";
};
};
...

View File

@ -0,0 +1,54 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/light/brcm,apds9999.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Broadcom APDS-9999 Digital Proximity and RGB Sensor
maintainers:
- Jose A. Perez de Azpillaga <azpijr@gmail.com>
description: |
Broadcom APDS-9999 is a digital proximity and RGB sensor with
ambient light sensing (ALS) capability. The device uses individual
R, G, B, and IR channels plus a Vertical Cavity Surface Emitting
Laser (VCSEL) for proximity detection.
Datasheet: https://docs.broadcom.com/docs/APDS-9999-DS
properties:
compatible:
enum:
- brcm,apds9999
reg:
maxItems: 1
vdd-supply: true
vcsel-supply:
description: VCSEL power supply (VVCSEL pin)
interrupts:
maxItems: 1
additionalProperties: false
required:
- compatible
- reg
- vdd-supply
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
light-sensor@52 {
compatible = "brcm,apds9999";
reg = <0x52>;
vdd-supply = <&vdd_reg>;
vcsel-supply = <&vcsel_reg>;
};
};

View File

@ -26,6 +26,8 @@ properties:
- amstaos,tmd2672
- amstaos,tsl2772
- amstaos,tmd2772
- avago,apds9900
- avago,apds9901
- avago,apds9930
reg:

View File

@ -4,7 +4,7 @@
$id: http://devicetree.org/schemas/iio/light/vishay,veml6030.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: VEML3235, VEML6030, VEML6035 and VEML7700 Ambient Light Sensors (ALS)
title: VEML3235, VEML3328, VEML6030, VEML6035 and VEML7700 Ambient Light Sensors (ALS)
maintainers:
- Rishi Gupta <gupt21@gmail.com>
@ -21,6 +21,7 @@ description: |
Specifications about the sensors can be found at:
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/84889/veml6035.pdf
https://www.vishay.com/docs/84286/veml7700.pdf
@ -29,6 +30,7 @@ properties:
compatible:
enum:
- vishay,veml3235
- vishay,veml3328
- vishay,veml6030
- vishay,veml6035
- vishay,veml7700
@ -79,6 +81,7 @@ allOf:
compatible:
enum:
- vishay,veml3235
- vishay,veml3328
- vishay,veml7700
then:
properties:

View File

@ -0,0 +1,63 @@
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/iio/magnetometer/memsic,mmc5983.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MEMSIC MMC5983MA 3-axis magnetic sensor
maintainers:
- Vladislav Kulikov <vlad.kulikov.c@gmail.com>
properties:
compatible:
const: memsic,mmc5983
reg:
maxItems: 1
interrupts:
maxItems: 1
vdd-supply:
description: Regulator that provides power to the sensor
vddio-supply:
description: Regulator that provides power to the digital interface and INT pin
required:
- compatible
- reg
- vdd-supply
allOf:
- $ref: /schemas/spi/spi-peripheral-props.yaml#
unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
magnetometer@30 {
compatible = "memsic,mmc5983";
reg = <0x30>;
vdd-supply = <&vdd_3v3_reg>;
vddio-supply = <&vdd_3v3_reg>;
};
};
- |
spi {
#address-cells = <1>;
#size-cells = <0>;
magnetometer@0 {
compatible = "memsic,mmc5983";
reg = <0>;
spi-max-frequency = <10000000>;
vdd-supply = <&vdd_3v3_reg>;
vddio-supply = <&vdd_3v3_reg>;
};
};

View File

@ -4,14 +4,18 @@
$id: http://devicetree.org/schemas/iio/temperature/adi,ltc2983.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Analog Devices LTC2983, LTC2986, LTM2985 Multi-sensor Temperature system
title: Analog Devices LTC2983 and similar Multi-sensor Temperature systems
maintainers:
- Nuno Sá <nuno.sa@analog.com>
description: |
Analog Devices LTC2983, LTC2984, LTC2986, LTM2985 Multi-Sensor Digital
Temperature Measurement Systems
Analog Devices Multi-Sensor Digital Temperature Measurement Systems:
- ADT7604
- LTC2983
- LTC2984
- LTC2986
- LTM2985
https://www.analog.com/media/en/technical-documentation/data-sheets/2983fc.pdf
https://www.analog.com/media/en/technical-documentation/data-sheets/2984fb.pdf
@ -43,6 +47,7 @@ properties:
compatible:
oneOf:
- enum:
- adi,adt7604
- adi,ltc2983
- adi,ltc2986
- adi,ltm2985
@ -436,6 +441,121 @@ patternProperties:
required:
- adi,custom-temp
'^copper-trace@':
$ref: '#/$defs/sensor-node'
unevaluatedProperties: false
description: |
Copper trace resistance sensor (some parts only). Two variants exist:
sub-ohm (< 1 ohm, no custom table allowed) and standard (> 1 ohm,
required custom table).
properties:
reg:
minimum: 2
maximum: 20
adi,sensor-type:
description: Sensor type for copper trace sensors.
$ref: /schemas/types.yaml#/definitions/uint32
const: 32
adi,rsense-handle:
description: Associated sense resistor sensor.
$ref: /schemas/types.yaml#/definitions/phandle
adi,copper-trace-sub-ohm:
description:
Select the sub-ohm (< 1 ohm) copper trace variant. Custom table
and excitation current are not allowed in this mode.
type: boolean
adi,excitation-current-microamp:
description:
Excitation current applied to the copper trace. Not used in
sub-ohm mode. The datasheet recommends 1mA for copper trace
sensors due to their typically small resistance.
enum: [5, 10, 25, 50, 100, 250, 500, 1000]
default: 1000
adi,custom-copper-trace:
description:
Resistance-to-temperature table for copper trace sensors with
resistance > 1 ohm. Required when adi,copper-trace-sub-ohm is not
set. See Page 36 of the datasheet.
$ref: /schemas/types.yaml#/definitions/uint64-matrix
minItems: 3
maxItems: 64
items:
items:
- description: Resistance point in uOhms.
- description: Temperature point in uK.
required:
- adi,rsense-handle
allOf:
- if:
required:
- adi,copper-trace-sub-ohm
then:
properties:
adi,custom-copper-trace: false
adi,excitation-current-microamp: false
- if:
not:
required:
- adi,copper-trace-sub-ohm
then:
required:
- adi,custom-copper-trace
'^leak-detector@':
$ref: '#/$defs/sensor-node'
unevaluatedProperties: false
description: |
Leak detector sensor (some parts only). Outputs resistance in ohms and
a coverage percentage via IIO_COVERAGE (raw/1024 = coverage %).
properties:
reg:
minimum: 2
maximum: 20
adi,sensor-type:
description: Sensor type for leak detector sensors.
$ref: /schemas/types.yaml#/definitions/uint32
const: 33
adi,rsense-handle:
description: Associated sense resistor sensor.
$ref: /schemas/types.yaml#/definitions/phandle
adi,excitation-current-nanoamp:
description:
Excitation current applied to the leak detector. The correct value
depends on the electrical characteristics of the liquid being sensed.
For example, 10000 (10µA) is recommended for PG25 (see datasheet
Table 39).
enum: [250, 500, 1000, 5000, 10000, 25000, 50000, 100000, 250000,
500000, 1000000]
adi,custom-leak-detector:
description: |
Lookup table mapping resistance to coverage percentage. Entries must
be in ascending resistance order.
$ref: /schemas/types.yaml#/definitions/uint64-matrix
minItems: 3
maxItems: 64
items:
items:
- description: Resistance point in uOhms.
- description: Coverage data percentage (0 to 100).
required:
- adi,rsense-handle
- adi,excitation-current-nanoamp
- adi,custom-leak-detector
'^rsense@':
$ref: '#/$defs/sensor-node'
unevaluatedProperties: false
@ -477,6 +597,32 @@ allOf:
patternProperties:
'^temp@': false
- if:
properties:
compatible:
contains:
const: adi,adt7604
then:
patternProperties:
'^thermocouple@': false
'^diode@': false
'^adc@': false
'^temp@': false
'^rtd@':
properties:
adi,sensor-type:
not:
const: 18
'^thermistor@':
properties:
adi,sensor-type:
not:
const: 27
else:
patternProperties:
'^copper-trace@': false
'^leak-detector@': false
examples:
- |
#include <dt-bindings/interrupt-controller/irq.h>
@ -556,4 +702,69 @@ examples:
};
};
};
- |
#include <dt-bindings/interrupt-controller/irq.h>
spi {
#address-cells = <1>;
#size-cells = <0>;
temperature-sensor@0 {
compatible = "adi,adt7604";
reg = <0>;
interrupt-parent = <&gpio>;
interrupts = <25 IRQ_TYPE_EDGE_RISING>;
#address-cells = <1>;
#size-cells = <0>;
vdd-supply = <&supply>;
trace_rsense: rsense@2 {
reg = <2>;
adi,sensor-type = <29>;
adi,rsense-val-milli-ohms = <100000>; // 100 ohm
};
copper-trace@4 {
reg = <4>;
adi,sensor-type = <32>;
adi,rsense-handle = <&trace_rsense>;
adi,copper-trace-sub-ohm;
};
r_sense: rsense@12 {
reg = <12>;
adi,sensor-type = <29>;
adi,rsense-val-milli-ohms = <1000000>; // 1 kohm
};
leak-detector@14 {
reg = <14>;
adi,sensor-type = <33>;
adi,rsense-handle = <&r_sense>;
adi,excitation-current-nanoamp = <10000>;
adi,custom-leak-detector =
/bits/ 64 < 0 100>,
/bits/ 64 < 202020000 99>,
/bits/ 64 < 285710000 70>,
/bits/ 64 < 333330000 60>,
/bits/ 64 < 400000000 50>,
/bits/ 64 < 500000000 40>,
/bits/ 64 < 666670000 30>,
/bits/ 64 < 1000000000 20>,
/bits/ 64 < 2000000000 10>,
/bits/ 64 <1000000000000 0>;
};
rtd@18 {
reg = <18>;
adi,sensor-type = <12>; // PT100
adi,rsense-handle = <&r_sense>;
adi,number-of-wires = <2>;
adi,rsense-share;
adi,excitation-current-microamp = <500>;
adi,rtd-curve = <0>;
};
};
};
...

View File

@ -37,9 +37,10 @@ directory contains attributes of the following form:
* :file:`index`, the scan_index of the channel.
* :file:`type`, description of the scan element data storage within the buffer
and hence the form in which it is read from user space.
Format is [be|le]:[s|u]bits/storagebits[Xrepeat][>>shift] .
Format is [be|le]:[f|s|u]bits/storagebits[Xrepeat][>>shift] .
* *be* or *le*, specifies big or little endian.
* *f*, specifies if floating-point.
* *s* or *u*, specifies if signed (2's complement) or unsigned.
* *bits*, is the number of valid data bits.
* *storagebits*, is the number of bits (after padding) that it occupies in the
@ -78,7 +79,7 @@ fields in iio_chan_spec definition::
/* other members */
int scan_index
struct {
char sign;
char format;
u8 realbits;
u8 storagebits;
u8 shift;
@ -98,7 +99,7 @@ following channel definition::
/* other stuff here */
.scan_index = 0,
.scan_type = {
.sign = 's',
.format = IIO_SCAN_FORMAT_SIGNED_INT,
.realbits = 12,
.storagebits = 16,
.shift = 4,

View File

@ -29,21 +29,21 @@ A typical triggered buffer setup looks like this::
irqreturn_t sensor_trigger_handler(int irq, void *p)
{
u16 buf[8];
IIO_DECLARE_BUFFER_WITH_TS(u16, buf, 3) = { };
int i = 0;
/* read data for each active channel */
for_each_set_bit(bit, active_scan_mask, masklength)
buf[i++] = sensor_get_data(bit)
iio_for_each_active_channel(indio_dev, bit)
buf[i++] = sensor_get_data(bit);
iio_push_to_buffers_with_timestamp(indio_dev, buf, timestamp);
iio_push_to_buffers_with_ts(indio_dev, buf, sizeof(buf), timestamp);
iio_trigger_notify_done(trigger);
return IRQ_HANDLED;
}
/* setup triggered buffer, usually in probe function */
iio_triggered_buffer_setup(indio_dev, sensor_iio_polfunc,
iio_triggered_buffer_setup(indio_dev, sensor_iio_pollfunc,
sensor_trigger_handler,
sensor_buffer_setup_ops);

View File

@ -0,0 +1,227 @@
.. SPDX-License-Identifier: GPL-2.0-only
=============
AD4691 driver
=============
ADC driver for Analog Devices Inc. AD4691 family of multichannel SAR ADCs.
The module name is ``ad4691``.
Supported devices
=================
The following chips are supported by this driver:
* `AD4691 <https://www.analog.com/en/products/ad4691.html>`_ — 16-channel, 500 kSPS
* `AD4692 <https://www.analog.com/en/products/ad4692.html>`_ — 16-channel, 1 MSPS
* `AD4693 <https://www.analog.com/en/products/ad4693.html>`_ — 8-channel, 500 kSPS
* `AD4694 <https://www.analog.com/en/products/ad4694.html>`_ — 8-channel, 1 MSPS
IIO channels
============
Each physical ADC input maps to one IIO voltage channel. The AD4691 and AD4692
expose 16 channels (``voltage0`` through ``voltage15``); the AD4693 and AD4694
expose 8 channels (``voltage0`` through ``voltage7``).
All channels share a common scale (``in_voltage_scale``), derived from the
reference voltage. Each channel exposes:
* ``in_voltageN_raw`` — single-shot ADC result
The following attributes are shared across all channels:
* ``in_voltage_sampling_frequency`` — effective output rate, defined as the
internal oscillator frequency divided by the oversampling ratio. Writing this
attribute selects the nearest achievable rate for the current OSR; the value
read back reflects the actual rate after snapping to the closest valid
oscillator entry.
* ``in_voltage_sampling_frequency_available`` — list of achievable effective
rates for the current oversampling ratio. The list updates dynamically when
the oversampling ratio changes.
The following attributes are shared across all channels and only available in
CNV Burst Mode:
* ``in_voltage_oversampling_ratio`` — hardware oversampling depth applied to
all channels; see `Oversampling`_ below.
* ``in_voltage_oversampling_ratio_available`` — valid ratios: 1, 2, 4, 8, 16,
32.
Operating modes
===============
The driver supports two operating modes, selected automatically from the
device tree at probe time.
Manual Mode
-----------
Selected when no ``pwms`` property is present in the device tree. The CNV pin
is tied to the SPI chip-select: every CS assertion triggers a conversion and
returns the previous result. A user-defined IIO trigger (e.g. hrtimer trigger)
drives the buffer.
Oversampling is not supported in Manual Mode.
CNV Burst Mode
--------------
Selected when a ``pwms`` property is present in the device tree. A PWM drives
the CNV pin at the configured conversion rate. A GP pin wired to the SoC and
declared in the device tree signals DATA_READY at the end of each burst,
triggering a readout of all active channel results into the IIO buffer.
The buffer output rate is controlled by the ``sampling_frequency`` attribute
on the IIO buffer. In practice the PWM rate should be set low enough to allow
the SPI readout to complete before the next conversion burst begins.
Autonomous Mode (idle / single-shot)
-------------------------------------
When the IIO buffer is disabled, ``in_voltageN_raw`` reads perform a single
conversion on the requested channel using the internal oscillator. The
oscillator is started and stopped around each read to save power.
Oversampling
============
In CNV Burst Mode a shared hardware accumulator averages a configurable number
of successive conversions across all active channels. The result is always a
16-bit mean, so the buffer data type (shown in ``buffer0/in_voltageN_type``)
is unaffected by the oversampling ratio. Valid ratios are 1, 2, 4, 8, 16 and
32; the default is 1 (no averaging). Oversampling is not supported in Manual
Mode.
.. code-block:: bash
# Set oversampling ratio to 16 (shared across all channels)
echo 16 > /sys/bus/iio/devices/iio:device0/in_voltage_oversampling_ratio
# Read the resulting effective sampling frequency
cat /sys/bus/iio/devices/iio:device0/in_voltage_sampling_frequency
Writing ``in_voltage_oversampling_ratio`` stores the new shared depth and snaps
the internal oscillator to the largest valid table entry that is both less than
or equal to ``old_effective_rate × new_osr`` and evenly divisible by
``new_osr``. This preserves an integer read-back of
``in_voltage_sampling_frequency`` after the change and keeps the oscillator as
close as possible to the previous effective rate.
Reference voltage
=================
The driver supports two reference configurations, mutually exclusive:
* **External reference** (``ref-supply``): a voltage between 2.4 V and 5.25 V
supplied externally.
* **Buffered internal reference** (``refin-supply``): an internal reference
buffer is enabled by the driver.
Exactly one of ``ref-supply`` or ``refin-supply`` must be present in the
device tree. The reference voltage determines the full-scale range reported
via ``in_voltage_scale``.
LDO supply
==========
The chip contains an internal LDO that powers part of the analog front-end.
The supply configuration is mutually exclusive:
* **External VDD** (``vdd-supply``): an external 1.8 V supply is used directly;
the internal LDO is disabled.
* **Internal LDO** (``ldo-in-supply``): the internal LDO is enabled and fed
from the ``ldo-in`` regulator. Use this when no external 1.8 V VDD is present.
Exactly one of ``vdd-supply`` or ``ldo-in-supply`` must be provided.
Reset
=====
The driver supports two reset mechanisms:
* **Hardware reset** (``reset-gpios`` in device tree): the GPIO line is
asserted then deasserted at probe; the driver waits 300 µs for the chip
to complete its internal reset sequence before accepting SPI commands.
* **Software reset** (fallback when ``reset-gpios`` is absent): written
automatically at probe.
GP pins and interrupts
======================
The chip exposes up to four general-purpose (GP) pins. In CNV Burst Mode
(non-offload), one GP pin must be wired to an interrupt-capable SoC input and
declared in the device tree using the ``interrupts`` and ``interrupt-names``
properties. The ``interrupt-names`` value identifies which GP pin is used
(``"gp0"`` through ``"gp3"``).
Example device tree fragment::
adc@0 {
compatible = "adi,ad4692";
...
interrupt-parent = <&gpio0>;
interrupts = <17 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "gp0";
};
SPI offload support
===================
When a SPI offload engine (e.g. the AXI SPI Engine) is present, the driver
uses DMA-backed transfers for CPU-independent, high-throughput data capture.
SPI offload is detected automatically at probe; if no offload hardware is
available the driver falls back to the software triggered-buffer path.
Two SPI offload sub-modes exist:
CNV Burst offload
-----------------
Used when a ``pwms`` property is present and SPI offload is available. The PWM
drives CNV at the configured rate; on DATA_READY the offload engine reads all
active channel results and streams them directly to the IIO DMA buffer with no
CPU involvement. The GP pin used as DATA_READY trigger is supplied by the
trigger-source consumer at buffer enable time; no ``interrupt-names`` entry is
required.
Manual offload
--------------
Used when no ``pwms`` property is present and SPI offload is available. A
periodic SPI offload trigger controls the conversion rate and the offload engine
streams results directly to the IIO DMA buffer.
The ``sampling_frequency`` attribute on the IIO buffer controls the trigger
rate (in Hz). The initial rate is 100 kHz.
Oversampling is not supported in Manual Mode.
Buffer data format
==================
The sample format in the IIO buffer depends on whether SPI offload is in use.
Software triggered-buffer path (no SPI offload)
------------------------------------------------
Each active channel occupies one 16-bit big-endian slot (``storagebits=16``,
``endianness=be``). Active channels are packed densely in scan-index order,
followed by a 64-bit software timestamp appended by the IIO core.
SPI offload path
----------------
Each active channel occupies one 16-bit CPU-native slot (``storagebits=16``,
``endianness=cpu``). The SPI offload engine streams 16-bit words directly from
the SPI Engine into the DMA buffer; no software timestamp is appended.

View File

@ -11,7 +11,7 @@ This driver supports Analog Device's ADXL313 on SPI/I2C bus.
* `ADXL313 <https://www.analog.com/ADXL313>`_
The ADXL313is a low noise density, low power, 3-axis accelerometer with
The ADXL313 is a low noise density, low power, 3-axis accelerometer with
selectable measurement ranges. The ADXL313 supports the ±0.5 g, ±1 g, ±2 g and
±4 g ranges.
@ -38,7 +38,7 @@ specific device folder path ``/sys/bus/iio/devices/iio:deviceX``.
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_x_raw | Raw X-axis accelerometer channel value. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_y_calibbias | y-axis acceleration offset correction |
| in_accel_y_calibbias | Calibration offset for the Y-axis accelerometer channel. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_y_raw | Raw Y-axis accelerometer channel value. |
+---------------------------------------------------+----------------------------------------------------------+
@ -112,9 +112,9 @@ apply the following formula:
Where _offset and _scale are device attributes. If no _offset attribute is
present, simply assume its value is 0.
The ADXL313 driver offers data for a single types of channels, the table below
shows the measurement units for the processed value, which are defined by the
IIO framework:
The ADXL313 driver offers data for multiple channels of a single type.
The table below shows the measurement units for the processed value,
which are defined by the IIO framework:
+-------------------------------------+---------------------------+
| Channel type | Measurement unit |

View File

@ -47,7 +47,7 @@ specific device folder path ``/sys/bus/iio/devices/iio:deviceX``.
+-------------------------------------------+----------------------------------------------------------+
| in_accel_x_raw | Raw X-axis accelerometer channel value. |
+-------------------------------------------+----------------------------------------------------------+
| in_accel_y_calibbias | Y-axis acceleration offset correction |
| in_accel_y_calibbias | Calibration offset for the Y-axis accelerometer channel. |
+-------------------------------------------+----------------------------------------------------------+
| in_accel_y_raw | Raw Y-axis accelerometer channel value. |
+-------------------------------------------+----------------------------------------------------------+

View File

@ -51,7 +51,7 @@ specific device folder path ``/sys/bus/iio/devices/iio:deviceX``.
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_x_raw | Raw X-axis accelerometer channel value. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_y_calibbias | y-axis acceleration offset correction |
| in_accel_y_calibbias | Calibration offset for the Y-axis accelerometer channel. |
+---------------------------------------------------+----------------------------------------------------------+
| in_accel_y_raw | Raw Y-axis accelerometer channel value. |
+---------------------------------------------------+----------------------------------------------------------+

View File

@ -83,9 +83,10 @@ and the relevant _type attributes to establish the data storage format.
Read-only attribute containing the description of the scan element data storage
within the buffer and hence the form in which it is read from userspace. Format
is [be|le]:[s|u]bits/storagebits[Xrepeat][>>shift], where:
is [be|le]:[f|s|u]bits/storagebits[Xrepeat][>>shift], where:
- **be** or **le** specifies big or little-endian.
- **f** specifies if floating-point.
- **s** or **u** specifies if signed (2's complement) or unsigned.
- **bits** is the number of valid data bits.
- **storagebits** is the number of bits (after padding) that it occupies in the

View File

@ -23,6 +23,7 @@ Industrial I/O Kernel Drivers
ad4000
ad4030
ad4062
ad4691
ad4695
ad7191
ad7380

View File

@ -1,128 +0,0 @@
.. SPDX-License-Identifier: GPL-2.0
======================
Kernel driver apds990x
======================
Supported chips:
Avago APDS990X
Data sheet:
Not freely available
Author:
Samu Onkalo <samu.p.onkalo@nokia.com>
Description
-----------
APDS990x is a combined ambient light and proximity sensor. ALS and proximity
functionality are highly connected. ALS measurement path must be running
while the proximity functionality is enabled.
ALS produces raw measurement values for two channels: Clear channel
(infrared + visible light) and IR only. However, threshold comparisons happen
using clear channel only. Lux value and the threshold level on the HW
might vary quite much depending the spectrum of the light source.
Driver makes necessary conversions to both directions so that user handles
only lux values. Lux value is calculated using information from the both
channels. HW threshold level is calculated from the given lux value to match
with current type of the lightning. Sometimes inaccuracy of the estimations
lead to false interrupt, but that doesn't harm.
ALS contains 4 different gain steps. Driver automatically
selects suitable gain step. After each measurement, reliability of the results
is estimated and new measurement is triggered if necessary.
Platform data can provide tuned values to the conversion formulas if
values are known. Otherwise plain sensor default values are used.
Proximity side is little bit simpler. There is no need for complex conversions.
It produces directly usable values.
Driver controls chip operational state using pm_runtime framework.
Voltage regulators are controlled based on chip operational state.
SYSFS
-----
chip_id
RO - shows detected chip type and version
power_state
RW - enable / disable chip. Uses counting logic
1 enables the chip
0 disables the chip
lux0_input
RO - measured lux value
sysfs_notify called when threshold interrupt occurs
lux0_sensor_range
RO - lux0_input max value.
Actually never reaches since sensor tends
to saturate much before that. Real max value varies depending
on the light spectrum etc.
lux0_rate
RW - measurement rate in Hz
lux0_rate_avail
RO - supported measurement rates
lux0_calibscale
RW - calibration value.
Set to neutral value by default.
Output results are multiplied with calibscale / calibscale_default
value.
lux0_calibscale_default
RO - neutral calibration value
lux0_thresh_above_value
RW - HI level threshold value.
All results above the value
trigs an interrupt. 65535 (i.e. sensor_range) disables the above
interrupt.
lux0_thresh_below_value
RW - LO level threshold value.
All results below the value
trigs an interrupt. 0 disables the below interrupt.
prox0_raw
RO - measured proximity value
sysfs_notify called when threshold interrupt occurs
prox0_sensor_range
RO - prox0_raw max value (1023)
prox0_raw_en
RW - enable / disable proximity - uses counting logic
- 1 enables the proximity
- 0 disables the proximity
prox0_reporting_mode
RW - trigger / periodic.
In "trigger" mode the driver tells two possible
values: 0 or prox0_sensor_range value. 0 means no proximity,
1023 means proximity. This causes minimal number of interrupts.
In "periodic" mode the driver reports all values above
prox0_thresh_above. This causes more interrupts, but it can give
_rough_ estimate about the distance.
prox0_reporting_mode_avail
RO - accepted values to prox0_reporting_mode (trigger, periodic)
prox0_thresh_above_value
RW - threshold level which trigs proximity events.

View File

@ -13,7 +13,6 @@ fit into other categories.
ad525x_dpot
amd-sbi
apds990x
bh1770glc
c2port
dw-xdata-pcie

View File

@ -639,7 +639,7 @@ F: drivers/iio/accel/adxl355_i2c.c
F: drivers/iio/accel/adxl355_spi.c
ADXL367 THREE-AXIS DIGITAL ACCELEROMETER DRIVER
M: Cosmin Tanislav <cosmin.tanislav@analog.com>
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
@ -1459,7 +1459,7 @@ F: Documentation/devicetree/bindings/iio/adc/adi,ad4080.yaml
F: drivers/iio/adc/ad4080.c
ANALOG DEVICES INC AD4130 DRIVER
M: Cosmin Tanislav <cosmin.tanislav@analog.com>
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
@ -1483,6 +1483,15 @@ W: https://ez.analog.com/linux-software-drivers
F: Documentation/devicetree/bindings/iio/adc/adi,ad4170-4.yaml
F: drivers/iio/adc/ad4170-4.c
ANALOG DEVICES INC AD4691 DRIVER
M: Radu Sabau <radu.sabau@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,ad4691.yaml
F: Documentation/iio/ad4691.rst
F: drivers/iio/adc/ad4691.c
ANALOG DEVICES INC AD4695 DRIVER
M: Michael Hennerich <michael.hennerich@analog.com>
M: Nuno Sá <nuno.sa@analog.com>
@ -1505,6 +1514,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 AD5706R DRIVER
M: Alexis Czezar Torreno <alexisczezar.torreno@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,ad5706r.yaml
F: drivers/iio/dac/ad5706r.c
ANALOG DEVICES INC AD7091R DRIVER
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
L: linux-iio@vger.kernel.org
@ -1547,7 +1564,7 @@ F: Documentation/devicetree/bindings/iio/dac/adi,ad7293.yaml
F: drivers/iio/dac/ad7293.c
ANALOG DEVICES INC AD74115 DRIVER
M: Cosmin Tanislav <cosmin.tanislav@analog.com>
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
@ -1555,7 +1572,7 @@ F: Documentation/devicetree/bindings/iio/addac/adi,ad74115.yaml
F: drivers/iio/addac/ad74115.c
ANALOG DEVICES INC AD74413R DRIVER
M: Cosmin Tanislav <cosmin.tanislav@analog.com>
M: Marcelo Schmitt <marcelo.schmitt@analog.com>
L: linux-iio@vger.kernel.org
S: Supported
W: https://ez.analog.com/linux-software-drivers
@ -1851,8 +1868,9 @@ W: https://ez.analog.com/linux-software-drivers
F: drivers/dma/dma-axi-dmac.c
ANALOG DEVICES INC IIO DRIVERS
M: Lars-Peter Clausen <lars@metafoo.de>
M: Nuno Sá <nuno.sa@analog.com>
M: Michael Hennerich <Michael.Hennerich@analog.com>
L: linux@analog.com
S: Supported
W: http://wiki.analog.com/
W: https://ez.analog.com/linux-software-drivers
@ -4991,6 +5009,13 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/light/brcm,apds9160.yaml
F: drivers/iio/light/apds9160.c
BROADCOM APDS9999 AMBIENT LIGHT SENSOR DRIVER
M: Jose A. Perez de Azpillaga <azpijr@gmail.com>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/light/brcm,apds9999.yaml
F: drivers/iio/light/apds9999.c
BROADCOM ASP 2.0 ETHERNET DRIVER
M: Justin Chen <justin.chen@broadcom.com>
M: Florian Fainelli <florian.fainelli@broadcom.com>
@ -12500,6 +12525,7 @@ 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*
F: Documentation/devicetree/bindings/iio/
F: Documentation/driver-api/iio/
F: Documentation/iio/
F: drivers/iio/
F: drivers/staging/iio/
@ -17179,6 +17205,13 @@ F: drivers/mtd/
F: include/linux/mtd/
F: include/uapi/mtd/
MEMSIC MMC5983 MAGNETOMETER DRIVER
M: Vladislav Kulikov <vlad.kulikov.c@gmail.com>
L: linux-iio@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/iio/magnetometer/memsic,mmc5983.yaml
F: drivers/iio/magnetometer/mmc5983.c
MEN A21 WATCHDOG DRIVER
M: Johannes Thumshirn <morbidrsa@gmail.com>
L: linux-watchdog@vger.kernel.org
@ -22637,7 +22670,7 @@ F: Documentation/devicetree/bindings/mtd/renesas-nandc.yaml
F: drivers/mtd/nand/raw/renesas-nand-controller.c
RENESAS R-CAR GYROADC DRIVER
M: Marek Vasut <marek.vasut@gmail.com>
M: Marek Vasut <marek.vasut+renesas@mailbox.org>
L: linux-iio@vger.kernel.org
S: Supported
F: Documentation/devicetree/bindings/iio/adc/renesas,rcar-gyroadc.yaml
@ -24228,7 +24261,7 @@ F: Documentation/devicetree/bindings/iio/chemical/senseair,sunrise.yaml
F: drivers/iio/chemical/sunrise_co2.c
SENSIRION SCD30 CARBON DIOXIDE SENSOR DRIVER
M: Tomasz Duszynski <tomasz.duszynski@octakon.com>
M: Maxwell Doose <m32285159@gmail.com>
S: Maintained
F: Documentation/devicetree/bindings/iio/chemical/sensirion,scd30.yaml
F: drivers/iio/chemical/scd30.h
@ -28407,6 +28440,11 @@ S: Maintained
F: Documentation/devicetree/bindings/iio/light/vishay,veml6030.yaml
F: drivers/iio/light/veml3235.c
VISHAY VEML3328 RGB IR LIGHT SENSOR DRIVER
M: Joshua Crofts <joshua.crofts1@gmail.com>
S: Maintained
F: drivers/iio/light/veml3328.c
VISHAY VEML6030 AMBIENT LIGHT SENSOR DRIVER
M: Javier Carrasco <javier.carrasco.cruz@gmail.com>
S: Maintained

View File

@ -1240,7 +1240,9 @@ int adxl313_core_probe(struct device *dev,
data->regmap = regmap;
data->chip_info = chip_info;
mutex_init(&data->lock);
ret = devm_mutex_init(dev, &data->lock);
if (ret)
return ret;
indio_dev->name = chip_info->name;
indio_dev->info = &adxl313_info;
@ -1250,10 +1252,8 @@ int adxl313_core_probe(struct device *dev,
indio_dev->available_scan_masks = adxl313_scan_masks;
ret = adxl313_setup(dev, data, setup);
if (ret) {
dev_err(dev, "ADXL313 setup failed\n");
return ret;
}
if (ret)
return dev_err_probe(dev, ret, "ADXL313 setup failed\n");
int_line = adxl313_get_int_type(dev, &irq);
if (int_line == ADXL313_INT_NONE) {

View File

@ -65,6 +65,7 @@ MODULE_DEVICE_TABLE(of, adxl313_of_match);
static int adxl313_i2c_probe(struct i2c_client *client)
{
const struct adxl313_chip_info *chip_data;
struct device *dev = &client->dev;
struct regmap *regmap;
/*
@ -75,13 +76,10 @@ static int adxl313_i2c_probe(struct i2c_client *client)
regmap = devm_regmap_init_i2c(client,
&adxl31x_i2c_regmap_config[chip_data->type]);
if (IS_ERR(regmap)) {
dev_err(&client->dev, "Error initializing i2c regmap: %ld\n",
PTR_ERR(regmap));
return PTR_ERR(regmap);
}
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), "Error initializing i2c regmap\n");
return adxl313_core_probe(&client->dev, regmap, chip_data, NULL);
return adxl313_core_probe(dev, regmap, chip_data, NULL);
}
static struct i2c_driver adxl313_i2c_driver = {

View File

@ -70,6 +70,7 @@ static int adxl313_spi_setup(struct device *dev, struct regmap *regmap)
static int adxl313_spi_probe(struct spi_device *spi)
{
const struct adxl313_chip_info *chip_data;
struct device *dev = &spi->dev;
struct regmap *regmap;
int ret;
@ -83,14 +84,10 @@ static int adxl313_spi_probe(struct spi_device *spi)
regmap = devm_regmap_init_spi(spi,
&adxl31x_spi_regmap_config[chip_data->type]);
if (IS_ERR(regmap)) {
dev_err(&spi->dev, "Error initializing spi regmap: %ld\n",
PTR_ERR(regmap));
return PTR_ERR(regmap);
}
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), "Error initializing spi regmap\n");
return adxl313_core_probe(&spi->dev, regmap,
chip_data, &adxl313_spi_setup);
return adxl313_core_probe(dev, regmap, chip_data, &adxl313_spi_setup);
}
static const struct spi_device_id adxl313_spi_id[] = {

View File

@ -43,8 +43,8 @@ static const struct adxl345_chip_info adxl375_i2c_info = {
};
static const struct i2c_device_id adxl345_i2c_id[] = {
{ "adxl345", (kernel_ulong_t)&adxl345_i2c_info },
{ "adxl375", (kernel_ulong_t)&adxl375_i2c_info },
{ .name = "adxl345", .driver_data = (kernel_ulong_t)&adxl345_i2c_info },
{ .name = "adxl375", .driver_data = (kernel_ulong_t)&adxl375_i2c_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, adxl345_i2c_id);

View File

@ -336,10 +336,8 @@ static int adxl355_setup(struct adxl355_data *data)
return ret;
do {
if (--retries == 0) {
dev_err(data->dev, "Shadow registers mismatch\n");
return -EIO;
}
if (--retries == 0)
return dev_err_probe(data->dev, -EIO, "Shadow registers mismatch\n");
/*
* Perform a software reset to make sure the device is in a consistent
@ -351,7 +349,7 @@ static int adxl355_setup(struct adxl355_data *data)
return ret;
/* Wait at least 5ms after software reset */
usleep_range(5000, 10000);
fsleep(5 * USEC_PER_MSEC);
/* Read shadow registers for comparison */
ret = regmap_bulk_read(data->regmap,
@ -775,10 +773,8 @@ static int adxl355_probe_trigger(struct iio_dev *indio_dev, int irq)
irq);
ret = devm_iio_trigger_register(data->dev, data->dready_trig);
if (ret) {
dev_err(data->dev, "iio trigger register failed\n");
return ret;
}
if (ret)
return dev_err_probe(data->dev, ret, "iio trigger register failed\n");
indio_dev->trig = iio_trigger_get(data->dready_trig);
@ -802,7 +798,9 @@ int adxl355_core_probe(struct device *dev, struct regmap *regmap,
data->dev = dev;
data->op_mode = ADXL355_STANDBY;
data->chip_info = chip_info;
mutex_init(&data->lock);
ret = devm_mutex_init(dev, &data->lock);
if (ret)
return ret;
indio_dev->name = chip_info->name;
indio_dev->info = &adxl355_info;
@ -812,18 +810,14 @@ int adxl355_core_probe(struct device *dev, struct regmap *regmap,
indio_dev->available_scan_masks = adxl355_avail_scan_masks;
ret = adxl355_setup(data);
if (ret) {
dev_err(dev, "ADXL355 setup failed\n");
return ret;
}
if (ret)
return dev_err_probe(dev, ret, "ADXL355 setup failed\n");
ret = devm_iio_triggered_buffer_setup(dev, indio_dev,
&iio_pollfunc_store_time,
&adxl355_trigger_handler, NULL);
if (ret) {
dev_err(dev, "iio triggered buffer setup failed\n");
return ret;
}
if (ret)
return dev_err_probe(dev, ret, "iio triggered buffer setup failed\n");
irq = fwnode_irq_get_byname(dev_fwnode(dev), "DRDY");
if (irq > 0) {

View File

@ -23,6 +23,7 @@ static const struct regmap_config adxl355_i2c_regmap_config = {
static int adxl355_i2c_probe(struct i2c_client *client)
{
struct regmap *regmap;
struct device *dev = &client->dev;
const struct adxl355_chip_info *chip_data;
chip_data = i2c_get_match_data(client);
@ -30,19 +31,15 @@ static int adxl355_i2c_probe(struct i2c_client *client)
return -ENODEV;
regmap = devm_regmap_init_i2c(client, &adxl355_i2c_regmap_config);
if (IS_ERR(regmap)) {
dev_err(&client->dev, "Error initializing i2c regmap: %ld\n",
PTR_ERR(regmap));
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), "Error initializing i2c regmap\n");
return PTR_ERR(regmap);
}
return adxl355_core_probe(&client->dev, regmap, chip_data);
return adxl355_core_probe(dev, regmap, chip_data);
}
static const struct i2c_device_id adxl355_i2c_id[] = {
{ "adxl355", (kernel_ulong_t)&adxl35x_chip_info[ADXL355] },
{ "adxl359", (kernel_ulong_t)&adxl35x_chip_info[ADXL359] },
{ .name = "adxl355", .driver_data = (kernel_ulong_t)&adxl35x_chip_info[ADXL355] },
{ .name = "adxl359", .driver_data = (kernel_ulong_t)&adxl35x_chip_info[ADXL359] },
{ }
};
MODULE_DEVICE_TABLE(i2c, adxl355_i2c_id);

View File

@ -26,6 +26,7 @@ static const struct regmap_config adxl355_spi_regmap_config = {
static int adxl355_spi_probe(struct spi_device *spi)
{
const struct adxl355_chip_info *chip_data;
struct device *dev = &spi->dev;
struct regmap *regmap;
chip_data = spi_get_device_match_data(spi);
@ -33,14 +34,10 @@ static int adxl355_spi_probe(struct spi_device *spi)
return -EINVAL;
regmap = devm_regmap_init_spi(spi, &adxl355_spi_regmap_config);
if (IS_ERR(regmap)) {
dev_err(&spi->dev, "Error initializing spi regmap: %ld\n",
PTR_ERR(regmap));
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap), "Error initializing spi regmap\n");
return PTR_ERR(regmap);
}
return adxl355_core_probe(&spi->dev, regmap, chip_data);
return adxl355_core_probe(dev, regmap, chip_data);
}
static const struct spi_device_id adxl355_spi_id[] = {

View File

@ -1445,7 +1445,9 @@ int adxl367_probe(struct device *dev, const struct adxl367_ops *ops,
st->context = context;
st->ops = ops;
mutex_init(&st->lock);
ret = devm_mutex_init(dev, &st->lock);
if (ret)
return ret;
indio_dev->channels = adxl367_channels;
indio_dev->num_channels = ARRAY_SIZE(adxl367_channels);

View File

@ -61,7 +61,7 @@ static int adxl367_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id adxl367_i2c_id[] = {
{ "adxl367" },
{ .name = "adxl367" },
{ }
};
MODULE_DEVICE_TABLE(i2c, adxl367_i2c_id);

View File

@ -1299,7 +1299,9 @@ int adxl372_probe(struct device *dev, struct regmap *regmap,
st->irq = irq;
st->chip_info = chip_info;
mutex_init(&st->threshold_m);
ret = devm_mutex_init(dev, &st->threshold_m);
if (ret < 0)
return ret;
indio_dev->channels = adxl372_channels;
indio_dev->num_channels = ARRAY_SIZE(adxl372_channels);
@ -1314,10 +1316,8 @@ int adxl372_probe(struct device *dev, struct regmap *regmap,
}
ret = adxl372_setup(st);
if (ret < 0) {
dev_err(dev, "ADXL372 setup failed\n");
return ret;
}
if (ret < 0)
return dev_err_probe(dev, ret, "ADXL372 setup failed\n");
if (chip_info->fifo_supported) {
ret = adxl372_buffer_setup(indio_dev);

View File

@ -44,8 +44,8 @@ static int adxl372_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id adxl372_i2c_id[] = {
{ "adxl371", (kernel_ulong_t)&adxl371_chip_info },
{ "adxl372", (kernel_ulong_t)&adxl372_chip_info },
{ .name = "adxl371", .driver_data = (kernel_ulong_t)&adxl371_chip_info },
{ .name = "adxl372", .driver_data = (kernel_ulong_t)&adxl372_chip_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, adxl372_i2c_id);

View File

@ -1967,7 +1967,9 @@ int adxl380_probe(struct device *dev, struct regmap *regmap,
st->chip_info = chip_info;
st->odr = ADXL380_ODR_DSM;
mutex_init(&st->lock);
ret = devm_mutex_init(dev, &st->lock);
if (ret)
return ret;
indio_dev->channels = adxl380_channels;
indio_dev->num_channels = ARRAY_SIZE(adxl380_channels);

View File

@ -33,10 +33,10 @@ static int adxl380_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id adxl380_i2c_id[] = {
{ "adxl318", (kernel_ulong_t)&adxl318_chip_info },
{ "adxl319", (kernel_ulong_t)&adxl319_chip_info },
{ "adxl380", (kernel_ulong_t)&adxl380_chip_info },
{ "adxl382", (kernel_ulong_t)&adxl382_chip_info },
{ .name = "adxl318", .driver_data = (kernel_ulong_t)&adxl318_chip_info },
{ .name = "adxl319", .driver_data = (kernel_ulong_t)&adxl319_chip_info },
{ .name = "adxl380", .driver_data = (kernel_ulong_t)&adxl380_chip_info },
{ .name = "adxl382", .driver_data = (kernel_ulong_t)&adxl382_chip_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, adxl380_i2c_id);

View File

@ -1083,11 +1083,11 @@ static int bma180_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
static const struct i2c_device_id bma180_ids[] = {
{ "bma023", (kernel_ulong_t)&bma180_part_info[BMA023] },
{ "bma150", (kernel_ulong_t)&bma180_part_info[BMA150] },
{ "bma180", (kernel_ulong_t)&bma180_part_info[BMA180] },
{ "bma250", (kernel_ulong_t)&bma180_part_info[BMA250] },
{ "smb380", (kernel_ulong_t)&bma180_part_info[BMA150] },
{ .name = "bma023", .driver_data = (kernel_ulong_t)&bma180_part_info[BMA023] },
{ .name = "bma150", .driver_data = (kernel_ulong_t)&bma180_part_info[BMA150] },
{ .name = "bma180", .driver_data = (kernel_ulong_t)&bma180_part_info[BMA180] },
{ .name = "bma250", .driver_data = (kernel_ulong_t)&bma180_part_info[BMA250] },
{ .name = "smb380", .driver_data = (kernel_ulong_t)&bma180_part_info[BMA150] },
{ }
};

View File

@ -47,7 +47,7 @@ static const struct of_device_id bma220_i2c_match[] = {
MODULE_DEVICE_TABLE(of, bma220_i2c_match);
static const struct i2c_device_id bma220_i2c_id[] = {
{ "bma220" },
{ .name = "bma220" },
{ }
};
MODULE_DEVICE_TABLE(i2c, bma220_i2c_id);

View File

@ -28,7 +28,7 @@ static int bma400_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id bma400_i2c_ids[] = {
{ "bma400" },
{ .name = "bma400" },
{ }
};
MODULE_DEVICE_TABLE(i2c, bma400_i2c_ids);

View File

@ -245,16 +245,16 @@ static const struct acpi_device_id bmc150_accel_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, bmc150_accel_acpi_match);
static const struct i2c_device_id bmc150_accel_id[] = {
{"bma222"},
{"bma222e"},
{"bma250e"},
{"bma253"},
{"bma254"},
{"bma255"},
{"bma280"},
{"bmc150_accel"},
{"bmc156_accel", BOSCH_BMC156},
{"bmi055_accel"},
{ .name = "bma222", .driver_data = BOSCH_UNKNOWN },
{ .name = "bma222e", .driver_data = BOSCH_UNKNOWN },
{ .name = "bma250e", .driver_data = BOSCH_UNKNOWN },
{ .name = "bma253", .driver_data = BOSCH_UNKNOWN },
{ .name = "bma254", .driver_data = BOSCH_UNKNOWN },
{ .name = "bma255", .driver_data = BOSCH_UNKNOWN },
{ .name = "bma280", .driver_data = BOSCH_UNKNOWN },
{ .name = "bmc150_accel", .driver_data = BOSCH_UNKNOWN },
{ .name = "bmc156_accel", .driver_data = BOSCH_BMC156 },
{ .name = "bmi055_accel", .driver_data = BOSCH_UNKNOWN },
{ }
};

View File

@ -45,9 +45,9 @@ static const struct of_device_id bmi088_of_match[] = {
MODULE_DEVICE_TABLE(of, bmi088_of_match);
static const struct i2c_device_id bmi088_accel_id[] = {
{ "bmi085-accel", BOSCH_BMI085 },
{ "bmi088-accel", BOSCH_BMI088 },
{ "bmi090l-accel", BOSCH_BMI090L },
{ .name = "bmi085-accel", .driver_data = BOSCH_BMI085 },
{ .name = "bmi088-accel", .driver_data = BOSCH_BMI088 },
{ .name = "bmi090l-accel", .driver_data = BOSCH_BMI090L },
{ }
};
MODULE_DEVICE_TABLE(i2c, bmi088_accel_id);

View File

@ -162,9 +162,9 @@ static const struct acpi_device_id da280_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, da280_acpi_match);
static const struct i2c_device_id da280_i2c_id[] = {
{ "da217", (kernel_ulong_t)&da217_match_data },
{ "da226", (kernel_ulong_t)&da226_match_data },
{ "da280", (kernel_ulong_t)&da280_match_data },
{ .name = "da217", .driver_data = (kernel_ulong_t)&da217_match_data },
{ .name = "da226", .driver_data = (kernel_ulong_t)&da226_match_data },
{ .name = "da280", .driver_data = (kernel_ulong_t)&da280_match_data },
{ }
};
MODULE_DEVICE_TABLE(i2c, da280_i2c_id);

View File

@ -268,7 +268,7 @@ static int da311_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(da311_pm_ops, da311_suspend, da311_resume);
static const struct i2c_device_id da311_i2c_id[] = {
{ "da311" },
{ .name = "da311" },
{ }
};
MODULE_DEVICE_TABLE(i2c, da311_i2c_id);

View File

@ -199,9 +199,9 @@ static DEFINE_SIMPLE_DEV_PM_OPS(dmard06_pm_ops, dmard06_suspend,
dmard06_resume);
static const struct i2c_device_id dmard06_id[] = {
{ "dmard05" },
{ "dmard06" },
{ "dmard07" },
{ .name = "dmard05" },
{ .name = "dmard06" },
{ .name = "dmard07" },
{ }
};
MODULE_DEVICE_TABLE(i2c, dmard06_id);

View File

@ -123,7 +123,7 @@ static int dmard09_probe(struct i2c_client *client)
}
static const struct i2c_device_id dmard09_id[] = {
{ "dmard09" },
{ .name = "dmard09" },
{ }
};

View File

@ -229,7 +229,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(dmard10_pm_ops, dmard10_suspend,
dmard10_resume);
static const struct i2c_device_id dmard10_i2c_id[] = {
{ "dmard10" },
{ .name = "dmard10" },
{ }
};
MODULE_DEVICE_TABLE(i2c, dmard10_i2c_id);

View File

@ -28,10 +28,10 @@ static int fxls8962af_probe(struct i2c_client *client)
}
static const struct i2c_device_id fxls8962af_id[] = {
{ "fxls8962af", fxls8962af },
{ "fxls8964af", fxls8964af },
{ "fxls8967af", fxls8967af },
{ "fxls8974cf", fxls8974cf },
{ .name = "fxls8962af", .driver_data = fxls8962af },
{ .name = "fxls8964af", .driver_data = fxls8964af },
{ .name = "fxls8967af", .driver_data = fxls8967af },
{ .name = "fxls8974cf", .driver_data = fxls8974cf },
{ }
};
MODULE_DEVICE_TABLE(i2c, fxls8962af_id);

View File

@ -3,6 +3,7 @@
* HID Sensors Driver
* Copyright (c) 2012, Intel Corporation.
*/
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include <linux/module.h>
@ -119,17 +120,6 @@ static const struct iio_chan_spec gravity_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(CHANNEL_SCAN_INDEX_TIMESTAMP),
};
/* Adjust channel real bits based on report descriptor */
static void accel_3d_adjust_channel_bit_mask(struct iio_chan_spec *channels,
int channel, int size)
{
channels[channel].scan_type.sign = 's';
/* Real storage bits will change based on the report desc. */
channels[channel].scan_type.realbits = size * 8;
/* Maximum size of a sample to capture is u32 */
channels[channel].scan_type.storagebits = sizeof(u32) * 8;
}
/* Channel read_raw handler */
static int accel_3d_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
@ -297,19 +287,20 @@ static int accel_3d_parse_report(struct platform_device *pdev,
struct accel_3d_state *st)
{
int ret;
int i;
for (i = 0; i <= CHANNEL_SCAN_INDEX_Z; ++i) {
for (unsigned int ch = CHANNEL_SCAN_INDEX_X; ch <= CHANNEL_SCAN_INDEX_Z; ch++) {
ret = sensor_hub_input_get_attribute_info(hsdev,
HID_INPUT_REPORT,
usage_id,
HID_USAGE_SENSOR_ACCEL_X_AXIS + i,
&st->accel[CHANNEL_SCAN_INDEX_X + i]);
HID_USAGE_SENSOR_ACCEL_X_AXIS + ch,
&st->accel[ch]);
if (ret < 0)
break;
accel_3d_adjust_channel_bit_mask(channels,
CHANNEL_SCAN_INDEX_X + i,
st->accel[CHANNEL_SCAN_INDEX_X + i].size);
channels[ch].scan_type = (struct iio_scan_type) {
.format = 's',
.realbits = BYTES_TO_BITS(st->accel[ch].size),
.storagebits = BITS_PER_TYPE(u32),
};
}
dev_dbg(&pdev->dev, "accel_3d %x:%x, %x:%x, %x:%x\n",
st->accel[0].index,

View File

@ -1630,11 +1630,11 @@ static const struct dev_pm_ops kxcjk1013_pm_ops = {
};
static const struct i2c_device_id kxcjk1013_id[] = {
{ "kxcjk1013", (kernel_ulong_t)&kxcjk1013_info },
{ "kxcj91008", (kernel_ulong_t)&kxcj91008_info },
{ "kxtj21009", (kernel_ulong_t)&kxtj21009_info },
{ "kxtf9", (kernel_ulong_t)&kxtf9_info },
{ "kx023-1025", (kernel_ulong_t)&kx0231025_info },
{ .name = "kxcjk1013", .driver_data = (kernel_ulong_t)&kxcjk1013_info },
{ .name = "kxcj91008", .driver_data = (kernel_ulong_t)&kxcj91008_info },
{ .name = "kxtj21009", .driver_data = (kernel_ulong_t)&kxtj21009_info },
{ .name = "kxtf9", .driver_data = (kernel_ulong_t)&kxtf9_info },
{ .name = "kx023-1025", .driver_data = (kernel_ulong_t)&kx0231025_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, kxcjk1013_id);

View File

@ -43,7 +43,7 @@ static const struct of_device_id kxsd9_of_match[] = {
MODULE_DEVICE_TABLE(of, kxsd9_of_match);
static const struct i2c_device_id kxsd9_i2c_id[] = {
{ "kxsd9" },
{ .name = "kxsd9" },
{ }
};
MODULE_DEVICE_TABLE(i2c, kxsd9_i2c_id);

View File

@ -230,8 +230,8 @@ static int mc3230_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(mc3230_pm_ops, mc3230_suspend, mc3230_resume);
static const struct i2c_device_id mc3230_i2c_id[] = {
{ "mc3230", (kernel_ulong_t)&mc3230_chip_info },
{ "mc3510c", (kernel_ulong_t)&mc3510c_chip_info },
{ .name = "mc3230", .driver_data = (kernel_ulong_t)&mc3230_chip_info },
{ .name = "mc3510c", .driver_data = (kernel_ulong_t)&mc3510c_chip_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, mc3230_i2c_id);

View File

@ -32,8 +32,8 @@ static void mma7455_i2c_remove(struct i2c_client *i2c)
}
static const struct i2c_device_id mma7455_i2c_ids[] = {
{ "mma7455" },
{ "mma7456" },
{ .name = "mma7455" },
{ .name = "mma7456" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mma7455_i2c_ids);

View File

@ -259,7 +259,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(mma7660_pm_ops, mma7660_suspend,
mma7660_resume);
static const struct i2c_device_id mma7660_i2c_id[] = {
{ "mma7660" },
{ .name = "mma7660" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mma7660_i2c_id);

View File

@ -18,21 +18,22 @@
* TODO: orientation events
*/
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/property.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/types.h>
#include <linux/regulator/consumer.h>
#include <linux/iio/buffer.h>
#include <linux/iio/events.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/events.h>
#include <linux/delay.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/types.h>
#define MMA8452_STATUS 0x00
#define MMA8452_STATUS_DRDY (BIT(2) | BIT(1) | BIT(0))
@ -252,6 +253,8 @@ static int mma8452_read(struct mma8452_data *data, __be16 buf[3])
ret = i2c_smbus_read_i2c_block_data(data->client, MMA8452_OUT_X,
3 * sizeof(__be16), (u8 *)buf);
if (ret < 0)
return ret;
ret = mma8452_set_runtime_pm_state(data->client, false);
@ -704,8 +707,8 @@ static int mma8452_set_hp_filter_frequency(struct mma8452_data *data,
}
static int __mma8452_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int val, int val2, long mask)
struct iio_chan_spec const *chan,
int val, int val2, long mask)
{
struct mma8452_data *data = iio_priv(indio_dev);
int i, j, ret;
@ -786,8 +789,9 @@ static int mma8452_write_raw(struct iio_dev *indio_dev,
}
static int mma8452_get_event_regs(struct mma8452_data *data,
const struct iio_chan_spec *chan, enum iio_event_direction dir,
const struct mma8452_event_regs **ev_reg)
const struct iio_chan_spec *chan,
enum iio_event_direction dir,
const struct mma8452_event_regs **ev_reg)
{
if (!chan)
return -EINVAL;
@ -816,11 +820,11 @@ static int mma8452_get_event_regs(struct mma8452_data *data,
}
static int mma8452_read_event_value(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
enum iio_event_direction dir,
enum iio_event_info info,
int *val, int *val2)
const struct iio_chan_spec *chan,
enum iio_event_type type,
enum iio_event_direction dir,
enum iio_event_info info,
int *val, int *val2)
{
struct mma8452_data *data = iio_priv(indio_dev);
int ret, us, power_mode;
@ -879,11 +883,11 @@ static int mma8452_read_event_value(struct iio_dev *indio_dev,
}
static int mma8452_write_event_value(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
enum iio_event_type type,
enum iio_event_direction dir,
enum iio_event_info info,
int val, int val2)
const struct iio_chan_spec *chan,
enum iio_event_type type,
enum iio_event_direction dir,
enum iio_event_info info,
int val, int val2)
{
struct mma8452_data *data = iio_priv(indio_dev);
int ret, reg, steps;
@ -953,8 +957,7 @@ static int mma8452_read_event_config(struct iio_dev *indio_dev,
case IIO_EV_DIR_FALLING:
return mma8452_freefall_mode_enabled(data);
case IIO_EV_DIR_RISING:
ret = i2c_smbus_read_byte_data(data->client,
ev_regs->ev_cfg);
ret = i2c_smbus_read_byte_data(data->client, ev_regs->ev_cfg);
if (ret < 0)
return ret;
@ -1191,7 +1194,7 @@ static const struct attribute_group mma8452_event_attribute_group = {
static const struct iio_mount_matrix *
mma8452_get_mount_matrix(const struct iio_dev *indio_dev,
const struct iio_chan_spec *chan)
const struct iio_chan_spec *chan)
{
struct mma8452_data *data = iio_priv(indio_dev);
@ -1514,8 +1517,9 @@ static int mma8452_reset(struct i2c_client *client)
* The following code will read the reset register, and check whether
* this reset works.
*/
i2c_smbus_write_byte_data(client, MMA8452_CTRL_REG2,
MMA8452_CTRL_REG2_RST);
i2c_smbus_write_byte_data(client,
MMA8452_CTRL_REG2,
MMA8452_CTRL_REG2_RST);
for (i = 0; i < 10; i++) {
usleep_range(100, 200);
@ -1544,6 +1548,7 @@ MODULE_DEVICE_TABLE(of, mma8452_dt_ids);
static int mma8452_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct mma8452_data *data;
struct iio_dev *indio_dev;
int ret;
@ -1576,14 +1581,12 @@ static int mma8452_probe(struct i2c_client *client)
"failed to get VDDIO regulator!\n");
ret = regulator_enable(data->vdd_reg);
if (ret) {
dev_err(&client->dev, "failed to enable VDD regulator!\n");
return ret;
}
if (ret)
return dev_err_probe(dev, ret, "failed to enable VDD regulator!\n");
ret = regulator_enable(data->vddio_reg);
if (ret) {
dev_err(&client->dev, "failed to enable VDDIO regulator!\n");
dev_err_probe(dev, ret, "failed to enable VDDIO regulator!\n");
goto disable_regulator_vdd;
}
@ -1645,8 +1648,8 @@ static int mma8452_probe(struct i2c_client *client)
dev_dbg(&client->dev, "using interrupt line INT2\n");
} else {
ret = i2c_smbus_write_byte_data(client,
MMA8452_CTRL_REG5,
data->chip_info->all_events);
MMA8452_CTRL_REG5,
data->chip_info->all_events);
if (ret < 0)
goto disable_regulators;
@ -1654,8 +1657,8 @@ static int mma8452_probe(struct i2c_client *client)
}
ret = i2c_smbus_write_byte_data(client,
MMA8452_CTRL_REG4,
data->chip_info->enabled_events);
MMA8452_CTRL_REG4,
data->chip_info->enabled_events);
if (ret < 0)
goto disable_regulators;
@ -1680,18 +1683,16 @@ static int mma8452_probe(struct i2c_client *client)
goto trigger_cleanup;
if (client->irq) {
ret = devm_request_threaded_irq(&client->dev,
client->irq,
NULL, mma8452_interrupt,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
client->name, indio_dev);
ret = request_threaded_irq(client->irq, NULL, mma8452_interrupt,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
client->name, indio_dev);
if (ret)
goto buffer_cleanup;
}
ret = pm_runtime_set_active(&client->dev);
if (ret < 0)
goto buffer_cleanup;
goto free_irq;
pm_runtime_enable(&client->dev);
pm_runtime_set_autosuspend_delay(&client->dev,
@ -1700,7 +1701,7 @@ static int mma8452_probe(struct i2c_client *client)
ret = iio_device_register(indio_dev);
if (ret < 0)
goto buffer_cleanup;
goto free_irq;
ret = mma8452_set_freefall_mode(data, false);
if (ret < 0)
@ -1711,6 +1712,10 @@ static int mma8452_probe(struct i2c_client *client)
unregister_device:
iio_device_unregister(indio_dev);
free_irq:
if (client->irq)
free_irq(client->irq, indio_dev);
buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
@ -1736,6 +1741,9 @@ static void mma8452_remove(struct i2c_client *client)
pm_runtime_disable(&client->dev);
pm_runtime_set_suspended(&client->dev);
if (client->irq)
free_irq(client->irq, indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
mma8452_trigger_cleanup(indio_dev);
mma8452_standby(iio_priv(indio_dev));
@ -1821,12 +1829,12 @@ static const struct dev_pm_ops mma8452_pm_ops = {
};
static const struct i2c_device_id mma8452_id[] = {
{ "fxls8471", (kernel_ulong_t)&mma_chip_info_table[fxls8471] },
{ "mma8451", (kernel_ulong_t)&mma_chip_info_table[mma8451] },
{ "mma8452", (kernel_ulong_t)&mma_chip_info_table[mma8452] },
{ "mma8453", (kernel_ulong_t)&mma_chip_info_table[mma8453] },
{ "mma8652", (kernel_ulong_t)&mma_chip_info_table[mma8652] },
{ "mma8653", (kernel_ulong_t)&mma_chip_info_table[mma8653] },
{ .name = "fxls8471", .driver_data = (kernel_ulong_t)&mma_chip_info_table[fxls8471] },
{ .name = "mma8451", .driver_data = (kernel_ulong_t)&mma_chip_info_table[mma8451] },
{ .name = "mma8452", .driver_data = (kernel_ulong_t)&mma_chip_info_table[mma8452] },
{ .name = "mma8453", .driver_data = (kernel_ulong_t)&mma_chip_info_table[mma8453] },
{ .name = "mma8652", .driver_data = (kernel_ulong_t)&mma_chip_info_table[mma8652] },
{ .name = "mma8653", .driver_data = (kernel_ulong_t)&mma_chip_info_table[mma8653] },
{ }
};
MODULE_DEVICE_TABLE(i2c, mma8452_id);

View File

@ -582,7 +582,7 @@ static const struct acpi_device_id mma9551_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, mma9551_acpi_match);
static const struct i2c_device_id mma9551_id[] = {
{ "mma9551" },
{ .name = "mma9551" },
{ }
};

View File

@ -1219,7 +1219,7 @@ static const struct acpi_device_id mma9553_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, mma9553_acpi_match);
static const struct i2c_device_id mma9553_id[] = {
{ "mma9553" },
{ .name = "mma9553" },
{ }
};

View File

@ -580,8 +580,8 @@ static const struct of_device_id mxc4005_of_match[] = {
MODULE_DEVICE_TABLE(of, mxc4005_of_match);
static const struct i2c_device_id mxc4005_id[] = {
{ "mxc4005" },
{ "mxc6655" },
{ .name = "mxc4005" },
{ .name = "mxc6655" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mxc4005_id);

View File

@ -171,8 +171,8 @@ static const struct acpi_device_id mxc6255_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, mxc6255_acpi_match);
static const struct i2c_device_id mxc6255_id[] = {
{ "mxc6225" },
{ "mxc6255" },
{ .name = "mxc6225" },
{ .name = "mxc6255" },
{ }
};
MODULE_DEVICE_TABLE(i2c, mxc6255_id);

View File

@ -76,7 +76,7 @@ static const struct iio_chan_spec ssp_acc_channels[] = {
SSP_CHANNEL_AG(IIO_ACCEL, IIO_MOD_X, SSP_CHANNEL_SCAN_INDEX_X),
SSP_CHANNEL_AG(IIO_ACCEL, IIO_MOD_Y, SSP_CHANNEL_SCAN_INDEX_Y),
SSP_CHANNEL_AG(IIO_ACCEL, IIO_MOD_Z, SSP_CHANNEL_SCAN_INDEX_Z),
SSP_CHAN_TIMESTAMP(SSP_CHANNEL_SCAN_INDEX_TIME),
IIO_CHAN_SOFT_TIMESTAMP(SSP_CHANNEL_SCAN_INDEX_TIME),
};
static int ssp_process_accel_data(struct iio_dev *indio_dev, void *buf,

View File

@ -138,32 +138,32 @@ static const struct acpi_device_id st_accel_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, st_accel_acpi_match);
static const struct i2c_device_id st_accel_id_table[] = {
{ LSM303DLH_ACCEL_DEV_NAME },
{ LSM303DLHC_ACCEL_DEV_NAME },
{ LIS3DH_ACCEL_DEV_NAME },
{ LSM330D_ACCEL_DEV_NAME },
{ LSM330DL_ACCEL_DEV_NAME },
{ LSM330DLC_ACCEL_DEV_NAME },
{ LIS331DLH_ACCEL_DEV_NAME },
{ LSM303DL_ACCEL_DEV_NAME },
{ LSM303DLM_ACCEL_DEV_NAME },
{ LSM330_ACCEL_DEV_NAME },
{ LSM303AGR_ACCEL_DEV_NAME },
{ LIS2DH12_ACCEL_DEV_NAME },
{ LIS3L02DQ_ACCEL_DEV_NAME },
{ LNG2DM_ACCEL_DEV_NAME },
{ H3LIS331DL_ACCEL_DEV_NAME },
{ LIS331DL_ACCEL_DEV_NAME },
{ LIS3LV02DL_ACCEL_DEV_NAME },
{ LIS2DW12_ACCEL_DEV_NAME },
{ LIS3DE_ACCEL_DEV_NAME },
{ LIS2DE12_ACCEL_DEV_NAME },
{ LIS2DS12_ACCEL_DEV_NAME },
{ LIS2HH12_ACCEL_DEV_NAME },
{ LIS302DL_ACCEL_DEV_NAME },
{ LSM303C_ACCEL_DEV_NAME },
{ SC7A20_ACCEL_DEV_NAME },
{ IIS328DQ_ACCEL_DEV_NAME },
{ .name = LSM303DLH_ACCEL_DEV_NAME },
{ .name = LSM303DLHC_ACCEL_DEV_NAME },
{ .name = LIS3DH_ACCEL_DEV_NAME },
{ .name = LSM330D_ACCEL_DEV_NAME },
{ .name = LSM330DL_ACCEL_DEV_NAME },
{ .name = LSM330DLC_ACCEL_DEV_NAME },
{ .name = LIS331DLH_ACCEL_DEV_NAME },
{ .name = LSM303DL_ACCEL_DEV_NAME },
{ .name = LSM303DLM_ACCEL_DEV_NAME },
{ .name = LSM330_ACCEL_DEV_NAME },
{ .name = LSM303AGR_ACCEL_DEV_NAME },
{ .name = LIS2DH12_ACCEL_DEV_NAME },
{ .name = LIS3L02DQ_ACCEL_DEV_NAME },
{ .name = LNG2DM_ACCEL_DEV_NAME },
{ .name = H3LIS331DL_ACCEL_DEV_NAME },
{ .name = LIS331DL_ACCEL_DEV_NAME },
{ .name = LIS3LV02DL_ACCEL_DEV_NAME },
{ .name = LIS2DW12_ACCEL_DEV_NAME },
{ .name = LIS3DE_ACCEL_DEV_NAME },
{ .name = LIS2DE12_ACCEL_DEV_NAME },
{ .name = LIS2DS12_ACCEL_DEV_NAME },
{ .name = LIS2HH12_ACCEL_DEV_NAME },
{ .name = LIS302DL_ACCEL_DEV_NAME },
{ .name = LSM303C_ACCEL_DEV_NAME },
{ .name = SC7A20_ACCEL_DEV_NAME },
{ .name = IIS328DQ_ACCEL_DEV_NAME },
{ }
};
MODULE_DEVICE_TABLE(i2c, st_accel_id_table);

View File

@ -630,8 +630,8 @@ static DEFINE_SIMPLE_DEV_PM_OPS(stk8312_pm_ops, stk8312_suspend,
static const struct i2c_device_id stk8312_i2c_id[] = {
/* Deprecated in favour of lowercase form */
{ "STK8312" },
{ "stk8312" },
{ .name = "STK8312" },
{ .name = "stk8312" },
{ }
};
MODULE_DEVICE_TABLE(i2c, stk8312_i2c_id);

View File

@ -519,7 +519,7 @@ static DEFINE_SIMPLE_DEV_PM_OPS(stk8ba50_pm_ops, stk8ba50_suspend,
stk8ba50_resume);
static const struct i2c_device_id stk8ba50_i2c_id[] = {
{ "stk8ba50" },
{ .name = "stk8ba50" },
{ }
};
MODULE_DEVICE_TABLE(i2c, stk8ba50_i2c_id);

View File

@ -373,7 +373,7 @@ static DEFINE_RUNTIME_DEV_PM_OPS(pm886_gpadc_pm_ops,
pm886_gpadc_runtime_resume, NULL);
static const struct platform_device_id pm886_gpadc_id[] = {
{ "88pm886-gpadc" },
{ .name = "88pm886-gpadc" },
{ }
};
MODULE_DEVICE_TABLE(platform, pm886_gpadc_id);

View File

@ -144,6 +144,22 @@ config AD4170_4
To compile this driver as a module, choose M here: the module will be
called ad4170-4.
config AD4691
tristate "Analog Devices AD4691 Family ADC Driver"
depends on SPI
depends on REGULATOR || COMPILE_TEST
select IIO_BUFFER
select IIO_BUFFER_DMAENGINE
select IIO_TRIGGERED_BUFFER
select REGMAP
select SPI_OFFLOAD
help
Say yes here to build support for Analog Devices AD4691 Family MuxSAR
SPI analog to digital converters (ADC).
To compile this driver as a module, choose M here: the module will be
called ad4691.
config AD4695
tristate "Analog Device AD4695 ADC Driver"
depends on SPI
@ -1354,7 +1370,7 @@ config QCOM_SPMI_VADC
be called qcom-spmi-vadc.
config QCOM_SPMI_ADC5
tristate "Qualcomm Technologies Inc. SPMI PMIC5 ADC"
tristate "Qualcomm SPMI PMIC5 ADC"
depends on SPMI
select REGMAP_SPMI
select QCOM_VADC_COMMON
@ -1374,7 +1390,7 @@ config QCOM_SPMI_ADC5
be called qcom-spmi-adc5.
config QCOM_SPMI_ADC5_GEN3
tristate "Qualcomm Technologies Inc. SPMI PMIC5 GEN3 ADC"
tristate "Qualcomm SPMI PMIC5 GEN3 ADC"
depends on SPMI && THERMAL
select REGMAP_SPMI
select QCOM_VADC_COMMON

View File

@ -16,6 +16,7 @@ obj-$(CONFIG_AD4080) += ad4080.o
obj-$(CONFIG_AD4130) += ad4130.o
obj-$(CONFIG_AD4134) += ad4134.o
obj-$(CONFIG_AD4170_4) += ad4170-4.o
obj-$(CONFIG_AD4691) += ad4691.o
obj-$(CONFIG_AD4695) += ad4695.o
obj-$(CONFIG_AD4851) += ad4851.o
obj-$(CONFIG_AD7091R) += ad7091r-base.o

View File

@ -436,10 +436,9 @@ static int ad4062_check_ids(struct ad4062_state *st)
return ret;
val = be16_to_cpu(st->buf.be16);
if (val != AD4062_I3C_VENDOR) {
dev_err(dev, "Vendor ID x%x does not match expected value\n", val);
return -ENODEV;
}
if (val != AD4062_I3C_VENDOR)
return dev_err_probe(dev, -ENODEV,
"Vendor ID x%x does not match expected value\n", val);
return 0;
}

View File

@ -16,6 +16,7 @@
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
@ -134,6 +135,10 @@
#define AD4086_CHIP_ID 0x0056
#define AD4087_CHIP_ID 0x0057
#define AD4088_CHIP_ID 0x0058
#define AD4880_CHIP_ID 0x0059
#define AD4884_CHIP_ID 0x005C
#define AD4080_MAX_CHANNELS 2
#define AD4080_LVDS_CNV_CLK_CNT_MAX 7
@ -179,8 +184,9 @@ struct ad4080_chip_info {
};
struct ad4080_state {
struct regmap *regmap;
struct iio_backend *back;
struct spi_device *spi[AD4080_MAX_CHANNELS];
struct regmap *regmap[AD4080_MAX_CHANNELS];
struct iio_backend *back[AD4080_MAX_CHANNELS];
const struct ad4080_chip_info *info;
/*
* Synchronize access to members the of driver state, and ensure
@ -189,7 +195,7 @@ struct ad4080_state {
struct mutex lock;
unsigned int num_lanes;
unsigned long clk_rate;
enum ad4080_filter_type filter_type;
enum ad4080_filter_type filter_type[AD4080_MAX_CHANNELS];
bool lvds_cnv_en;
};
@ -206,9 +212,9 @@ static int ad4080_reg_access(struct iio_dev *indio_dev, unsigned int reg,
struct ad4080_state *st = iio_priv(indio_dev);
if (readval)
return regmap_read(st->regmap, reg, readval);
return regmap_read(st->regmap[0], reg, readval);
return regmap_write(st->regmap, reg, writeval);
return regmap_write(st->regmap[0], reg, writeval);
}
static int ad4080_get_scale(struct ad4080_state *st, int *val, int *val2)
@ -229,8 +235,9 @@ static unsigned int ad4080_get_dec_rate(struct iio_dev *dev,
struct ad4080_state *st = iio_priv(dev);
int ret;
unsigned int data;
unsigned int ch = chan->channel;
ret = regmap_read(st->regmap, AD4080_REG_FILTER_CONFIG, &data);
ret = regmap_read(st->regmap[ch], AD4080_REG_FILTER_CONFIG, &data);
if (ret)
return ret;
@ -242,13 +249,14 @@ static int ad4080_set_dec_rate(struct iio_dev *dev,
unsigned int mode)
{
struct ad4080_state *st = iio_priv(dev);
unsigned int ch = chan->channel;
guard(mutex)(&st->lock);
if ((st->filter_type >= SINC_5 && mode >= 512) || mode < 2)
if ((st->filter_type[ch] >= SINC_5 && mode >= 512) || mode < 2)
return -EINVAL;
return regmap_update_bits(st->regmap, AD4080_REG_FILTER_CONFIG,
return regmap_update_bits(st->regmap[ch], AD4080_REG_FILTER_CONFIG,
AD4080_FILTER_CONFIG_SINC_DEC_RATE_MSK,
FIELD_PREP(AD4080_FILTER_CONFIG_SINC_DEC_RATE_MSK,
(ilog2(mode) - 1)));
@ -268,15 +276,15 @@ static int ad4080_read_raw(struct iio_dev *indio_dev,
dec_rate = ad4080_get_dec_rate(indio_dev, chan);
if (dec_rate < 0)
return dec_rate;
if (st->filter_type == SINC_5_COMP)
if (st->filter_type[chan->channel] == SINC_5_COMP)
dec_rate *= 2;
if (st->filter_type)
if (st->filter_type[chan->channel])
*val = DIV_ROUND_CLOSEST(st->clk_rate, dec_rate);
else
*val = st->clk_rate;
return IIO_VAL_INT;
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
if (st->filter_type == FILTER_NONE) {
if (st->filter_type[chan->channel] == FILTER_NONE) {
*val = 1;
} else {
*val = ad4080_get_dec_rate(indio_dev, chan);
@ -297,7 +305,7 @@ static int ad4080_write_raw(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
if (st->filter_type == FILTER_NONE && val > 1)
if (st->filter_type[chan->channel] == FILTER_NONE && val > 1)
return -EINVAL;
return ad4080_set_dec_rate(indio_dev, chan, val);
@ -306,23 +314,23 @@ static int ad4080_write_raw(struct iio_dev *indio_dev,
}
}
static int ad4080_lvds_sync_write(struct ad4080_state *st)
static int ad4080_lvds_sync_write(struct ad4080_state *st, unsigned int ch)
{
struct device *dev = regmap_get_device(st->regmap);
struct device *dev = regmap_get_device(st->regmap[ch]);
int ret;
ret = regmap_set_bits(st->regmap, AD4080_REG_ADC_DATA_INTF_CONFIG_A,
ret = regmap_set_bits(st->regmap[ch], AD4080_REG_ADC_DATA_INTF_CONFIG_A,
AD4080_ADC_DATA_INTF_CONFIG_A_INTF_CHK_EN);
if (ret)
return ret;
ret = iio_backend_interface_data_align(st->back, 10000);
ret = iio_backend_interface_data_align(st->back[ch], 10000);
if (ret)
return dev_err_probe(dev, ret,
"Data alignment process failed\n");
dev_dbg(dev, "Success: Pattern correct and Locked!\n");
return regmap_clear_bits(st->regmap, AD4080_REG_ADC_DATA_INTF_CONFIG_A,
return regmap_clear_bits(st->regmap[ch], AD4080_REG_ADC_DATA_INTF_CONFIG_A,
AD4080_ADC_DATA_INTF_CONFIG_A_INTF_CHK_EN);
}
@ -331,9 +339,10 @@ static int ad4080_get_filter_type(struct iio_dev *dev,
{
struct ad4080_state *st = iio_priv(dev);
unsigned int data;
unsigned int ch = chan->channel;
int ret;
ret = regmap_read(st->regmap, AD4080_REG_FILTER_CONFIG, &data);
ret = regmap_read(st->regmap[ch], AD4080_REG_FILTER_CONFIG, &data);
if (ret)
return ret;
@ -345,6 +354,7 @@ static int ad4080_set_filter_type(struct iio_dev *dev,
unsigned int mode)
{
struct ad4080_state *st = iio_priv(dev);
unsigned int ch = chan->channel;
int dec_rate;
int ret;
@ -357,18 +367,18 @@ static int ad4080_set_filter_type(struct iio_dev *dev,
if (mode >= SINC_5 && dec_rate >= 512)
return -EINVAL;
ret = iio_backend_filter_type_set(st->back, mode);
ret = iio_backend_filter_type_set(st->back[ch], mode);
if (ret)
return ret;
ret = regmap_update_bits(st->regmap, AD4080_REG_FILTER_CONFIG,
ret = regmap_update_bits(st->regmap[ch], AD4080_REG_FILTER_CONFIG,
AD4080_FILTER_CONFIG_FILTER_SEL_MSK,
FIELD_PREP(AD4080_FILTER_CONFIG_FILTER_SEL_MSK,
mode));
if (ret)
return ret;
st->filter_type = mode;
st->filter_type[ch] = mode;
return 0;
}
@ -382,14 +392,14 @@ static int ad4080_read_avail(struct iio_dev *indio_dev,
switch (mask) {
case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
switch (st->filter_type) {
switch (st->filter_type[chan->channel]) {
case FILTER_NONE:
*vals = ad4080_dec_rate_none;
*length = ARRAY_SIZE(ad4080_dec_rate_none);
break;
default:
*vals = ad4080_dec_rate_avail;
*length = st->filter_type >= SINC_5 ?
*length = st->filter_type[chan->channel] >= SINC_5 ?
(ARRAY_SIZE(ad4080_dec_rate_avail) - 2) :
ARRAY_SIZE(ad4080_dec_rate_avail);
break;
@ -401,6 +411,28 @@ static int ad4080_read_avail(struct iio_dev *indio_dev,
}
}
static int ad4880_update_scan_mode(struct iio_dev *indio_dev,
const unsigned long *scan_mask)
{
struct ad4080_state *st = iio_priv(indio_dev);
int ret;
for (unsigned int ch = 0; ch < st->info->num_channels; ch++) {
/*
* Each backend has a single channel (channel 0 from the
* backend's perspective), so always use channel index 0.
*/
if (test_bit(ch, scan_mask))
ret = iio_backend_chan_enable(st->back[ch], 0);
else
ret = iio_backend_chan_disable(st->back[ch], 0);
if (ret)
return ret;
}
return 0;
}
static const struct iio_info ad4080_iio_info = {
.debugfs_reg_access = ad4080_reg_access,
.read_raw = ad4080_read_raw,
@ -408,6 +440,19 @@ static const struct iio_info ad4080_iio_info = {
.read_avail = ad4080_read_avail,
};
/*
* AD4880 needs update_scan_mode to enable/disable individual backend channels.
* Single-channel devices don't need this as their backends may not implement
* chan_enable/chan_disable operations.
*/
static const struct iio_info ad4880_iio_info = {
.debugfs_reg_access = ad4080_reg_access,
.read_raw = ad4080_read_raw,
.write_raw = ad4080_write_raw,
.read_avail = ad4080_read_avail,
.update_scan_mode = ad4880_update_scan_mode,
};
static const struct iio_enum ad4080_filter_type_enum = {
.items = ad4080_filter_type_iio_enum,
.num_items = ARRAY_SIZE(ad4080_filter_type_iio_enum),
@ -422,17 +467,28 @@ static struct iio_chan_spec_ext_info ad4080_ext_info[] = {
{ }
};
#define AD4080_CHANNEL_DEFINE(bits, storage) { \
/*
* AD4880 needs per-channel filter configuration since each channel has
* its own independent ADC with separate SPI interface.
*/
static struct iio_chan_spec_ext_info ad4880_ext_info[] = {
IIO_ENUM("filter_type", IIO_SEPARATE, &ad4080_filter_type_enum),
IIO_ENUM_AVAILABLE("filter_type", IIO_SEPARATE,
&ad4080_filter_type_enum),
{ }
};
#define AD4080_CHANNEL_DEFINE(bits, storage, idx) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = 0, \
.channel = (idx), \
.info_mask_separate = BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
.info_mask_shared_by_all_available = \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
.ext_info = ad4080_ext_info, \
.scan_index = 0, \
.scan_index = (idx), \
.scan_type = { \
.sign = 's', \
.realbits = (bits), \
@ -440,23 +496,56 @@ static struct iio_chan_spec_ext_info ad4080_ext_info[] = {
}, \
}
static const struct iio_chan_spec ad4080_channel = AD4080_CHANNEL_DEFINE(20, 32);
/*
* AD4880 has per-channel attributes (filter_type, oversampling_ratio,
* sampling_frequency) since each channel has its own independent ADC
* with separate SPI configuration interface.
*/
#define AD4880_CHANNEL_DEFINE(bits, storage, idx) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = (idx), \
.info_mask_separate = BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
.info_mask_separate_available = \
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
.ext_info = ad4880_ext_info, \
.scan_index = (idx), \
.scan_type = { \
.sign = 's', \
.realbits = (bits), \
.storagebits = (storage), \
}, \
}
static const struct iio_chan_spec ad4081_channel = AD4080_CHANNEL_DEFINE(20, 32);
static const struct iio_chan_spec ad4080_channel = AD4080_CHANNEL_DEFINE(20, 32, 0);
static const struct iio_chan_spec ad4082_channel = AD4080_CHANNEL_DEFINE(20, 32);
static const struct iio_chan_spec ad4081_channel = AD4080_CHANNEL_DEFINE(20, 32, 0);
static const struct iio_chan_spec ad4083_channel = AD4080_CHANNEL_DEFINE(16, 16);
static const struct iio_chan_spec ad4082_channel = AD4080_CHANNEL_DEFINE(20, 32, 0);
static const struct iio_chan_spec ad4084_channel = AD4080_CHANNEL_DEFINE(16, 16);
static const struct iio_chan_spec ad4083_channel = AD4080_CHANNEL_DEFINE(16, 16, 0);
static const struct iio_chan_spec ad4085_channel = AD4080_CHANNEL_DEFINE(16, 16);
static const struct iio_chan_spec ad4084_channel = AD4080_CHANNEL_DEFINE(16, 16, 0);
static const struct iio_chan_spec ad4086_channel = AD4080_CHANNEL_DEFINE(14, 16);
static const struct iio_chan_spec ad4085_channel = AD4080_CHANNEL_DEFINE(16, 16, 0);
static const struct iio_chan_spec ad4087_channel = AD4080_CHANNEL_DEFINE(14, 16);
static const struct iio_chan_spec ad4086_channel = AD4080_CHANNEL_DEFINE(14, 16, 0);
static const struct iio_chan_spec ad4088_channel = AD4080_CHANNEL_DEFINE(14, 16);
static const struct iio_chan_spec ad4087_channel = AD4080_CHANNEL_DEFINE(14, 16, 0);
static const struct iio_chan_spec ad4088_channel = AD4080_CHANNEL_DEFINE(14, 16, 0);
static const struct iio_chan_spec ad4880_channels[] = {
AD4880_CHANNEL_DEFINE(20, 32, 0),
AD4880_CHANNEL_DEFINE(20, 32, 1),
};
static const struct iio_chan_spec ad4884_channels[] = {
AD4880_CHANNEL_DEFINE(16, 16, 0),
AD4880_CHANNEL_DEFINE(16, 16, 1),
};
static const struct ad4080_chip_info ad4080_chip_info = {
.name = "ad4080",
@ -548,25 +637,44 @@ static const struct ad4080_chip_info ad4088_chip_info = {
.lvds_cnv_clk_cnt_max = 8,
};
static int ad4080_setup(struct iio_dev *indio_dev)
static const struct ad4080_chip_info ad4880_chip_info = {
.name = "ad4880",
.product_id = AD4880_CHIP_ID,
.scale_table = ad4080_scale_table,
.num_scales = ARRAY_SIZE(ad4080_scale_table),
.num_channels = 2,
.channels = ad4880_channels,
.lvds_cnv_clk_cnt_max = AD4080_LVDS_CNV_CLK_CNT_MAX,
};
static const struct ad4080_chip_info ad4884_chip_info = {
.name = "ad4884",
.product_id = AD4884_CHIP_ID,
.scale_table = ad4080_scale_table,
.num_scales = ARRAY_SIZE(ad4080_scale_table),
.num_channels = 2,
.channels = ad4884_channels,
.lvds_cnv_clk_cnt_max = 2,
};
static int ad4080_setup_channel(struct ad4080_state *st, unsigned int ch)
{
struct ad4080_state *st = iio_priv(indio_dev);
struct device *dev = regmap_get_device(st->regmap);
struct device *dev = regmap_get_device(st->regmap[ch]);
__le16 id_le;
u16 id;
int ret;
ret = regmap_write(st->regmap, AD4080_REG_INTERFACE_CONFIG_A,
ret = regmap_write(st->regmap[ch], AD4080_REG_INTERFACE_CONFIG_A,
AD4080_INTERFACE_CONFIG_A_SW_RESET);
if (ret)
return ret;
ret = regmap_write(st->regmap, AD4080_REG_INTERFACE_CONFIG_A,
ret = regmap_write(st->regmap[ch], AD4080_REG_INTERFACE_CONFIG_A,
AD4080_INTERFACE_CONFIG_A_SDO_ENABLE);
if (ret)
return ret;
ret = regmap_bulk_read(st->regmap, AD4080_REG_PRODUCT_ID_L, &id_le,
ret = regmap_bulk_read(st->regmap[ch], AD4080_REG_PRODUCT_ID_L, &id_le,
sizeof(id_le));
if (ret)
return ret;
@ -575,18 +683,18 @@ static int ad4080_setup(struct iio_dev *indio_dev)
if (id != st->info->product_id)
dev_info(dev, "Unrecognized CHIP_ID 0x%X\n", id);
ret = regmap_set_bits(st->regmap, AD4080_REG_GPIO_CONFIG_A,
ret = regmap_set_bits(st->regmap[ch], AD4080_REG_GPIO_CONFIG_A,
AD4080_GPIO_CONFIG_A_GPO_1_EN);
if (ret)
return ret;
ret = regmap_write(st->regmap, AD4080_REG_GPIO_CONFIG_B,
ret = regmap_write(st->regmap[ch], AD4080_REG_GPIO_CONFIG_B,
FIELD_PREP(AD4080_GPIO_CONFIG_B_GPIO_1_SEL_MSK,
AD4080_GPIO_CONFIG_B_GPIO_FILTER_RES_RDY));
if (ret)
return ret;
ret = iio_backend_num_lanes_set(st->back, st->num_lanes);
ret = iio_backend_num_lanes_set(st->back[ch], st->num_lanes);
if (ret)
return ret;
@ -594,7 +702,7 @@ static int ad4080_setup(struct iio_dev *indio_dev)
return 0;
/* Set maximum LVDS Data Transfer Latency */
ret = regmap_update_bits(st->regmap,
ret = regmap_update_bits(st->regmap[ch],
AD4080_REG_ADC_DATA_INTF_CONFIG_B,
AD4080_ADC_DATA_INTF_CONFIG_B_LVDS_CNV_CLK_CNT_MSK,
FIELD_PREP(AD4080_ADC_DATA_INTF_CONFIG_B_LVDS_CNV_CLK_CNT_MSK,
@ -603,24 +711,38 @@ static int ad4080_setup(struct iio_dev *indio_dev)
return ret;
if (st->num_lanes > 1) {
ret = regmap_set_bits(st->regmap, AD4080_REG_ADC_DATA_INTF_CONFIG_A,
ret = regmap_set_bits(st->regmap[ch], AD4080_REG_ADC_DATA_INTF_CONFIG_A,
AD4080_ADC_DATA_INTF_CONFIG_A_SPI_LVDS_LANES);
if (ret)
return ret;
}
ret = regmap_set_bits(st->regmap,
ret = regmap_set_bits(st->regmap[ch],
AD4080_REG_ADC_DATA_INTF_CONFIG_B,
AD4080_ADC_DATA_INTF_CONFIG_B_LVDS_CNV_EN);
if (ret)
return ret;
return ad4080_lvds_sync_write(st);
return ad4080_lvds_sync_write(st, ch);
}
static int ad4080_properties_parse(struct ad4080_state *st)
static int ad4080_setup(struct iio_dev *indio_dev)
{
struct ad4080_state *st = iio_priv(indio_dev);
int ret;
for (unsigned int ch = 0; ch < st->info->num_channels; ch++) {
ret = ad4080_setup_channel(st, ch);
if (ret)
return ret;
}
return 0;
}
static int ad4080_properties_parse(struct ad4080_state *st,
struct device *dev)
{
struct device *dev = regmap_get_device(st->regmap);
st->lvds_cnv_en = device_property_read_bool(dev, "adi,lvds-cnv-enable");
@ -655,14 +777,28 @@ static int ad4080_probe(struct spi_device *spi)
return dev_err_probe(dev, ret,
"failed to get and enable supplies\n");
st->regmap = devm_regmap_init_spi(spi, &ad4080_regmap_config);
if (IS_ERR(st->regmap))
return PTR_ERR(st->regmap);
/* Setup primary SPI device (channel 0) */
st->spi[0] = spi;
st->regmap[0] = devm_regmap_init_spi(spi, &ad4080_regmap_config);
if (IS_ERR(st->regmap[0]))
return PTR_ERR(st->regmap[0]);
st->info = spi_get_device_match_data(spi);
if (!st->info)
return -ENODEV;
/* Setup ancillary SPI devices for additional channels */
for (unsigned int ch = 1; ch < st->info->num_channels; ch++) {
st->spi[ch] = devm_spi_new_ancillary_device(spi, spi_get_chipselect(spi, ch));
if (IS_ERR(st->spi[ch]))
return dev_err_probe(dev, PTR_ERR(st->spi[ch]),
"failed to register ancillary device\n");
st->regmap[ch] = devm_regmap_init_spi(st->spi[ch], &ad4080_regmap_config);
if (IS_ERR(st->regmap[ch]))
return PTR_ERR(st->regmap[ch]);
}
ret = devm_mutex_init(dev, &st->lock);
if (ret)
return ret;
@ -670,9 +806,10 @@ static int ad4080_probe(struct spi_device *spi)
indio_dev->name = st->info->name;
indio_dev->channels = st->info->channels;
indio_dev->num_channels = st->info->num_channels;
indio_dev->info = &ad4080_iio_info;
indio_dev->info = st->info->num_channels > 1 ?
&ad4880_iio_info : &ad4080_iio_info;
ret = ad4080_properties_parse(st);
ret = ad4080_properties_parse(st, dev);
if (ret)
return ret;
@ -682,15 +819,25 @@ static int ad4080_probe(struct spi_device *spi)
st->clk_rate = clk_get_rate(clk);
st->back = devm_iio_backend_get(dev, NULL);
if (IS_ERR(st->back))
return PTR_ERR(st->back);
/* Get backends for all channels */
for (unsigned int ch = 0; ch < st->info->num_channels; ch++) {
st->back[ch] = devm_iio_backend_get_by_index(dev, ch);
if (IS_ERR(st->back[ch]))
return PTR_ERR(st->back[ch]);
ret = devm_iio_backend_request_buffer(dev, st->back, indio_dev);
if (ret)
return ret;
ret = devm_iio_backend_enable(dev, st->back[ch]);
if (ret)
return ret;
}
ret = devm_iio_backend_enable(dev, st->back);
/*
* Request buffer from the first backend only. For multi-channel
* devices (e.g., AD4880), the FPGA uses two axi_ad408x IP instances
* (one per ADC channel) whose outputs are combined by a packer block
* that interleaves all channel data into a single DMA stream routed
* through the first backend's clock domain.
*/
ret = devm_iio_backend_request_buffer(dev, st->back[0], indio_dev);
if (ret)
return ret;
@ -711,6 +858,8 @@ static const struct spi_device_id ad4080_id[] = {
{ "ad4086", (kernel_ulong_t)&ad4086_chip_info },
{ "ad4087", (kernel_ulong_t)&ad4087_chip_info },
{ "ad4088", (kernel_ulong_t)&ad4088_chip_info },
{ "ad4880", (kernel_ulong_t)&ad4880_chip_info },
{ "ad4884", (kernel_ulong_t)&ad4884_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ad4080_id);
@ -725,6 +874,8 @@ static const struct of_device_id ad4080_of_match[] = {
{ .compatible = "adi,ad4086", &ad4086_chip_info },
{ .compatible = "adi,ad4087", &ad4087_chip_info },
{ .compatible = "adi,ad4088", &ad4088_chip_info },
{ .compatible = "adi,ad4880", &ad4880_chip_info },
{ .compatible = "adi,ad4884", &ad4884_chip_info },
{ }
};
MODULE_DEVICE_TABLE(of, ad4080_of_match);

View File

@ -9,6 +9,7 @@
#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/err.h>
@ -21,6 +22,7 @@
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/spi/spi.h>
#include <linux/types.h>
#include <linux/units.h>
#include <asm/div64.h>
@ -30,6 +32,9 @@
#include <linux/iio/iio.h>
#include <linux/iio/kfifo_buf.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/trigger.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#define AD4130_NAME "ad4130"
@ -40,6 +45,7 @@
#define AD4130_ADC_CONTROL_REG 0x01
#define AD4130_ADC_CONTROL_BIPOLAR_MASK BIT(14)
#define AD4130_ADC_CONTROL_INT_REF_VAL_MASK BIT(13)
#define AD4130_ADC_CONTROL_CONT_READ_MASK BIT(11)
#define AD4130_INT_REF_2_5V 2500000
#define AD4130_INT_REF_1_25V 1250000
#define AD4130_ADC_CONTROL_CSB_EN_MASK BIT(9)
@ -54,7 +60,9 @@
#define AD4130_IO_CONTROL_REG 0x03
#define AD4130_IO_CONTROL_INT_PIN_SEL_MASK GENMASK(9, 8)
#define AD4130_IO_CONTROL_GPIO_DATA_MASK GENMASK(7, 4)
#define AD4130_4_IO_CONTROL_GPIO_DATA_MASK GENMASK(7, 6)
#define AD4130_IO_CONTROL_GPIO_CTRL_MASK GENMASK(3, 0)
#define AD4130_4_IO_CONTROL_GPIO_CTRL_MASK GENMASK(3, 2)
#define AD4130_VBIAS_REG 0x04
@ -125,6 +133,28 @@
#define AD4130_INVALID_SLOT -1
static const unsigned int ad4129_reg_size[] = {
[AD4130_STATUS_REG] = 1,
[AD4130_ADC_CONTROL_REG] = 2,
[AD4130_DATA_REG] = 2,
[AD4130_IO_CONTROL_REG] = 2,
[AD4130_VBIAS_REG] = 2,
[AD4130_ID_REG] = 1,
[AD4130_ERROR_REG] = 2,
[AD4130_ERROR_EN_REG] = 2,
[AD4130_MCLK_COUNT_REG] = 1,
[AD4130_CHANNEL_X_REG(0) ... AD4130_CHANNEL_X_REG(AD4130_MAX_CHANNELS - 1)] = 3,
[AD4130_CONFIG_X_REG(0) ... AD4130_CONFIG_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
[AD4130_FILTER_X_REG(0) ... AD4130_FILTER_X_REG(AD4130_MAX_SETUPS - 1)] = 3,
[AD4130_OFFSET_X_REG(0) ... AD4130_OFFSET_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
[AD4130_GAIN_X_REG(0) ... AD4130_GAIN_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
[AD4130_MISC_REG] = 2,
[AD4130_FIFO_CONTROL_REG] = 3,
[AD4130_FIFO_STATUS_REG] = 1,
[AD4130_FIFO_THRESHOLD_REG] = 3,
[AD4130_FIFO_DATA_REG] = 2,
};
static const unsigned int ad4130_reg_size[] = {
[AD4130_STATUS_REG] = 1,
[AD4130_ADC_CONTROL_REG] = 2,
@ -147,6 +177,24 @@ static const unsigned int ad4130_reg_size[] = {
[AD4130_FIFO_DATA_REG] = 3,
};
static const unsigned int ad4131_reg_size[] = {
[AD4130_STATUS_REG] = 1,
[AD4130_ADC_CONTROL_REG] = 2,
[AD4130_DATA_REG] = 2,
[AD4130_IO_CONTROL_REG] = 2,
[AD4130_VBIAS_REG] = 2,
[AD4130_ID_REG] = 1,
[AD4130_ERROR_REG] = 2,
[AD4130_ERROR_EN_REG] = 2,
[AD4130_MCLK_COUNT_REG] = 1,
[AD4130_CHANNEL_X_REG(0) ... AD4130_CHANNEL_X_REG(AD4130_MAX_CHANNELS - 1)] = 3,
[AD4130_CONFIG_X_REG(0) ... AD4130_CONFIG_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
[AD4130_FILTER_X_REG(0) ... AD4130_FILTER_X_REG(AD4130_MAX_SETUPS - 1)] = 3,
[AD4130_OFFSET_X_REG(0) ... AD4130_OFFSET_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
[AD4130_GAIN_X_REG(0) ... AD4130_GAIN_X_REG(AD4130_MAX_SETUPS - 1)] = 2,
[AD4130_MISC_REG] = 2,
};
enum ad4130_int_ref_val {
AD4130_INT_REF_VAL_2_5V,
AD4130_INT_REF_VAL_1_25V,
@ -224,6 +272,28 @@ enum ad4130_pin_function {
AD4130_PIN_FN_VBIAS = BIT(3),
};
/* Pin mapping for AIN0..AIN7, VBIAS_0..VBIAS_7 */
static const u8 ad4130_4_pin_map[] = {
0x00, 0x01, 0x04, 0x05, 0x0A, 0x0B, 0x0E, 0x0F, /* 0 - 7 */
};
/* Pin mapping for AIN0..AIN15, VBIAS_0..VBIAS_15 */
static const u8 ad4130_8_pin_map[] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0 - 7 */
0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, /* 8 - 15 */
};
struct ad4130_chip_info {
const char *name;
unsigned int max_analog_pins;
unsigned int num_gpios;
const struct iio_info *info;
const unsigned int *reg_size;
const unsigned int reg_size_length;
const u8 *pin_map;
bool has_fifo;
};
/*
* If you make adaptations in this struct, you most likely also have to adapt
* ad4130_setup_info_eq(), too.
@ -268,6 +338,7 @@ struct ad4130_state {
struct regmap *regmap;
struct spi_device *spi;
struct clk *mclk;
const struct ad4130_chip_info *chip_info;
struct regulator_bulk_data regulators[4];
u32 irq_trigger;
u32 inv_irq_trigger;
@ -294,6 +365,7 @@ struct ad4130_state {
u32 mclk_sel;
bool int_ref_en;
bool bipolar;
bool buffer_wait_for_irq;
unsigned int num_enabled_channels;
unsigned int effective_watermark;
@ -301,6 +373,7 @@ struct ad4130_state {
struct spi_message fifo_msg;
struct spi_transfer fifo_xfer[2];
struct iio_trigger *trig;
/*
* DMA (thus cache coherency maintenance) requires any transfer
@ -312,9 +385,13 @@ struct ad4130_state {
u8 reg_write_tx_buf[4];
u8 reg_read_tx_buf[1];
u8 reg_read_rx_buf[3];
u8 fifo_tx_buf[2];
u8 fifo_rx_buf[AD4130_FIFO_SIZE *
AD4130_FIFO_MAX_SAMPLE_SIZE];
union {
struct {
u8 fifo_tx_buf[2];
u8 fifo_rx_buf[AD4130_FIFO_SIZE * AD4130_FIFO_MAX_SAMPLE_SIZE];
};
IIO_DECLARE_BUFFER_WITH_TS(u32, scan_channels, AD4130_MAX_CHANNELS);
};
};
static const char * const ad4130_int_pin_names[] = {
@ -394,10 +471,10 @@ static const char * const ad4130_filter_types_str[] = {
static int ad4130_get_reg_size(struct ad4130_state *st, unsigned int reg,
unsigned int *size)
{
if (reg >= ARRAY_SIZE(ad4130_reg_size))
if (reg >= st->chip_info->reg_size_length)
return -EINVAL;
*size = ad4130_reg_size[reg];
*size = st->chip_info->reg_size[reg];
return 0;
}
@ -505,7 +582,8 @@ static int ad4130_gpio_init_valid_mask(struct gpio_chip *gc,
/*
* Output-only GPIO functionality is available on pins AIN2 through
* AIN5. If these pins are used for anything else, do not expose them.
* AIN5 for some parts and AIN2 through AIN3 for others. If these pins
* are used for anything else, do not expose them.
*/
for (i = 0; i < ngpios; i++) {
unsigned int pin = i + AD4130_AIN2_P1;
@ -526,8 +604,14 @@ static int ad4130_gpio_set(struct gpio_chip *gc, unsigned int offset,
int value)
{
struct ad4130_state *st = gpiochip_get_data(gc);
unsigned int mask = FIELD_PREP(AD4130_IO_CONTROL_GPIO_DATA_MASK,
BIT(offset));
unsigned int mask;
if (st->chip_info->num_gpios == AD4130_MAX_GPIOS)
mask = FIELD_PREP(AD4130_IO_CONTROL_GPIO_DATA_MASK,
BIT(offset));
else
mask = FIELD_PREP(AD4130_4_IO_CONTROL_GPIO_DATA_MASK,
BIT(offset));
return regmap_update_bits(st->regmap, AD4130_IO_CONTROL_REG, mask,
value ? mask : 0);
@ -588,10 +672,43 @@ static irqreturn_t ad4130_irq_handler(int irq, void *private)
struct iio_dev *indio_dev = private;
struct ad4130_state *st = iio_priv(indio_dev);
if (iio_buffer_enabled(indio_dev))
ad4130_push_fifo_data(indio_dev);
else
if (iio_buffer_enabled(indio_dev)) {
if (st->chip_info->has_fifo)
ad4130_push_fifo_data(indio_dev);
else if (st->buffer_wait_for_irq)
complete(&st->completion);
else
iio_trigger_poll(st->trig);
} else {
complete(&st->completion);
}
return IRQ_HANDLED;
}
static irqreturn_t ad4130_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ad4130_state *st = iio_priv(indio_dev);
unsigned int data_reg_size = ad4130_data_reg_size(st);
struct spi_transfer xfer = { };
unsigned int num_en_chn;
int ret;
num_en_chn = bitmap_weight(indio_dev->active_scan_mask,
iio_get_masklength(indio_dev));
xfer.rx_buf = st->scan_channels;
xfer.len = data_reg_size * num_en_chn;
ret = spi_sync_transfer(st->spi, &xfer, 1);
if (ret < 0)
goto err_out;
iio_push_to_buffers_with_timestamp(indio_dev, &st->scan_channels,
iio_get_time_ns(indio_dev));
err_out:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
@ -1291,6 +1408,79 @@ static const struct iio_info ad4130_info = {
.debugfs_reg_access = ad4130_reg_access,
};
static const struct iio_info ad4131_info = {
.read_raw = ad4130_read_raw,
.read_avail = ad4130_read_avail,
.write_raw_get_fmt = ad4130_write_raw_get_fmt,
.write_raw = ad4130_write_raw,
.update_scan_mode = ad4130_update_scan_mode,
.debugfs_reg_access = ad4130_reg_access,
};
static const struct ad4130_chip_info ad4129_4_chip_info = {
.name = "ad4129-4",
.max_analog_pins = 8,
.num_gpios = 2,
.info = &ad4130_info,
.reg_size = ad4129_reg_size,
.reg_size_length = ARRAY_SIZE(ad4129_reg_size),
.has_fifo = true,
.pin_map = ad4130_4_pin_map,
};
static const struct ad4130_chip_info ad4129_8_chip_info = {
.name = "ad4129-8",
.max_analog_pins = 16,
.num_gpios = 4,
.info = &ad4130_info,
.reg_size = ad4129_reg_size,
.reg_size_length = ARRAY_SIZE(ad4129_reg_size),
.has_fifo = true,
.pin_map = ad4130_8_pin_map,
};
static const struct ad4130_chip_info ad4130_4_chip_info = {
.name = "ad4130-4",
.max_analog_pins = 16,
.num_gpios = 2,
.info = &ad4130_info,
.reg_size = ad4130_reg_size,
.reg_size_length = ARRAY_SIZE(ad4130_reg_size),
.has_fifo = true,
.pin_map = ad4130_4_pin_map,
};
static const struct ad4130_chip_info ad4130_8_chip_info = {
.name = "ad4130-8",
.max_analog_pins = 16,
.num_gpios = 4,
.info = &ad4130_info,
.reg_size = ad4130_reg_size,
.reg_size_length = ARRAY_SIZE(ad4130_reg_size),
.has_fifo = true,
.pin_map = ad4130_8_pin_map,
};
static const struct ad4130_chip_info ad4131_4_chip_info = {
.name = "ad4131-4",
.max_analog_pins = 8,
.num_gpios = 2,
.info = &ad4131_info,
.reg_size = ad4131_reg_size,
.reg_size_length = ARRAY_SIZE(ad4131_reg_size),
.pin_map = ad4130_4_pin_map,
};
static const struct ad4130_chip_info ad4131_8_chip_info = {
.name = "ad4131-8",
.max_analog_pins = 16,
.num_gpios = 4,
.info = &ad4131_info,
.reg_size = ad4131_reg_size,
.reg_size_length = ARRAY_SIZE(ad4131_reg_size),
.pin_map = ad4130_8_pin_map,
};
static int ad4130_buffer_postenable(struct iio_dev *indio_dev)
{
struct ad4130_state *st = iio_priv(indio_dev);
@ -1298,44 +1488,89 @@ static int ad4130_buffer_postenable(struct iio_dev *indio_dev)
guard(mutex)(&st->lock);
ret = ad4130_set_watermark_interrupt_en(st, true);
if (st->chip_info->has_fifo) {
ret = ad4130_set_watermark_interrupt_en(st, true);
if (ret)
return ret;
ret = irq_set_irq_type(st->spi->irq, st->inv_irq_trigger);
if (ret)
return ret;
ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_WM);
if (ret)
return ret;
}
ret = ad4130_set_mode(st, AD4130_MODE_CONTINUOUS);
if (ret)
return ret;
ret = irq_set_irq_type(st->spi->irq, st->inv_irq_trigger);
if (ret)
return ret;
/*
* When using triggered buffer, Entering continuous read mode must
* be the last command sent. No configuration changes are allowed until
* exiting this mode.
*/
if (!st->chip_info->has_fifo) {
ret = regmap_update_bits(st->regmap, AD4130_ADC_CONTROL_REG,
AD4130_ADC_CONTROL_CONT_READ_MASK,
FIELD_PREP(AD4130_ADC_CONTROL_CONT_READ_MASK, 1));
if (ret)
return ret;
}
ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_WM);
if (ret)
return ret;
return ad4130_set_mode(st, AD4130_MODE_CONTINUOUS);
return 0;
}
static int ad4130_buffer_predisable(struct iio_dev *indio_dev)
{
struct ad4130_state *st = iio_priv(indio_dev);
unsigned int i;
u32 temp;
int ret;
guard(mutex)(&st->lock);
if (!st->chip_info->has_fifo) {
temp = 0x42;
reinit_completion(&st->completion);
/*
* In continuous read mode, when all samples are read, the data
* ready signal returns high until the next conversion result is
* ready. To exit this mode, the command must be sent when data
* ready is low. In order to ensure that condition, wait for the
* next interrupt (when the new conversion is finished), allowing
* data ready to return low before sending the exit command.
*/
st->buffer_wait_for_irq = true;
if (!wait_for_completion_timeout(&st->completion, msecs_to_jiffies(1000)))
dev_warn(&st->spi->dev, "Conversion timed out\n");
st->buffer_wait_for_irq = false;
/* Perform a read data command to exit continuous read mode (0x42) */
ret = spi_write(st->spi, &temp, 1);
if (ret)
return ret;
}
ret = ad4130_set_mode(st, AD4130_MODE_IDLE);
if (ret)
return ret;
ret = irq_set_irq_type(st->spi->irq, st->irq_trigger);
if (ret)
return ret;
if (st->chip_info->has_fifo) {
ret = irq_set_irq_type(st->spi->irq, st->irq_trigger);
if (ret)
return ret;
ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_DISABLED);
if (ret)
return ret;
ret = ad4130_set_fifo_mode(st, AD4130_FIFO_MODE_DISABLED);
if (ret)
return ret;
ret = ad4130_set_watermark_interrupt_en(st, false);
if (ret)
return ret;
ret = ad4130_set_watermark_interrupt_en(st, false);
if (ret)
return ret;
}
/*
* update_scan_mode() is not called in the disable path, disable all
@ -1410,6 +1645,34 @@ static const struct iio_dev_attr *ad4130_fifo_attributes[] = {
NULL
};
static const struct iio_trigger_ops ad4130_trigger_ops = {
.validate_device = iio_trigger_validate_own_device,
};
static int ad4130_triggered_buffer_setup(struct iio_dev *indio_dev)
{
struct ad4130_state *st = iio_priv(indio_dev);
int ret;
st->trig = devm_iio_trigger_alloc(indio_dev->dev.parent, "%s-dev%d",
indio_dev->name, iio_device_id(indio_dev));
if (!st->trig)
return -ENOMEM;
st->trig->ops = &ad4130_trigger_ops;
iio_trigger_set_drvdata(st->trig, indio_dev);
ret = devm_iio_trigger_register(indio_dev->dev.parent, st->trig);
if (ret)
return ret;
indio_dev->trig = iio_trigger_get(st->trig);
return devm_iio_triggered_buffer_setup(indio_dev->dev.parent, indio_dev,
&iio_pollfunc_store_time,
&ad4130_trigger_handler,
&ad4130_buffer_ops);
}
static int _ad4130_find_table_index(const unsigned int *tbl, size_t len,
unsigned int val)
{
@ -1496,6 +1759,17 @@ static int ad4130_parse_fw_setup(struct ad4130_state *st,
return 0;
}
static unsigned int ad4130_translate_pin(struct ad4130_state *st,
unsigned int logical_pin)
{
/* For analog input pins, use the chip-specific pin mapping */
if (logical_pin < st->chip_info->max_analog_pins)
return st->chip_info->pin_map[logical_pin];
/* For internal channels, pass through unchanged */
return logical_pin;
}
static int ad4130_validate_diff_channel(struct ad4130_state *st, u32 pin)
{
struct device *dev = &st->spi->dev;
@ -1504,7 +1778,7 @@ static int ad4130_validate_diff_channel(struct ad4130_state *st, u32 pin)
return dev_err_probe(dev, -EINVAL,
"Invalid differential channel %u\n", pin);
if (pin >= AD4130_MAX_ANALOG_PINS)
if (pin >= st->chip_info->max_analog_pins)
return 0;
if (st->pins_fn[pin] == AD4130_PIN_FN_SPECIAL)
@ -1536,7 +1810,7 @@ static int ad4130_validate_excitation_pin(struct ad4130_state *st, u32 pin)
{
struct device *dev = &st->spi->dev;
if (pin >= AD4130_MAX_ANALOG_PINS)
if (pin >= st->chip_info->max_analog_pins)
return dev_err_probe(dev, -EINVAL,
"Invalid excitation pin %u\n", pin);
@ -1554,7 +1828,7 @@ static int ad4130_validate_vbias_pin(struct ad4130_state *st, u32 pin)
{
struct device *dev = &st->spi->dev;
if (pin >= AD4130_MAX_ANALOG_PINS)
if (pin >= st->chip_info->max_analog_pins)
return dev_err_probe(dev, -EINVAL, "Invalid vbias pin %u\n",
pin);
@ -1730,7 +2004,7 @@ static int ad4310_parse_fw(struct iio_dev *indio_dev)
ret = device_property_count_u32(dev, "adi,vbias-pins");
if (ret > 0) {
if (ret > AD4130_MAX_ANALOG_PINS)
if (ret > st->chip_info->max_analog_pins)
return dev_err_probe(dev, -EINVAL,
"Too many vbias pins %u\n", ret);
@ -1914,9 +2188,14 @@ static int ad4130_setup(struct iio_dev *indio_dev)
* function of P2 takes priority over the GPIO out function.
*/
val = 0;
for (i = 0; i < AD4130_MAX_GPIOS; i++)
if (st->pins_fn[i + AD4130_AIN2_P1] == AD4130_PIN_FN_NONE)
val |= FIELD_PREP(AD4130_IO_CONTROL_GPIO_CTRL_MASK, BIT(i));
for (i = 0; i < st->chip_info->num_gpios; i++) {
if (st->pins_fn[i + AD4130_AIN2_P1] == AD4130_PIN_FN_NONE) {
if (st->chip_info->num_gpios == 2)
val |= FIELD_PREP(AD4130_4_IO_CONTROL_GPIO_CTRL_MASK, BIT(i));
else
val |= FIELD_PREP(AD4130_IO_CONTROL_GPIO_CTRL_MASK, BIT(i));
}
}
val |= FIELD_PREP(AD4130_IO_CONTROL_INT_PIN_SEL_MASK, st->int_pin_sel);
@ -1926,21 +2205,23 @@ static int ad4130_setup(struct iio_dev *indio_dev)
val = 0;
for (i = 0; i < st->num_vbias_pins; i++)
val |= BIT(st->vbias_pins[i]);
val |= BIT(ad4130_translate_pin(st, st->vbias_pins[i]));
ret = regmap_write(st->regmap, AD4130_VBIAS_REG, val);
if (ret)
return ret;
ret = regmap_clear_bits(st->regmap, AD4130_FIFO_CONTROL_REG,
AD4130_FIFO_CONTROL_HEADER_MASK);
if (ret)
return ret;
if (st->chip_info->has_fifo) {
ret = regmap_clear_bits(st->regmap, AD4130_FIFO_CONTROL_REG,
AD4130_FIFO_CONTROL_HEADER_MASK);
if (ret)
return ret;
/* FIFO watermark interrupt starts out as enabled, disable it. */
ret = ad4130_set_watermark_interrupt_en(st, false);
if (ret)
return ret;
/* FIFO watermark interrupt starts out as enabled, disable it. */
ret = ad4130_set_watermark_interrupt_en(st, false);
if (ret)
return ret;
}
/* Setup channels. */
for (i = 0; i < indio_dev->num_channels; i++) {
@ -1948,10 +2229,14 @@ static int ad4130_setup(struct iio_dev *indio_dev)
struct iio_chan_spec *chan = &st->chans[i];
unsigned int val;
val = FIELD_PREP(AD4130_CHANNEL_AINP_MASK, chan->channel) |
FIELD_PREP(AD4130_CHANNEL_AINM_MASK, chan->channel2) |
FIELD_PREP(AD4130_CHANNEL_IOUT1_MASK, chan_info->iout0) |
FIELD_PREP(AD4130_CHANNEL_IOUT2_MASK, chan_info->iout1);
val = FIELD_PREP(AD4130_CHANNEL_AINP_MASK,
ad4130_translate_pin(st, chan->channel)) |
FIELD_PREP(AD4130_CHANNEL_AINM_MASK,
ad4130_translate_pin(st, chan->channel2)) |
FIELD_PREP(AD4130_CHANNEL_IOUT1_MASK,
ad4130_translate_pin(st, chan_info->iout0)) |
FIELD_PREP(AD4130_CHANNEL_IOUT2_MASK,
ad4130_translate_pin(st, chan_info->iout1));
ret = regmap_write(st->regmap, AD4130_CHANNEL_X_REG(i), val);
if (ret)
@ -1994,26 +2279,30 @@ static int ad4130_probe(struct spi_device *spi)
st = iio_priv(indio_dev);
st->chip_info = device_get_match_data(dev);
memset(st->reset_buf, 0xff, sizeof(st->reset_buf));
init_completion(&st->completion);
mutex_init(&st->lock);
st->spi = spi;
/*
* Xfer: [ XFR1 ] [ XFR2 ]
* Master: 0x7D N ......................
* Slave: ...... DATA1 DATA2 ... DATAN
*/
st->fifo_tx_buf[0] = AD4130_COMMS_READ_MASK | AD4130_FIFO_DATA_REG;
st->fifo_xfer[0].tx_buf = st->fifo_tx_buf;
st->fifo_xfer[0].len = sizeof(st->fifo_tx_buf);
st->fifo_xfer[1].rx_buf = st->fifo_rx_buf;
spi_message_init_with_transfers(&st->fifo_msg, st->fifo_xfer,
ARRAY_SIZE(st->fifo_xfer));
if (st->chip_info->has_fifo) {
/*
* Xfer: [ XFR1 ] [ XFR2 ]
* Master: 0x7D N ......................
* Slave: ...... DATA1 DATA2 ... DATAN
*/
st->fifo_tx_buf[0] = AD4130_COMMS_READ_MASK | AD4130_FIFO_DATA_REG;
st->fifo_xfer[0].tx_buf = st->fifo_tx_buf;
st->fifo_xfer[0].len = sizeof(st->fifo_tx_buf);
st->fifo_xfer[1].rx_buf = st->fifo_rx_buf;
spi_message_init_with_transfers(&st->fifo_msg, st->fifo_xfer,
ARRAY_SIZE(st->fifo_xfer));
}
indio_dev->name = AD4130_NAME;
indio_dev->name = st->chip_info->name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &ad4130_info;
indio_dev->info = st->chip_info->info;
st->regmap = devm_regmap_init(dev, NULL, st, &ad4130_regmap_config);
if (IS_ERR(st->regmap))
@ -2056,9 +2345,9 @@ static int ad4130_probe(struct spi_device *spi)
ad4130_fill_scale_tbls(st);
st->gc.owner = THIS_MODULE;
st->gc.label = AD4130_NAME;
st->gc.label = st->chip_info->name;
st->gc.base = -1;
st->gc.ngpio = AD4130_MAX_GPIOS;
st->gc.ngpio = st->chip_info->num_gpios;
st->gc.parent = dev;
st->gc.can_sleep = true;
st->gc.init_valid_mask = ad4130_gpio_init_valid_mask;
@ -2069,9 +2358,12 @@ static int ad4130_probe(struct spi_device *spi)
if (ret)
return ret;
ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev,
&ad4130_buffer_ops,
ad4130_fifo_attributes);
if (st->chip_info->has_fifo)
ret = devm_iio_kfifo_buffer_setup_ext(dev, indio_dev,
&ad4130_buffer_ops,
ad4130_fifo_attributes);
else
ret = ad4130_triggered_buffer_setup(indio_dev);
if (ret)
return ret;
@ -2081,40 +2373,75 @@ static int ad4130_probe(struct spi_device *spi)
if (ret)
return dev_err_probe(dev, ret, "Failed to request irq\n");
/*
* When the chip enters FIFO mode, IRQ polarity is inverted.
* When the chip exits FIFO mode, IRQ polarity returns to normal.
* See datasheet pages: 65, FIFO Watermark Interrupt section,
* and 71, Bit Descriptions for STATUS Register, RDYB.
* Cache the normal and inverted IRQ triggers to set them when
* entering and exiting FIFO mode.
*/
st->irq_trigger = irq_get_trigger_type(spi->irq);
if (st->irq_trigger & IRQF_TRIGGER_RISING)
st->inv_irq_trigger = IRQF_TRIGGER_FALLING;
else if (st->irq_trigger & IRQF_TRIGGER_FALLING)
st->inv_irq_trigger = IRQF_TRIGGER_RISING;
else
return dev_err_probe(dev, -EINVAL, "Invalid irq flags: %u\n",
st->irq_trigger);
if (st->chip_info->has_fifo) {
/*
* When the chip enters FIFO mode, IRQ polarity is inverted.
* When the chip exits FIFO mode, IRQ polarity returns to normal.
* See datasheet pages: 65, FIFO Watermark Interrupt section,
* and 71, Bit Descriptions for STATUS Register, RDYB.
* Cache the normal and inverted IRQ triggers to set them when
* entering and exiting FIFO mode.
*/
st->irq_trigger = irq_get_trigger_type(spi->irq);
if (st->irq_trigger & IRQF_TRIGGER_RISING)
st->inv_irq_trigger = IRQF_TRIGGER_FALLING;
else if (st->irq_trigger & IRQF_TRIGGER_FALLING)
st->inv_irq_trigger = IRQF_TRIGGER_RISING;
else
return dev_err_probe(dev, -EINVAL, "Invalid irq flags: %u\n",
st->irq_trigger);
}
return devm_iio_device_register(dev, indio_dev);
}
static const struct of_device_id ad4130_of_match[] = {
{
.compatible = "adi,ad4129-4",
.data = &ad4129_4_chip_info
},
{
.compatible = "adi,ad4129-8",
.data = &ad4129_8_chip_info
},
{
.compatible = "adi,ad4130-4",
.data = &ad4130_4_chip_info
},
{
.compatible = "adi,ad4130",
.data = &ad4130_8_chip_info
},
{
.compatible = "adi,ad4131-4",
.data = &ad4131_4_chip_info
},
{
.compatible = "adi,ad4131-8",
.data = &ad4131_8_chip_info
},
{ }
};
MODULE_DEVICE_TABLE(of, ad4130_of_match);
static const struct spi_device_id ad4130_id_table[] = {
{ "ad4129-4", (kernel_ulong_t)&ad4129_4_chip_info },
{ "ad4129-8", (kernel_ulong_t)&ad4129_8_chip_info },
{ "ad4130-4", (kernel_ulong_t)&ad4130_4_chip_info },
{ "ad4130", (kernel_ulong_t)&ad4130_8_chip_info },
{ "ad4131-4", (kernel_ulong_t)&ad4131_4_chip_info },
{ "ad4131-8", (kernel_ulong_t)&ad4131_8_chip_info },
{ }
};
MODULE_DEVICE_TABLE(spi, ad4130_id_table);
static struct spi_driver ad4130_driver = {
.driver = {
.name = AD4130_NAME,
.of_match_table = ad4130_of_match,
},
.probe = ad4130_probe,
.id_table = ad4130_id_table,
};
module_spi_driver(ad4130_driver);

View File

@ -1699,34 +1699,29 @@ static int ad4170_gpio_get_direction(struct gpio_chip *gc, unsigned int offset)
return ret;
}
static const unsigned long gpio_masks[] = {
AD4170_GPIO_MODE_GPIO0_MSK,
AD4170_GPIO_MODE_GPIO1_MSK,
AD4170_GPIO_MODE_GPIO2_MSK,
AD4170_GPIO_MODE_GPIO3_MSK,
};
static int ad4170_gpio_direction_input(struct gpio_chip *gc, unsigned int offset)
{
struct iio_dev *indio_dev = gpiochip_get_data(gc);
struct ad4170_state *st = iio_priv(indio_dev);
unsigned long gpio_mask;
int ret;
if (!iio_device_claim_direct(indio_dev))
return -EBUSY;
switch (offset) {
case 0:
gpio_mask = AD4170_GPIO_MODE_GPIO0_MSK;
break;
case 1:
gpio_mask = AD4170_GPIO_MODE_GPIO1_MSK;
break;
case 2:
gpio_mask = AD4170_GPIO_MODE_GPIO2_MSK;
break;
case 3:
gpio_mask = AD4170_GPIO_MODE_GPIO3_MSK;
break;
default:
if (offset >= ARRAY_SIZE(gpio_masks)) {
ret = -EINVAL;
goto err_release;
}
ret = regmap_update_bits(st->regmap, AD4170_GPIO_MODE_REG, gpio_mask,
ret = regmap_update_bits(st->regmap, AD4170_GPIO_MODE_REG,
gpio_masks[offset],
AD4170_GPIO_MODE_GPIO_INPUT << (2 * offset));
err_release:
@ -1740,7 +1735,6 @@ static int ad4170_gpio_direction_output(struct gpio_chip *gc,
{
struct iio_dev *indio_dev = gpiochip_get_data(gc);
struct ad4170_state *st = iio_priv(indio_dev);
unsigned long gpio_mask;
int ret;
ret = ad4170_gpio_set(gc, offset, value);
@ -1750,24 +1744,13 @@ static int ad4170_gpio_direction_output(struct gpio_chip *gc,
if (!iio_device_claim_direct(indio_dev))
return -EBUSY;
switch (offset) {
case 0:
gpio_mask = AD4170_GPIO_MODE_GPIO0_MSK;
break;
case 1:
gpio_mask = AD4170_GPIO_MODE_GPIO1_MSK;
break;
case 2:
gpio_mask = AD4170_GPIO_MODE_GPIO2_MSK;
break;
case 3:
gpio_mask = AD4170_GPIO_MODE_GPIO3_MSK;
break;
default:
if (offset >= ARRAY_SIZE(gpio_masks)) {
ret = -EINVAL;
goto err_release;
}
ret = regmap_update_bits(st->regmap, AD4170_GPIO_MODE_REG, gpio_mask,
ret = regmap_update_bits(st->regmap, AD4170_GPIO_MODE_REG,
gpio_masks[offset],
AD4170_GPIO_MODE_GPIO_OUTPUT << (2 * offset));
err_release:

2084
drivers/iio/adc/ad4691.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -101,23 +101,17 @@ static const struct ad7091r_init_info ad7091r5_init_info = {
static int ad7091r5_i2c_probe(struct i2c_client *i2c)
{
const struct ad7091r_init_info *init_info;
init_info = i2c_get_match_data(i2c);
if (!init_info)
return -EINVAL;
return ad7091r_probe(&i2c->dev, init_info, i2c->irq);
return ad7091r_probe(&i2c->dev, &ad7091r5_init_info, i2c->irq);
}
static const struct of_device_id ad7091r5_dt_ids[] = {
{ .compatible = "adi,ad7091r5", .data = &ad7091r5_init_info },
{ .compatible = "adi,ad7091r5" },
{ }
};
MODULE_DEVICE_TABLE(of, ad7091r5_dt_ids);
static const struct i2c_device_id ad7091r5_i2c_ids[] = {
{ "ad7091r5", (kernel_ulong_t)&ad7091r5_init_info },
{ .name = "ad7091r5" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad7091r5_i2c_ids);

View File

@ -154,27 +154,18 @@ static int ad7191_config_setup(struct iio_dev *indio_dev)
const u32 gain[4] = { 1, 8, 64, 128 };
static u32 scale_buffer[4][2];
int odr_value, odr_index = 0, pga_value, pga_index = 0, i, ret;
const char *propname;
u64 scale_uv;
st->samp_freq_index = 0;
st->scale_index = 0;
ret = device_property_read_u32(dev, "adi,odr-value", &odr_value);
if (ret && ret != -EINVAL)
return dev_err_probe(dev, ret, "Failed to get odr value.\n");
propname = "adi,odr-value";
if (device_property_present(dev, propname)) {
ret = device_property_read_u32(dev, propname, &odr_value);
if (ret)
return dev_err_probe(dev, ret, "Failed to get %s.\n", propname);
if (ret == -EINVAL) {
st->odr_gpios = devm_gpiod_get_array(dev, "odr", GPIOD_OUT_LOW);
if (IS_ERR(st->odr_gpios))
return dev_err_probe(dev, PTR_ERR(st->odr_gpios),
"Failed to get odr gpios.\n");
if (st->odr_gpios->ndescs != 2)
return dev_err_probe(dev, -EINVAL, "Expected 2 odr gpio pins.\n");
st->samp_freq_avail = samp_freq;
st->samp_freq_avail_size = ARRAY_SIZE(samp_freq);
} else {
for (i = 0; i < ARRAY_SIZE(samp_freq); i++) {
if (odr_value != samp_freq[i])
continue;
@ -186,6 +177,17 @@ static int ad7191_config_setup(struct iio_dev *indio_dev)
st->samp_freq_avail_size = 1;
st->odr_gpios = NULL;
} else {
st->odr_gpios = devm_gpiod_get_array(dev, "odr", GPIOD_OUT_LOW);
if (IS_ERR(st->odr_gpios))
return dev_err_probe(dev, PTR_ERR(st->odr_gpios),
"Failed to get odr gpios.\n");
if (st->odr_gpios->ndescs != 2)
return dev_err_probe(dev, -EINVAL, "Expected 2 odr gpio pins.\n");
st->samp_freq_avail = samp_freq;
st->samp_freq_avail_size = ARRAY_SIZE(samp_freq);
}
mutex_lock(&st->lock);
@ -200,22 +202,12 @@ static int ad7191_config_setup(struct iio_dev *indio_dev)
mutex_unlock(&st->lock);
ret = device_property_read_u32(dev, "adi,pga-value", &pga_value);
if (ret && ret != -EINVAL)
return dev_err_probe(dev, ret, "Failed to get pga value.\n");
propname = "adi,pga-value";
if (device_property_present(dev, propname)) {
ret = device_property_read_u32(dev, propname, &pga_value);
if (ret)
return dev_err_probe(dev, ret, "Failed to get %s.\n", propname);
if (ret == -EINVAL) {
st->pga_gpios = devm_gpiod_get_array(dev, "pga", GPIOD_OUT_LOW);
if (IS_ERR(st->pga_gpios))
return dev_err_probe(dev, PTR_ERR(st->pga_gpios),
"Failed to get pga gpios.\n");
if (st->pga_gpios->ndescs != 2)
return dev_err_probe(dev, -EINVAL, "Expected 2 pga gpio pins.\n");
st->scale_avail = scale_buffer;
st->scale_avail_size = ARRAY_SIZE(scale_buffer);
} else {
for (i = 0; i < ARRAY_SIZE(gain); i++) {
if (pga_value != gain[i])
continue;
@ -227,6 +219,17 @@ static int ad7191_config_setup(struct iio_dev *indio_dev)
st->scale_avail_size = 1;
st->pga_gpios = NULL;
} else {
st->pga_gpios = devm_gpiod_get_array(dev, "pga", GPIOD_OUT_LOW);
if (IS_ERR(st->pga_gpios))
return dev_err_probe(dev, PTR_ERR(st->pga_gpios),
"Failed to get pga gpios.\n");
if (st->pga_gpios->ndescs != 2)
return dev_err_probe(dev, -EINVAL, "Expected 2 pga gpio pins.\n");
st->scale_avail = scale_buffer;
st->scale_avail_size = ARRAY_SIZE(scale_buffer);
}
st->temp_gpio = devm_gpiod_get(dev, "temp", GPIOD_OUT_LOW);

View File

@ -39,7 +39,7 @@
#define AD7192_REG_CONF 2 /* Configuration Register (RW, 24-bit) */
#define AD7192_REG_DATA 3 /* Data Register (RO, 24/32-bit) */
#define AD7192_REG_ID 4 /* ID Register (RO, 8-bit) */
#define AD7192_REG_GPOCON 5 /* GPOCON Register (RO, 8-bit) */
#define AD7192_REG_GPOCON 5 /* GPOCON Register (RW, 8-bit) */
#define AD7192_REG_OFFSET 6 /* Offset Register (RW, 16-bit */
/* (AD7792)/24-bit (AD7192)) */
#define AD7192_REG_FULLSALE 7 /* Full-Scale Register */
@ -576,7 +576,12 @@ static int ad7192_setup(struct iio_dev *indio_dev, struct device *dev)
ret = ad_sd_reset(&st->sd);
if (ret < 0)
return ret;
usleep_range(500, 1000); /* Wait for at least 500us */
/*
* Per AD7192 datasheet (Rev. A, page 34, RESET section), allow
* 500 us after a reset before accessing on-chip registers.
*/
fsleep(500);
/* write/read test for device presence */
ret = ad_sd_read_reg(&st->sd, AD7192_REG_ID, 1, &id);

View File

@ -496,7 +496,8 @@ static ssize_t ad7280_store_balance_sw(struct iio_dev *indio_dev,
devaddr = chan->address >> 8;
ch = chan->address & 0xFF;
mutex_lock(&st->lock);
guard(mutex)(&st->lock);
if (readin)
st->cb_mask[devaddr] |= BIT(ch);
else
@ -505,7 +506,6 @@ static ssize_t ad7280_store_balance_sw(struct iio_dev *indio_dev,
ret = ad7280_write(st, devaddr, AD7280A_CELL_BALANCE_REG, 0,
FIELD_PREP(AD7280A_CELL_BALANCE_CHAN_BITMAP_MSK,
st->cb_mask[devaddr]));
mutex_unlock(&st->lock);
return ret ? ret : len;
}
@ -516,14 +516,13 @@ static ssize_t ad7280_show_balance_timer(struct iio_dev *indio_dev,
char *buf)
{
struct ad7280_state *st = iio_priv(indio_dev);
u8 devaddr = chan->address >> 8;
u8 ch = chan->address & 0xFF;
unsigned int msecs;
int ret;
mutex_lock(&st->lock);
ret = ad7280_read_reg(st, chan->address >> 8,
(chan->address & 0xFF) + AD7280A_CB1_TIMER_REG);
mutex_unlock(&st->lock);
scoped_guard(mutex, &st->lock)
ret = ad7280_read_reg(st, devaddr, ch + AD7280A_CB1_TIMER_REG);
if (ret < 0)
return ret;
@ -538,6 +537,8 @@ static ssize_t ad7280_store_balance_timer(struct iio_dev *indio_dev,
const char *buf, size_t len)
{
struct ad7280_state *st = iio_priv(indio_dev);
u8 devaddr = chan->address >> 8;
u8 ch = chan->address & 0xFF;
int val, val2;
int ret;
@ -551,11 +552,10 @@ static ssize_t ad7280_store_balance_timer(struct iio_dev *indio_dev,
if (val > 31)
return -EINVAL;
mutex_lock(&st->lock);
ret = ad7280_write(st, chan->address >> 8,
(chan->address & 0xFF) + AD7280A_CB1_TIMER_REG, 0,
guard(mutex)(&st->lock);
ret = ad7280_write(st, devaddr, ch + AD7280A_CB1_TIMER_REG, 0,
FIELD_PREP(AD7280A_CB_TIMER_VAL_MSK, val));
mutex_unlock(&st->lock);
return ret ? ret : len;
}
@ -737,7 +737,8 @@ static int ad7280a_write_thresh(struct iio_dev *indio_dev,
if (val2 != 0)
return -EINVAL;
mutex_lock(&st->lock);
guard(mutex)(&st->lock);
switch (chan->type) {
case IIO_VOLTAGE:
value = ((val - 1000) * 100) / 1568; /* LSB 15.68mV */
@ -748,22 +749,20 @@ static int ad7280a_write_thresh(struct iio_dev *indio_dev,
ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr,
1, value);
if (ret)
break;
return ret;
st->cell_threshhigh = value;
break;
return 0;
case IIO_EV_DIR_FALLING:
addr = AD7280A_CELL_UNDERVOLTAGE_REG;
ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr,
1, value);
if (ret)
break;
return ret;
st->cell_threshlow = value;
break;
return 0;
default:
ret = -EINVAL;
goto err_unlock;
return -EINVAL;
}
break;
case IIO_TEMP:
value = (val * 10) / 196; /* LSB 19.6mV */
value = clamp(value, 0L, 0xFFL);
@ -773,31 +772,23 @@ static int ad7280a_write_thresh(struct iio_dev *indio_dev,
ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr,
1, value);
if (ret)
break;
return ret;
st->aux_threshhigh = value;
break;
return 0;
case IIO_EV_DIR_FALLING:
addr = AD7280A_AUX_ADC_UNDERVOLTAGE_REG;
ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, addr,
1, value);
if (ret)
break;
return ret;
st->aux_threshlow = value;
break;
return 0;
default:
ret = -EINVAL;
goto err_unlock;
return -EINVAL;
}
break;
default:
ret = -EINVAL;
goto err_unlock;
return -EINVAL;
}
err_unlock:
mutex_unlock(&st->lock);
return ret;
}
static irqreturn_t ad7280_event_handler(int irq, void *private)
@ -881,17 +872,18 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
long m)
{
struct ad7280_state *st = iio_priv(indio_dev);
u8 devaddr = chan->address >> 8;
u8 ch = chan->address & 0xFF;
int ret;
switch (m) {
case IIO_CHAN_INFO_RAW:
mutex_lock(&st->lock);
case IIO_CHAN_INFO_RAW: {
guard(mutex)(&st->lock);
if (chan->address == AD7280A_ALL_CELLS)
ret = ad7280_read_all_channels(st, st->scan_cnt, NULL);
else
ret = ad7280_read_channel(st, chan->address >> 8,
chan->address & 0xFF);
mutex_unlock(&st->lock);
ret = ad7280_read_channel(st, devaddr, ch);
if (ret < 0)
return ret;
@ -899,8 +891,9 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
*val = ret;
return IIO_VAL_INT;
}
case IIO_CHAN_INFO_SCALE:
if ((chan->address & 0xFF) <= AD7280A_CELL_VOLTAGE_6_REG)
if (ch <= AD7280A_CELL_VOLTAGE_6_REG)
*val = 4000;
else
*val = 5000;
@ -990,8 +983,8 @@ static int ad7280_probe(struct spi_device *spi)
st->acquisition_time = AD7280A_CTRL_LB_ACQ_TIME_1600ns;
break;
default:
dev_err(dev, "Firmware provided acquisition time is invalid\n");
return -EINVAL;
return dev_err_probe(dev, -EINVAL,
"Firmware provided acquisition time is invalid\n");
}
} else {
st->acquisition_time = AD7280A_CTRL_LB_ACQ_TIME_400ns;

View File

@ -536,7 +536,7 @@ static int ad7291_probe(struct i2c_client *client)
}
static const struct i2c_device_id ad7291_id[] = {
{ "ad7291" },
{ .name = "ad7291" },
{ }
};

View File

@ -253,12 +253,13 @@ static const struct iio_info ad7292_info = {
static int ad7292_probe(struct spi_device *spi)
{
struct device *dev = &spi->dev;
struct ad7292_state *st;
struct iio_dev *indio_dev;
bool diff_channels = false;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
@ -266,12 +267,11 @@ static int ad7292_probe(struct spi_device *spi)
st->spi = spi;
ret = ad7292_spi_reg_read(st, AD7292_REG_VENDOR_ID);
if (ret != ADI_VENDOR_ID) {
dev_err(&spi->dev, "Wrong vendor id 0x%x\n", ret);
return -EINVAL;
}
if (ret != ADI_VENDOR_ID)
return dev_err_probe(dev, -EINVAL,
"Wrong vendor id 0x%x\n", ret);
ret = devm_regulator_get_enable_read_voltage(&spi->dev, "vref");
ret = devm_regulator_get_enable_read_voltage(dev, "vref");
if (ret < 0 && ret != -ENODEV)
return ret;
@ -281,7 +281,7 @@ static int ad7292_probe(struct spi_device *spi)
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &ad7292_info;
device_for_each_child_node_scoped(&spi->dev, child) {
device_for_each_child_node_scoped(dev, child) {
diff_channels = fwnode_property_read_bool(child,
"diff-channels");
if (diff_channels)
@ -296,7 +296,7 @@ static int ad7292_probe(struct spi_device *spi)
indio_dev->channels = ad7292_channels;
}
return devm_iio_device_register(&spi->dev, indio_dev);
return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id ad7292_id_table[] = {

View File

@ -1475,7 +1475,7 @@ static int ad7606_probe_channels(struct iio_dev *indio_dev)
}
if (slow_bus)
channels[i] = (struct iio_chan_spec)IIO_CHAN_SOFT_TIMESTAMP(i);
channels[i] = IIO_CHAN_SOFT_TIMESTAMP(i);
indio_dev->channels = channels;

View File

@ -175,12 +175,12 @@ enum ad7960_mode {
static int ad7625_set_sampling_freq(struct ad7625_state *st, u32 freq)
{
u32 target;
struct pwm_waveform clk_gate_wf = { }, cnv_wf = { };
unsigned long target;
int ret;
target = DIV_ROUND_UP(NSEC_PER_SEC, freq);
cnv_wf.period_length_ns = clamp(target, 100, 10 * KILO);
cnv_wf.period_length_ns = clamp(target, 100UL, 10UL * NSEC_PER_USEC);
/*
* Use the maximum conversion time t_CNVH from the datasheet as

View File

@ -1871,10 +1871,8 @@ static int ad7768_probe(struct spi_device *spi)
return ret;
ret = ad7768_setup(indio_dev);
if (ret < 0) {
dev_err(&spi->dev, "AD7768 setup failed\n");
return ret;
}
if (ret < 0)
return dev_err_probe(dev, ret, "AD7768 setup failed\n");
init_completion(&st->completion);
ret = devm_mutex_init(&spi->dev, &st->pga_lock);

View File

@ -264,16 +264,12 @@ static const struct iio_info ad7780_info = {
static int ad7780_init_gpios(struct device *dev, struct ad7780_state *st)
{
int ret;
st->powerdown_gpio = devm_gpiod_get_optional(dev,
"powerdown",
GPIOD_OUT_LOW);
if (IS_ERR(st->powerdown_gpio)) {
ret = PTR_ERR(st->powerdown_gpio);
dev_err(dev, "Failed to request powerdown GPIO: %d\n", ret);
return ret;
}
if (IS_ERR(st->powerdown_gpio))
return dev_err_probe(dev, PTR_ERR(st->powerdown_gpio),
"Failed to request powerdown GPIO\n");
if (!st->chip_info->is_ad778x)
return 0;
@ -282,20 +278,16 @@ static int ad7780_init_gpios(struct device *dev, struct ad7780_state *st)
st->gain_gpio = devm_gpiod_get_optional(dev,
"adi,gain",
GPIOD_OUT_HIGH);
if (IS_ERR(st->gain_gpio)) {
ret = PTR_ERR(st->gain_gpio);
dev_err(dev, "Failed to request gain GPIO: %d\n", ret);
return ret;
}
if (IS_ERR(st->gain_gpio))
return dev_err_probe(dev, PTR_ERR(st->gain_gpio),
"Failed to request gain GPIO\n");
st->filter_gpio = devm_gpiod_get_optional(dev,
"adi,filter",
GPIOD_OUT_HIGH);
if (IS_ERR(st->filter_gpio)) {
ret = PTR_ERR(st->filter_gpio);
dev_err(dev, "Failed to request filter GPIO: %d\n", ret);
return ret;
}
if (IS_ERR(st->filter_gpio))
return dev_err_probe(dev, PTR_ERR(st->filter_gpio),
"Failed to request filter GPIO\n");
return 0;
}
@ -307,11 +299,12 @@ static void ad7780_reg_disable(void *reg)
static int ad7780_probe(struct spi_device *spi)
{
struct device *dev = &spi->dev;
struct ad7780_state *st;
struct iio_dev *indio_dev;
int ret;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
@ -329,29 +322,28 @@ static int ad7780_probe(struct spi_device *spi)
indio_dev->num_channels = 1;
indio_dev->info = &ad7780_info;
ret = ad7780_init_gpios(&spi->dev, st);
ret = ad7780_init_gpios(dev, st);
if (ret)
return ret;
st->reg = devm_regulator_get(&spi->dev, "avdd");
st->reg = devm_regulator_get(dev, "avdd");
if (IS_ERR(st->reg))
return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret) {
dev_err(&spi->dev, "Failed to enable specified AVdd supply\n");
return ret;
}
if (ret)
return dev_err_probe(dev, ret,
"Failed to enable specified AVdd supply\n");
ret = devm_add_action_or_reset(&spi->dev, ad7780_reg_disable, st->reg);
ret = devm_add_action_or_reset(dev, ad7780_reg_disable, st->reg);
if (ret)
return ret;
ret = devm_ad_sd_setup_buffer_and_trigger(&spi->dev, indio_dev);
ret = devm_ad_sd_setup_buffer_and_trigger(dev, indio_dev);
if (ret)
return ret;
return devm_iio_device_register(&spi->dev, indio_dev);
return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id ad7780_id[] = {

View File

@ -407,23 +407,22 @@ static void ad7791_reg_disable(void *reg)
static int ad7791_probe(struct spi_device *spi)
{
const struct ad7791_platform_data *pdata = dev_get_platdata(&spi->dev);
struct device *dev = &spi->dev;
const struct ad7791_platform_data *pdata = dev_get_platdata(dev);
struct iio_dev *indio_dev;
struct ad7791_state *st;
int ret;
if (!spi->irq) {
dev_err(&spi->dev, "Missing IRQ.\n");
return -ENXIO;
}
if (!spi->irq)
return dev_err_probe(dev, -ENXIO, "Missing IRQ.\n");
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
st->reg = devm_regulator_get(&spi->dev, "refin");
st->reg = devm_regulator_get(dev, "refin");
if (IS_ERR(st->reg))
return PTR_ERR(st->reg);
@ -431,7 +430,7 @@ static int ad7791_probe(struct spi_device *spi)
if (ret)
return ret;
ret = devm_add_action_or_reset(&spi->dev, ad7791_reg_disable, st->reg);
ret = devm_add_action_or_reset(dev, ad7791_reg_disable, st->reg);
if (ret)
return ret;
@ -447,7 +446,7 @@ static int ad7791_probe(struct spi_device *spi)
else
indio_dev->info = &ad7791_no_filter_info;
ret = devm_ad_sd_setup_buffer_and_trigger(&spi->dev, indio_dev);
ret = devm_ad_sd_setup_buffer_and_trigger(dev, indio_dev);
if (ret)
return ret;
@ -455,7 +454,7 @@ static int ad7791_probe(struct spi_device *spi)
if (ret)
return ret;
return devm_iio_device_register(&spi->dev, indio_dev);
return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id ad7791_spi_ids[] = {

View File

@ -268,7 +268,12 @@ static int ad7793_setup(struct iio_dev *indio_dev,
ret = ad_sd_reset(&st->sd);
if (ret < 0)
goto out;
usleep_range(500, 2000); /* Wait for at least 500us */
/*
* Per AD7792/AD7793 datasheet (Rev. B, page 25, RESET section),
* allow 500 us after a reset before accessing on-chip registers.
*/
fsleep(500);
/* write/read test for device presence */
ret = ad_sd_read_reg(&st->sd, AD7793_REG_ID, 1, &id);
@ -278,8 +283,8 @@ static int ad7793_setup(struct iio_dev *indio_dev,
id &= AD7793_ID_MASK;
if (id != st->chip_info->id) {
ret = -ENODEV;
dev_err(&st->sd.spi->dev, "device ID query failed\n");
ret = dev_err_probe(&st->sd.spi->dev, -ENODEV,
"device ID query failed\n");
goto out;
}
@ -338,8 +343,7 @@ static int ad7793_setup(struct iio_dev *indio_dev,
return 0;
out:
dev_err(&st->sd.spi->dev, "setup failed\n");
return ret;
return dev_err_probe(&st->sd.spi->dev, ret, "setup failed\n");
}
static const u16 ad7793_sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39,
@ -774,22 +778,19 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = {
static int ad7793_probe(struct spi_device *spi)
{
const struct ad7793_platform_data *pdata = dev_get_platdata(&spi->dev);
struct device *dev = &spi->dev;
const struct ad7793_platform_data *pdata = dev_get_platdata(dev);
struct ad7793_state *st;
struct iio_dev *indio_dev;
int ret, vref_mv = 0;
if (!pdata) {
dev_err(&spi->dev, "no platform data?\n");
return -ENODEV;
}
if (!pdata)
return dev_err_probe(dev, -ENODEV, "no platform data?\n");
if (!spi->irq) {
dev_err(&spi->dev, "no IRQ?\n");
return -ENODEV;
}
if (!spi->irq)
return dev_err_probe(dev, -ENODEV, "no IRQ?\n");
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@ -798,7 +799,7 @@ static int ad7793_probe(struct spi_device *spi)
ad_sd_init(&st->sd, indio_dev, spi, &ad7793_sigma_delta_info);
if (pdata->refsel != AD7793_REFSEL_INTERNAL) {
ret = devm_regulator_get_enable_read_voltage(&spi->dev, "refin");
ret = devm_regulator_get_enable_read_voltage(dev, "refin");
if (ret < 0)
return ret;
@ -816,7 +817,7 @@ static int ad7793_probe(struct spi_device *spi)
indio_dev->num_channels = st->chip_info->num_channels;
indio_dev->info = st->chip_info->iio_info;
ret = devm_ad_sd_setup_buffer_and_trigger(&spi->dev, indio_dev);
ret = devm_ad_sd_setup_buffer_and_trigger(dev, indio_dev);
if (ret)
return ret;
@ -824,7 +825,7 @@ static int ad7793_probe(struct spi_device *spi)
if (ret)
return ret;
return devm_iio_device_register(&spi->dev, indio_dev);
return devm_iio_device_register(dev, indio_dev);
}
static const struct spi_device_id ad7793_id[] = {

View File

@ -341,8 +341,8 @@ static int ad7949_spi_probe(struct spi_device *spi)
} else if (spi_is_bpw_supported(spi, 8)) {
spi->bits_per_word = 8;
} else {
dev_err(dev, "unable to find common BPW with spi controller\n");
return -EINVAL;
return dev_err_probe(dev, -EINVAL,
"unable to find common BPW with spi controller\n");
}
/* Setup internal voltage reference */
@ -357,8 +357,8 @@ static int ad7949_spi_probe(struct spi_device *spi)
ad7949_adc->refsel = AD7949_CFG_VAL_REF_INT_4096;
break;
default:
dev_err(dev, "unsupported internal voltage reference\n");
return -EINVAL;
return dev_err_probe(dev, -EINVAL,
"unsupported internal voltage reference\n");
}
/* Setup external voltage reference, buffered? */
@ -382,10 +382,9 @@ static int ad7949_spi_probe(struct spi_device *spi)
if (ad7949_adc->refsel & AD7949_CFG_VAL_REF_EXTERNAL) {
ret = regulator_enable(ad7949_adc->vref);
if (ret < 0) {
dev_err(dev, "fail to enable regulator\n");
return ret;
}
if (ret < 0)
return dev_err_probe(dev, ret,
"fail to enable regulator\n");
ret = devm_add_action_or_reset(dev, ad7949_disable_reg,
ad7949_adc->vref);
@ -396,16 +395,10 @@ static int ad7949_spi_probe(struct spi_device *spi)
mutex_init(&ad7949_adc->lock);
ret = ad7949_spi_init(ad7949_adc);
if (ret) {
dev_err(dev, "fail to init this device: %d\n", ret);
return ret;
}
ret = devm_iio_device_register(dev, indio_dev);
if (ret)
dev_err(dev, "fail to register iio device: %d\n", ret);
return dev_err_probe(dev, ret, "fail to init this device\n");
return ret;
return devm_iio_device_register(dev, indio_dev);
}
static const struct of_device_id ad7949_spi_of_id[] = {

View File

@ -18,27 +18,29 @@
* ad7998 and similar chips.
*/
#include <linux/interrupt.h>
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/sysfs.h>
#include <linux/i2c.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/bitops.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/types.h>
#include <linux/units.h>
#include <linux/iio/buffer.h>
#include <linux/iio/events.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#include <linux/iio/events.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#define AD799X_CHANNEL_SHIFT 4
#define AD799X_MAX_CHANNELS 8
/*
* AD7991, AD7995 and AD7999 defines
@ -133,8 +135,11 @@ struct ad799x_state {
unsigned int id;
u16 config;
u8 *rx_buf;
unsigned int transfer_size;
int vref_uV;
IIO_DECLARE_BUFFER_WITH_TS(__be16, rx_buf, AD799X_MAX_CHANNELS);
};
static int ad799x_write_config(struct ad799x_state *st, u16 val)
@ -217,7 +222,8 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
}
b_sent = i2c_smbus_read_i2c_block_data(st->client,
cmd, st->transfer_size, st->rx_buf);
cmd, st->transfer_size,
(u8 *)st->rx_buf);
if (b_sent < 0)
goto out;
@ -234,11 +240,6 @@ static int ad799x_update_scan_mode(struct iio_dev *indio_dev,
{
struct ad799x_state *st = iio_priv(indio_dev);
kfree(st->rx_buf);
st->rx_buf = kmalloc(indio_dev->scan_bytes, GFP_KERNEL);
if (!st->rx_buf)
return -ENOMEM;
st->transfer_size = bitmap_weight(scan_mask,
iio_get_masklength(indio_dev)) * 2;
@ -306,14 +307,7 @@ static int ad799x_read_raw(struct iio_dev *indio_dev,
GENMASK(chan->scan_type.realbits - 1, 0);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
if (st->vref)
ret = regulator_get_voltage(st->vref);
else
ret = regulator_get_voltage(st->reg);
if (ret < 0)
return ret;
*val = ret / 1000;
*val = st->vref_uV / (MICRO / MILLI);
*val2 = chan->scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2;
}
@ -781,8 +775,14 @@ static const struct ad799x_chip_info ad799x_chip_info_tbl[] = {
},
};
static void ad799x_reg_disable(void *reg)
{
regulator_disable(reg);
}
static int ad799x_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
const struct i2c_device_id *id = i2c_client_get_device_id(client);
int ret;
int extra_config = 0;
@ -791,7 +791,7 @@ static int ad799x_probe(struct i2c_client *client)
const struct ad799x_chip_info *chip_info =
&ad799x_chip_info_tbl[id->driver_data];
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
@ -799,6 +799,10 @@ static int ad799x_probe(struct i2c_client *client)
/* this is only used for device removal purposes */
i2c_set_clientdata(client, indio_dev);
ret = devm_mutex_init(dev, &st->lock);
if (ret)
return ret;
st->id = id->driver_data;
if (client->irq > 0 && chip_info->irq_config.info)
st->chip_config = &chip_info->irq_config;
@ -807,33 +811,53 @@ static int ad799x_probe(struct i2c_client *client)
/* TODO: Add pdata options for filtering and bit delay */
st->reg = devm_regulator_get(&client->dev, "vcc");
st->reg = devm_regulator_get(dev, "vcc");
if (IS_ERR(st->reg))
return PTR_ERR(st->reg);
ret = regulator_enable(st->reg);
if (ret)
return ret;
ret = devm_add_action_or_reset(dev, ad799x_reg_disable, st->reg);
if (ret)
return ret;
/* check if an external reference is supplied */
if (chip_info->has_vref) {
st->vref = devm_regulator_get_optional(&client->dev, "vref");
st->vref = devm_regulator_get_optional(dev, "vref");
ret = PTR_ERR_OR_ZERO(st->vref);
if (ret) {
if (ret != -ENODEV)
goto error_disable_reg;
if (ret == -ENODEV) {
st->vref = NULL;
dev_info(&client->dev, "Using VCC reference voltage\n");
dev_info(dev, "Using VCC reference voltage\n");
} else if (ret) {
return ret;
}
if (st->vref) {
dev_info(&client->dev, "Using external reference voltage\n");
dev_info(dev, "Using external reference voltage\n");
extra_config |= AD7991_REF_SEL;
ret = regulator_enable(st->vref);
if (ret)
goto error_disable_reg;
return ret;
ret = devm_add_action_or_reset(dev, ad799x_reg_disable, st->vref);
if (ret)
return ret;
ret = regulator_get_voltage(st->vref);
if (ret < 0)
return ret;
st->vref_uV = ret;
}
}
if (!st->vref) {
ret = regulator_get_voltage(st->reg);
if (ret < 0)
return ret;
st->vref_uV = ret;
}
st->client = client;
indio_dev->name = id->name;
@ -845,15 +869,15 @@ static int ad799x_probe(struct i2c_client *client)
ret = ad799x_update_config(st, st->chip_config->default_config | extra_config);
if (ret)
goto error_disable_vref;
return ret;
ret = iio_triggered_buffer_setup(indio_dev, NULL,
ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL,
&ad799x_trigger_handler, NULL);
if (ret)
goto error_disable_vref;
return ret;
if (client->irq > 0) {
ret = devm_request_threaded_irq(&client->dev,
ret = devm_request_threaded_irq(dev,
client->irq,
NULL,
ad799x_event_handler,
@ -862,40 +886,10 @@ static int ad799x_probe(struct i2c_client *client)
client->name,
indio_dev);
if (ret)
goto error_cleanup_ring;
return ret;
}
mutex_init(&st->lock);
ret = iio_device_register(indio_dev);
if (ret)
goto error_cleanup_ring;
return 0;
error_cleanup_ring:
iio_triggered_buffer_cleanup(indio_dev);
error_disable_vref:
if (st->vref)
regulator_disable(st->vref);
error_disable_reg:
regulator_disable(st->reg);
return ret;
}
static void ad799x_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
struct ad799x_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
if (st->vref)
regulator_disable(st->vref);
regulator_disable(st->reg);
kfree(st->rx_buf);
return devm_iio_device_register(dev, indio_dev);
}
static int ad799x_suspend(struct device *dev)
@ -946,14 +940,14 @@ static int ad799x_resume(struct device *dev)
static DEFINE_SIMPLE_DEV_PM_OPS(ad799x_pm_ops, ad799x_suspend, ad799x_resume);
static const struct i2c_device_id ad799x_id[] = {
{ "ad7991", ad7991 },
{ "ad7995", ad7995 },
{ "ad7999", ad7999 },
{ "ad7992", ad7992 },
{ "ad7993", ad7993 },
{ "ad7994", ad7994 },
{ "ad7997", ad7997 },
{ "ad7998", ad7998 },
{ .name = "ad7991", .driver_data = ad7991 },
{ .name = "ad7995", .driver_data = ad7995 },
{ .name = "ad7999", .driver_data = ad7999 },
{ .name = "ad7992", .driver_data = ad7992 },
{ .name = "ad7993", .driver_data = ad7993 },
{ .name = "ad7994", .driver_data = ad7994 },
{ .name = "ad7997", .driver_data = ad7997 },
{ .name = "ad7998", .driver_data = ad7998 },
{ }
};
@ -965,7 +959,6 @@ static struct i2c_driver ad799x_driver = {
.pm = pm_sleep_ptr(&ad799x_pm_ops),
},
.probe = ad799x_probe,
.remove = ad799x_remove,
.id_table = ad799x_id,
};
module_i2c_driver(ad799x_driver);

View File

@ -1349,11 +1349,10 @@ static int ad9467_probe(struct spi_device *spi)
return ret;
id = ad9467_spi_read(st, AN877_ADC_REG_CHIP_ID);
if (id != st->info->id) {
dev_err(dev, "Mismatch CHIP_ID, got 0x%X, expected 0x%X\n",
id, st->info->id);
return -ENODEV;
}
if (id != st->info->id)
return dev_err_probe(dev, -ENODEV,
"Mismatch CHIP_ID, got 0x%X, expected 0x%X\n",
id, st->info->id);
if (st->info->num_scales > 1)
indio_dev->info = &ad9467_info;

View File

@ -481,7 +481,7 @@ static irqreturn_t at91_adc_9x5_interrupt(int irq, void *private)
static int at91_adc_channel_init(struct iio_dev *idev)
{
struct at91_adc_state *st = iio_priv(idev);
struct iio_chan_spec *chan_array, *timestamp;
struct iio_chan_spec *chan_array;
int bit, idx = 0;
unsigned long rsvd_mask = 0;
@ -519,14 +519,8 @@ static int at91_adc_channel_init(struct iio_dev *idev)
chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
idx++;
}
timestamp = chan_array + idx;
timestamp->type = IIO_TIMESTAMP;
timestamp->channel = -1;
timestamp->scan_index = idx;
timestamp->scan_type.sign = 's';
timestamp->scan_type.realbits = 64;
timestamp->scan_type.storagebits = 64;
chan_array[idx] = IIO_CHAN_SOFT_TIMESTAMP(idx);
idev->channels = chan_array;
return idev->num_channels;

View File

@ -262,7 +262,7 @@ static const struct iio_info cc10001_adc_info = {
static int cc10001_adc_channel_init(struct iio_dev *indio_dev,
unsigned long channel_map)
{
struct iio_chan_spec *chan_array, *timestamp;
struct iio_chan_spec *chan_array;
unsigned int bit, idx = 0;
indio_dev->num_channels = bitmap_weight(&channel_map,
@ -289,13 +289,7 @@ static int cc10001_adc_channel_init(struct iio_dev *indio_dev,
idx++;
}
timestamp = &chan_array[idx];
timestamp->type = IIO_TIMESTAMP;
timestamp->channel = -1;
timestamp->scan_index = idx;
timestamp->scan_type.sign = 's';
timestamp->scan_type.realbits = 64;
timestamp->scan_type.storagebits = 64;
chan_array[idx] = IIO_CHAN_SOFT_TIMESTAMP(idx);
indio_dev->channels = chan_array;

View File

@ -444,16 +444,6 @@ static int dln2_update_scan_mode(struct iio_dev *indio_dev,
lval.scan_type.endianness = IIO_LE; \
}
/* Assignment version of IIO_CHAN_SOFT_TIMESTAMP */
#define IIO_CHAN_SOFT_TIMESTAMP_ASSIGN(lval, _si) { \
lval.type = IIO_TIMESTAMP; \
lval.channel = -1; \
lval.scan_index = _si; \
lval.scan_type.sign = 's'; \
lval.scan_type.realbits = 64; \
lval.scan_type.storagebits = 64; \
}
static const struct iio_info dln2_adc_info = {
.read_raw = dln2_adc_read_raw,
.write_raw = dln2_adc_write_raw,
@ -614,7 +604,7 @@ static int dln2_adc_probe(struct platform_device *pdev)
for (i = 0; i < chans; ++i)
DLN2_ADC_CHAN(dln2->iio_channels[i], i)
IIO_CHAN_SOFT_TIMESTAMP_ASSIGN(dln2->iio_channels[i], i);
dln2->iio_channels[i] = IIO_CHAN_SOFT_TIMESTAMP(i);
indio_dev->name = DLN2_ADC_MOD_NAME;
indio_dev->info = &dln2_adc_info;

View File

@ -207,7 +207,7 @@ static const struct of_device_id pmc_adc_of_match[] = {
MODULE_DEVICE_TABLE(of, pmc_adc_of_match);
static const struct i2c_device_id pmc_adc_id_table[] = {
{ "pmc-adc" },
{ .name = "pmc-adc" },
{ }
};
MODULE_DEVICE_TABLE(i2c, pmc_adc_id_table);

View File

@ -28,22 +28,20 @@
struct hx711_gain_to_scale {
int gain;
int gain_pulse;
int scale;
int channel;
};
/*
* .scale depends on AVDD which in turn is known as soon as the regulator
* is available
* therefore we set .scale in hx711_probe()
* is available; it is stored per device in hx711_data.gain_scale[]
*
* channel A in documentation is channel 0 in source code
* channel B in documentation is channel 1 in source code
*/
static struct hx711_gain_to_scale hx711_gain_to_scale[HX711_GAIN_MAX] = {
{ 128, 1, 0, 0 },
{ 32, 2, 0, 1 },
{ 64, 3, 0, 0 }
static const struct hx711_gain_to_scale hx711_gain_to_scale[HX711_GAIN_MAX] = {
{ 128, 1, 0 },
{ 32, 2, 1 },
{ 64, 3, 0 },
};
static int hx711_get_gain_to_pulse(int gain)
@ -56,22 +54,22 @@ static int hx711_get_gain_to_pulse(int gain)
return 1;
}
static int hx711_get_gain_to_scale(int gain)
static int hx711_get_gain_to_scale(const int *gain_scale, int gain)
{
int i;
for (i = 0; i < HX711_GAIN_MAX; i++)
if (hx711_gain_to_scale[i].gain == gain)
return hx711_gain_to_scale[i].scale;
return gain_scale[i];
return 0;
}
static int hx711_get_scale_to_gain(int scale)
static int hx711_get_scale_to_gain(const int *gain_scale, int scale)
{
int i;
for (i = 0; i < HX711_GAIN_MAX; i++)
if (hx711_gain_to_scale[i].scale == scale)
if (gain_scale[i] == scale)
return hx711_gain_to_scale[i].gain;
return -EINVAL;
}
@ -82,6 +80,7 @@ struct hx711_data {
struct gpio_desc *gpiod_dout;
int gain_set; /* gain set on device */
int gain_chan_a; /* gain for channel A */
int gain_scale[HX711_GAIN_MAX];
struct mutex lock;
/*
* triggered buffer
@ -290,7 +289,8 @@ static int hx711_read_raw(struct iio_dev *indio_dev,
*val = 0;
mutex_lock(&hx711_data->lock);
*val2 = hx711_get_gain_to_scale(hx711_data->gain_set);
*val2 = hx711_get_gain_to_scale(hx711_data->gain_scale,
hx711_data->gain_set);
mutex_unlock(&hx711_data->lock);
@ -321,7 +321,7 @@ static int hx711_write_raw(struct iio_dev *indio_dev,
mutex_lock(&hx711_data->lock);
gain = hx711_get_scale_to_gain(val2);
gain = hx711_get_scale_to_gain(hx711_data->gain_scale, val2);
if (gain < 0) {
mutex_unlock(&hx711_data->lock);
return gain;
@ -386,6 +386,7 @@ static ssize_t hx711_scale_available_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct hx711_data *hx711_data = iio_priv(dev_to_iio_dev(dev));
struct iio_dev_attr *iio_attr = to_iio_dev_attr(attr);
int channel = iio_attr->address;
int i, len = 0;
@ -393,7 +394,7 @@ static ssize_t hx711_scale_available_show(struct device *dev,
for (i = 0; i < HX711_GAIN_MAX; i++)
if (hx711_gain_to_scale[i].channel == channel)
len += sprintf(buf + len, "0.%09d ",
hx711_gain_to_scale[i].scale);
hx711_data->gain_scale[i]);
len += sprintf(buf + len, "\n");
@ -511,7 +512,7 @@ static int hx711_probe(struct platform_device *pdev)
ret *= 100;
for (i = 0; i < HX711_GAIN_MAX; i++)
hx711_gain_to_scale[i].scale =
hx711_data->gain_scale[i] =
ret / hx711_gain_to_scale[i].gain / 1678;
hx711_data->gain_set = 128;

View File

@ -1078,12 +1078,12 @@ static void ina2xx_remove(struct i2c_client *client)
}
static const struct i2c_device_id ina2xx_id[] = {
{ "ina219", ina219 },
{ "ina220", ina219 },
{ "ina226", ina226 },
{ "ina230", ina226 },
{ "ina231", ina226 },
{ "ina236", ina236 },
{ .name = "ina219", .driver_data = ina219 },
{ .name = "ina220", .driver_data = ina219 },
{ .name = "ina226", .driver_data = ina226 },
{ .name = "ina230", .driver_data = ina226 },
{ .name = "ina231", .driver_data = ina226 },
{ .name = "ina236", .driver_data = ina236 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ina2xx_id);

View File

@ -7,6 +7,8 @@
*/
#include <dt-bindings/iio/adc/ingenic,adc.h>
#include <linux/cleanup.h>
#include <linux/clk.h>
#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
@ -115,7 +117,7 @@ static void ingenic_adc_set_adcmd(struct iio_dev *iio_dev, unsigned long mask)
{
struct ingenic_adc *adc = iio_priv(iio_dev);
mutex_lock(&adc->lock);
guard(mutex)(&adc->lock);
/* Init ADCMD */
readl(adc->base + JZ_ADC_REG_ADCMD);
@ -162,8 +164,6 @@ static void ingenic_adc_set_adcmd(struct iio_dev *iio_dev, unsigned long mask)
/* We're done */
writel(0, adc->base + JZ_ADC_REG_ADCMD);
mutex_unlock(&adc->lock);
}
static void ingenic_adc_set_config(struct ingenic_adc *adc,
@ -172,18 +172,15 @@ static void ingenic_adc_set_config(struct ingenic_adc *adc,
{
uint32_t cfg;
mutex_lock(&adc->lock);
guard(mutex)(&adc->lock);
cfg = readl(adc->base + JZ_ADC_REG_CFG) & ~mask;
cfg |= val;
writel(cfg, adc->base + JZ_ADC_REG_CFG);
mutex_unlock(&adc->lock);
}
static void ingenic_adc_enable_unlocked(struct ingenic_adc *adc,
int engine,
bool enabled)
static void __ingenic_adc_enable(struct ingenic_adc *adc, int engine,
bool enabled)
{
u8 val;
@ -201,9 +198,8 @@ static void ingenic_adc_enable(struct ingenic_adc *adc,
int engine,
bool enabled)
{
mutex_lock(&adc->lock);
ingenic_adc_enable_unlocked(adc, engine, enabled);
mutex_unlock(&adc->lock);
guard(mutex)(&adc->lock);
__ingenic_adc_enable(adc, engine, enabled);
}
static int ingenic_adc_capture(struct ingenic_adc *adc,
@ -218,18 +214,17 @@ static int ingenic_adc_capture(struct ingenic_adc *adc,
* probably due to the switch of VREF. We must keep the lock here to
* avoid races with the buffer enable/disable functions.
*/
mutex_lock(&adc->lock);
guard(mutex)(&adc->lock);
cfg = readl(adc->base + JZ_ADC_REG_CFG);
writel(cfg & ~JZ_ADC_REG_CFG_CMD_SEL, adc->base + JZ_ADC_REG_CFG);
ingenic_adc_enable_unlocked(adc, engine, true);
__ingenic_adc_enable(adc, engine, true);
ret = readb_poll_timeout(adc->base + JZ_ADC_REG_ENABLE, val,
!(val & BIT(engine)), 250, 1000);
if (ret)
ingenic_adc_enable_unlocked(adc, engine, false);
__ingenic_adc_enable(adc, engine, false);
writel(cfg, adc->base + JZ_ADC_REG_CFG);
mutex_unlock(&adc->lock);
return ret;
}
@ -628,22 +623,12 @@ static int ingenic_adc_read_avail(struct iio_dev *iio_dev,
}
}
static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
struct iio_chan_spec const *chan,
int *val)
static int __ingenic_adc_read_chan(struct ingenic_adc *adc,
struct iio_chan_spec const *chan,
int *val)
{
int cmd, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);
struct ingenic_adc *adc = iio_priv(iio_dev);
ret = clk_enable(adc->clk);
if (ret) {
dev_err(iio_dev->dev.parent, "Failed to enable clock: %d\n",
ret);
return ret;
}
/* We cannot sample the aux channels in parallel. */
mutex_lock(&adc->aux_lock);
if (adc->soc_data->has_aux_md && engine == 0) {
switch (chan->channel) {
case INGENIC_ADC_AUX0:
@ -662,7 +647,7 @@ static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
ret = ingenic_adc_capture(adc, engine);
if (ret)
goto out;
return ret;
switch (chan->channel) {
case INGENIC_ADC_AUX0:
@ -675,9 +660,26 @@ static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
break;
}
ret = IIO_VAL_INT;
out:
mutex_unlock(&adc->aux_lock);
return IIO_VAL_INT;
}
static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
struct iio_chan_spec const *chan,
int *val)
{
struct ingenic_adc *adc = iio_priv(iio_dev);
int ret;
ret = clk_enable(adc->clk);
if (ret) {
dev_err(iio_dev->dev.parent, "Failed to enable clock: %d\n", ret);
return ret;
}
/* We cannot sample the aux channels in parallel. */
scoped_guard(mutex, &adc->aux_lock)
ret = __ingenic_adc_read_chan(adc, chan, val);
clk_disable(adc->clk);
return ret;

View File

@ -9,7 +9,9 @@
*
* Copyright (c) 2023, Liam Beguin <liambeguin@gmail.com>
*/
#include <linux/array_size.h>
#include <linux/bitfield.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/iio/iio.h>
#include <linux/kernel.h>
@ -34,12 +36,14 @@
* @client: I2C reference
* @lock: Lock to serialize data access
* @vref_mv: Internal voltage reference
* @read_delay_us: Chip-specific read delay in microseconds
*/
struct ltc2309 {
struct device *dev;
struct i2c_client *client;
struct mutex lock; /* serialize data access */
int vref_mv;
unsigned int read_delay_us;
};
/* Order matches expected channel address, See datasheet Table 1. */
@ -117,20 +121,22 @@ static const struct iio_chan_spec ltc2309_channels[] = {
struct ltc2309_chip_info {
const char *name;
const struct iio_chan_spec *channels;
unsigned int read_delay_us;
int num_channels;
const struct iio_chan_spec *channels __counted_by_ptr(num_channels);
};
static const struct ltc2309_chip_info ltc2305_chip_info = {
.name = "ltc2305",
.channels = ltc2305_channels,
.read_delay_us = 2,
.num_channels = ARRAY_SIZE(ltc2305_channels),
.channels = ltc2305_channels,
};
static const struct ltc2309_chip_info ltc2309_chip_info = {
.name = "ltc2309",
.channels = ltc2309_channels,
.num_channels = ARRAY_SIZE(ltc2309_channels),
.channels = ltc2309_channels,
};
static int ltc2309_read_raw_channel(struct ltc2309 *ltc2309,
@ -151,6 +157,9 @@ static int ltc2309_read_raw_channel(struct ltc2309 *ltc2309,
return ret;
}
if (ltc2309->read_delay_us)
fsleep(ltc2309->read_delay_us);
ret = i2c_master_recv(ltc2309->client, (char *)&buf, 2);
if (ret < 0) {
dev_err(ltc2309->dev, "i2c read failed: %pe\n", ERR_PTR(ret));
@ -206,6 +215,7 @@ static int ltc2309_probe(struct i2c_client *client)
ltc2309->dev = &indio_dev->dev;
ltc2309->client = client;
ltc2309->read_delay_us = chip_info->read_delay_us;
indio_dev->name = chip_info->name;
indio_dev->modes = INDIO_DIRECT_MODE;
@ -233,8 +243,8 @@ static const struct of_device_id ltc2309_of_match[] = {
MODULE_DEVICE_TABLE(of, ltc2309_of_match);
static const struct i2c_device_id ltc2309_id[] = {
{ "ltc2305", (kernel_ulong_t)&ltc2305_chip_info },
{ "ltc2309", (kernel_ulong_t)&ltc2309_chip_info },
{ .name = "ltc2305", .driver_data = (kernel_ulong_t)&ltc2305_chip_info },
{ .name = "ltc2309", .driver_data = (kernel_ulong_t)&ltc2309_chip_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc2309_id);

View File

@ -136,8 +136,8 @@ static int ltc2471_i2c_probe(struct i2c_client *client)
}
static const struct i2c_device_id ltc2471_i2c_id[] = {
{ "ltc2471", ltc2471 },
{ "ltc2473", ltc2473 },
{ .name = "ltc2471", .driver_data = ltc2471 },
{ .name = "ltc2473", .driver_data = ltc2473 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc2471_i2c_id);

View File

@ -124,7 +124,7 @@ static int ltc2485_probe(struct i2c_client *client)
}
static const struct i2c_device_id ltc2485_id[] = {
{ "ltc2485" },
{ .name = "ltc2485" },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc2485_id);

View File

@ -142,8 +142,8 @@ static const struct ltc2497_chip_info ltc2497_info[] = {
};
static const struct i2c_device_id ltc2497_id[] = {
{ "ltc2497", (kernel_ulong_t)&ltc2497_info[TYPE_LTC2497] },
{ "ltc2499", (kernel_ulong_t)&ltc2497_info[TYPE_LTC2499] },
{ .name = "ltc2497", .driver_data = (kernel_ulong_t)&ltc2497_info[TYPE_LTC2497] },
{ .name = "ltc2499", .driver_data = (kernel_ulong_t)&ltc2497_info[TYPE_LTC2499] },
{ }
};
MODULE_DEVICE_TABLE(i2c, ltc2497_id);

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