Skip to content

drivers: adc: infineon: Support per-channel voltage reference selection for SAR ADC #104228

@laneb-infineon

Description

@laneb-infineon

Summary

See https://github.com/zephyrproject-rtos/zephyr/pull/103453/changes#diff-05b3ad7d958b304f5fb6e3bba41c85fd7b9b04a0b025f329a7e5d1039118c4eeR286-R315 for context.

The Infineon SAR ADC driver (adc_infineon_sar.c) currently enforces that all channels use the same voltage reference, matching the block-level vref-src devicetree property. During adc_channel_setup(), the driver validates that the channel's zephyr,reference (e.g., ADC_REF_INTERNAL, ADC_REF_VDD_1, ADC_REF_VDD_1_2) maps to the same source as the ADC node's vref-src, and returns -EINVAL on mismatch.

This means an application cannot configure one channel to use the internal 1.2V bandgap reference while another channel uses VDDA/2, even though the SAR hardware supports switching the reference between conversions by reconfiguring the VREF_SEL field in the SAR control register. The current implementation requires all channels to agree on a single reference, which limits flexibility in mixed-signal applications where different input ranges are needed on different channels.

Describe the solution you'd like

Allow per-channel voltage reference selection by:

  1. Storing the requested reference from adc_channel_cfg per channel (already done — data->channel_cfg[ch].reference).
  2. In psoc4_adc_configure_pdl() (or during the ISR-driven sequencer setup), dynamically reconfigure vrefSel and vrefMvValue in the SAR configuration on a per-channel basis before each channel's conversion starts.
  3. Remove or relax the current block-level validation in psoc4_adc_channel_setup() that rejects channels whose reference doesn't match vref-src. Instead, validate only that the requested reference is a supported type.
  4. Update the ref_internal field in the driver API (used by adc_raw_to_millivolts_dt()) to handle the case where different channels may report different effective vref values, or document that users should set zephyr,vref-mv on each channel node explicitly.

This may require SAR hardware re-initialization between channel conversions if channels in the same sequence use different references, which could impact throughput.

Alternatives

Allow mixed references only when channels are read individually (not in a multi-channel sequence), rejecting sequences that contain channels with differing references. This is simpler to implement since no mid-sequence reconfiguration is needed.

Additional Context

The PSOC 4 SAR ADC hardware supports four reference sources: internal 1.2V bandgap (CY_SAR_VREF_SEL_BGR), VDDA, VDDA/2, and external. The reference is selected via the SAR_CTRL.VREF_SEL bitfield, which can be changed between conversions. The current driver configures this once in psoc4_configure_reference() during psoc4_adc_configure_pdl() and applies it uniformly to all channels.

Relevant code:

  • Validation logic: psoc4_adc_channel_setup() in adc_infineon_sar.c
  • Reference configuration: psoc4_configure_reference() in the same file
  • Devicetree binding: dts/bindings/adc/infineon,sar-adc.yaml (vref-src property)

Metadata

Metadata

Assignees

Labels

EnhancementChanges/Updates/Additions to existing featuresarea: ADCAnalog-to-Digital Converter (ADC)platform: InfineonInfineon Technologies AG

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions