Skip to content

Conversation

@laneb-infineon
Copy link
Contributor

@laneb-infineon laneb-infineon commented Feb 4, 2026

This enables ADC driver support for PSOC4-based boards including cy8ckit_041s_max and cy8cproto_041tp.

This supercedes #101600

@zephyrbot zephyrbot added area: ADC Analog-to-Digital Converter (ADC) area: Clock Control area: Devicetree Binding PR modifies or adds a Device Tree binding platform: Infineon Infineon Technologies AG area: Boards/SoCs area: Samples Samples area: Tests Issues related to a particular existing or missing test labels Feb 4, 2026
}

/* Check for 12-bit resolution */
if (sequence->resolution == 12) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A define here will not make this more readable.

#define RESOLUTIION_12B 12 is not more readable than sequence->resolution == 12 here

data->channel_configs[ch].differential = ch_cfg->differential;
data->channel_configs[ch].avgEn = (sequence->oversampling > 0);
data->channel_configs[ch].resolution =
(sequence->resolution == 12) ? CY_SAR_MAX_RES : CY_SAR_SUB_RES;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto as above, the resolution will not be more readable from a define here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These sorts of broad "replace X with Y" comments are not helpful, #define'ing numbers is not always more readable and numbers with easily understood context (e.g. resolution = 12) won't be anymore readable by having a #define for them.

If you have suggestions on numbers that would benefit then by all means suggest it. But please do not dictate terms on how to change code without reasoning behind it.

/* Configure ADC sample times */
static void psoc4_configure_sample_times(struct psoc4_adc_data *data)
{
data->pdl_sar_cfg.sampleTime0 = data->sample_times[0] ? data->sample_times[0] : 3;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

@laneb-infineon laneb-infineon force-pushed the cy8ckit_041s_max_adc branch 2 times, most recently from a2ed841 to 0d56b99 Compare February 10, 2026 00:22
Copy link

@pablofsmelo pablofsmelo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am withdrawing my previous requested changes as I've reconsidered my position based on the technical discussion. Please disregard my previous review and proceed without my input.

Regarding the magic numbers, I still believe that using macros or defines would significantly improve code readability and ease future maintenance, but I’ll leave the final decision to the other maintainers.

Also, I tried to resolve my previous comments but was unable to, likely due to permission constraints. I kindly request someone with the necessary privileges to resolve/close them. Thank you.

@laneb-infineon laneb-infineon force-pushed the cy8ckit_041s_max_adc branch 3 times, most recently from 10baefb to 9bd0820 Compare February 11, 2026 21:44
@laneb-infineon
Copy link
Contributor Author

cy8ckit_041s_max Test Results

Results gathered with this commit

adc_dt

Expecting ~0.62V from readings

*** Booting Zephyr OS build v4.3.0-5842-g03122d393f9c ***
ADC reading[0]:
- adc@403a0000, channel 0: 1048 = 614 mV
- adc@403a0000, channel 1: 2094 = 613 mV
- adc@403a0000, channel 2: 2098 = 614 mV
ADC reading[1]:
- adc@403a0000, channel 0: 1045 = 612 mV
- adc@403a0000, channel 1: 2092 = 612 mV
- adc@403a0000, channel 2: 2098 = 614 mV
ADC reading[2]:
- adc@403a0000, channel 0: 1044 = 611 mV
- adc@403a0000, channel 1: 2094 = 613 mV
- adc@403a0000, channel 2: 2096 = 614 mV
ADC reading[3]:
- adc@403a0000, channel 0: 1044 = 611 mV
- adc@403a0000, channel 1: 2094 = 613 mV
- adc@403a0000, channel 2: 2096 = 614 mV

adc_sequence

Expecting ~0.62V from readings

*** Booting Zephyr OS build v4.3.0-5842-g03122d393f9c ***
ADC sequence reading [0]:
- adc@403a0000, channel 0, 5 sequence samples:
- - 2094 = 613mV
- - 2102 = 615mV
- - 2104 = 616mV
- - 2104 = 616mV
- - 2104 = 616mV
- adc@403a0000, channel 1, 5 sequence samples:
- - 1051 = 615mV
- - 1054 = 617mV
- - 1055 = 618mV
- - 1055 = 618mV
- - 1055 = 618mV
ADC sequence reading [1]:
- adc@403a0000, channel 0, 5 sequence samples:
- - 2092 = 612mV
- - 2102 = 615mV
- - 2104 = 616mV
- - 2104 = 616mV
- - 2104 = 616mV
- adc@403a0000, channel 1, 5 sequence samples:
- - 1051 = 615mV
- - 1054 = 617mV
- - 1055 = 618mV
- - 1055 = 618mV
- - 1055 = 618mV

adc_api

TESTSUITE adc_basic succeeded

------ TESTSUITE SUMMARY START ------

SUITE PASS - 100.00% [adc_basic]: pass = 6, fail = 0, skip = 0, total = 6 duration = 0.520 seconds
 - PASS - [adc_basic.test_adc_asynchronous_call] duration = 0.006 seconds
 - PASS - [adc_basic.test_adc_invalid_request] duration = 0.010 seconds
 - PASS - [adc_basic.test_adc_repeated_samplings] duration = 0.083 seconds
 - PASS - [adc_basic.test_adc_sample_one_channel] duration = 0.006 seconds
 - PASS - [adc_basic.test_adc_sample_two_channels] duration = 0.006 seconds
 - PASS - [adc_basic.test_adc_sample_with_interval] duration = 0.409 seconds

------ TESTSUITE SUMMARY END ------

===================================================================
PROJECT EXECUTION SUCCESSFUL

adc_error_cases

TESTSUITE adc_error_cases succeeded

------ TESTSUITE SUMMARY START ------

SUITE PASS - 100.00% [adc_error_cases]: pass = 7, fail = 0, skip = 0, total = 7 duration = 0.022 seconds
 - PASS - [adc_error_cases.test_adc_read_invalid_buffer] duration = 0.004 seconds
 - PASS - [adc_error_cases.test_adc_read_invalid_channels] duration = 0.003 seconds
 - PASS - [adc_error_cases.test_adc_read_invalid_oversampling] duration = 0.003 seconds
 - PASS - [adc_error_cases.test_adc_read_invalid_resolution] duration = 0.003 seconds
 - PASS - [adc_error_cases.test_adc_read_not_configured_channel] duration = 0.004 seconds
 - PASS - [adc_error_cases.test_adc_setup_invalid_gain] duration = 0.002 seconds
 - PASS - [adc_error_cases.test_adc_setup_invalid_reference] duration = 0.003 seconds

------ TESTSUITE SUMMARY END ------

===================================================================
PROJECT EXECUTION SUCCESSFUL

@laneb-infineon
Copy link
Contributor Author

cy8cproto_041tp Test Results

Results gathered with this commit

adc_dt

Expecting ~0.62V from readings

*** Booting Zephyr OS build v4.3.0-5842-g03122d393f9c ***
ADC reading[0]:
- adc@403a0000, channel 0: 2114 = 619 mV
- adc@403a0000, channel 1: 1045 = 612 mV
ADC reading[1]:
- adc@403a0000, channel 0: 2114 = 619 mV
- adc@403a0000, channel 1: 1046 = 612 mV
ADC reading[2]:
- adc@403a0000, channel 0: 2114 = 619 mV
- adc@403a0000, channel 1: 1044 = 611 mV
ADC reading[3]:
- adc@403a0000, channel 0: 2114 = 619 mV
- adc@403a0000, channel 1: 1046 = 612 mV

adc_sequence

Expecting ~0.62V from readings

*** Booting Zephyr OS build v4.3.0-5842-g03122d393f9c ***
ADC sequence reading [0]:
- adc@403a0000, channel 0, 5 sequence samples:
- - 2100 = 615mV
- - 2120 = 621mV
- - 2118 = 620mV
- - 2104 = 616mV
- - 2116 = 619mV
- adc@403a0000, channel 1, 5 sequence samples:
- - 1041 = 609mV
- - 1051 = 615mV
- - 1061 = 621mV
- - 1052 = 616mV
- - 1055 = 618mV
ADC sequence reading [1]:
- adc@403a0000, channel 0, 5 sequence samples:
- - 2108 = 617mV
- - 2108 = 617mV
- - 2126 = 622mV
- - 2118 = 620mV
- - 2124 = 622mV
- adc@403a0000, channel 1, 5 sequence samples:
- - 1046 = 612mV
- - 1054 = 617mV
- - 1054 = 617mV
- - 1053 = 616mV
- - 1050 = 615mV

adc_api

TESTSUITE adc_basic succeeded

------ TESTSUITE SUMMARY START ------

SUITE PASS - 100.00% [adc_basic]: pass = 6, fail = 0, skip = 0, total = 6 duration = 0.520 seconds
 - PASS - [adc_basic.test_adc_asynchronous_call] duration = 0.006 seconds
 - PASS - [adc_basic.test_adc_invalid_request] duration = 0.010 seconds
 - PASS - [adc_basic.test_adc_repeated_samplings] duration = 0.083 seconds
 - PASS - [adc_basic.test_adc_sample_one_channel] duration = 0.006 seconds
 - PASS - [adc_basic.test_adc_sample_two_channels] duration = 0.006 seconds
 - PASS - [adc_basic.test_adc_sample_with_interval] duration = 0.409 seconds

------ TESTSUITE SUMMARY END ------

===================================================================
PROJECT EXECUTION SUCCESSFUL

adc_error_cases

TESTSUITE adc_error_cases succeeded

------ TESTSUITE SUMMARY START ------

SUITE PASS - 100.00% [adc_error_cases]: pass = 7, fail = 0, skip = 0, total = 7 duration = 0.022 seconds
 - PASS - [adc_error_cases.test_adc_read_invalid_buffer] duration = 0.004 seconds
 - PASS - [adc_error_cases.test_adc_read_invalid_channels] duration = 0.003 seconds
 - PASS - [adc_error_cases.test_adc_read_invalid_oversampling] duration = 0.003 seconds
 - PASS - [adc_error_cases.test_adc_read_invalid_resolution] duration = 0.003 seconds
 - PASS - [adc_error_cases.test_adc_read_not_configured_channel] duration = 0.004 seconds
 - PASS - [adc_error_cases.test_adc_setup_invalid_gain] duration = 0.002 seconds
 - PASS - [adc_error_cases.test_adc_setup_invalid_reference] duration = 0.003 seconds

------ TESTSUITE SUMMARY END ------

===================================================================
PROJECT EXECUTION SUCCESSFUL

@laneb-infineon laneb-infineon changed the title boards: cy8ckit_041s_max: adc support drivers: adc: Add Infineon PSOC4 SAR ADC support Feb 11, 2026
Copy link
Contributor

@teburd teburd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to see a well done PR, its great to see the tests results here as well showing it works. A few comments, one of which I know will require a bit of finagling to work out. The other trivial.

I think we can safely say you have incorporated #101600 into this and given co-authorship in the commits, so its safe for @Deepika-aerlync to close that PR whenever comfortable and we can move forward with this one PR for the sar-adc support.

Thank you @Deepika-aerlync and others for the hard work!

.vref_mv = DT_INST_PROP(n, vref_mv), \
.clk_dst = (en_clk_dst_t)DT_INST_PROP(n, clk_dst), \
}; \
static const struct adc_driver_api adc_psoc4_driver_api_##n = { \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

# SPDX-License-Identifier: Apache-2.0

description: |
Infineon PSOC4 SAR ADC
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than tying this IP block to a part family (PSOC4) we should tie it to a version of the IP like the PDL drivers itself do.

We can do this with a compatible like (infineon,sar-adc-v2), an example here would be ST's I2C IP versioning

https://github.com/zephyrproject-rtos/zephyr/blob/main/dts/bindings/i2c/st%2Cstm32-i2c-v1.yaml
https://github.com/zephyrproject-rtos/zephyr/blob/main/drivers/i2c/Kconfig.stm32#L14

OR by adding (in case the IP is similar enough to others) adding version property

https://github.com/zephyrproject-rtos/zephyr/blob/main/dts/bindings/dma/nxp%2Cmcux-edma.yaml#L73

Which then gets use in Kconfig and/or code to vary things based on the version.

No strong preference on my part. The versioned compatible I think matches well with the PDL which also differentiates headers with -vX.h

https://github.com/zephyrproject-rtos/hal_infineon/tree/master/mtb-pdl-cat2/devices/include/ip

@Deepika-aerlync
Copy link
Contributor

Happy to see a well done PR, its great to see the tests results here as well showing it works. A few comments, one of which I know will require a bit of finagling to work out. The other trivial.

I think we can safely say you have incorporated #101600 into this and given co-authorship in the commits, so its safe for @Deepika-aerlync to close that PR whenever comfortable and we can move forward with this one PR for the sar-adc support.

Thank you @Deepika-aerlync and others for the hard work!

PR #101600 has been closed. Thanks! @teburd

#include <zephyr/devicetree.h>
#include <zephyr/logging/log.h>
#include <zephyr/sys/util.h>
#include <zephyr/drivers/clock_control/clock_control_ifx_cat1.h>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be good to to add:

#include <infineon_kconfig.h>

This is consistent with other drivers, and will help ensure some PDL macros are defined correctly, such as CY_IP_M0S8PASS4A_SAR_VERSION.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

Comment on lines 681 to 682
LOG_ERR("Invalid SARMUX pin number: %d", ch_cfg->vplus);
return;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function has several error return paths, but the function is returning void so there is no indication that the function actually failed. Would it make sense to add an error code output here so the caller knows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

}

LOG_ERR("Invalid pin number %u for routing determination", pin);
return PSOC4_ADC_ROUTE_SARMUX; /* Fallback */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might make sense to return some kind of error code here to indicate an unsupported/invalid routing path.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

Comment on lines 427 to 430
} else if (data->channel_cfg[ch].vplus_routing ==
data->channel_cfg[ch].vminus_routing) {
routing_mismatch = true;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be routing_mismatch = false? It seems like you would want the routing to be the same for positive and negative channels.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Simplified logic, changed.

return -EINVAL;
}

if (data->channel_cfg[ch].vminus_routing == PSOC4_ADC_ROUTE_SARMUX) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any case covering vminus_routing == PSOC4_ADC_ROUTE_SARBUS. Is this not supported in differential mode?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

Comment on lines 69 to 70
zephyr,input-positive = <2>; /* SARMUX pin 2 = P2.2 (V+) */
zephyr,input-negative = <3>; /* SARMUX pin 3 = P2.3 (V-) */
Copy link
Contributor

@jsbatch jsbatch Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throughout the overlays in this PR, input-positive and input-negative are defined differently between the 4100tp and 4100smax boards. I think either is fine, but it'd be nice if we were consistent with which approach we use.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed.

laneb-infineon and others added 4 commits February 12, 2026 14:29
Add driver for the PSOC4 SAR ADC peripheral with device tree
binding. The driver supports:

- Single-ended and differential channel configuration
- Configurable resolution (8-12 bits)
- Multiple voltage reference sources (internal, VDDA, VDDA/2, external)
- Hardware compensation for SAR v2/v3 single-ended channel limitation
- Interrupt-driven conversion completion
- Integration with peripheral clock control

The driver includes a compile-time per-instance API structure to
correctly report reference voltage to the ADC framework for accurate
raw-to-millivolts conversion.

Tested on CY8CKIT-041S-MAX and CY8CPROTO-041TP boards.

Signed-off-by: Braeden Lane <[email protected]>
Co-authored-by: Deepika R <[email protected]>
Co-authored-by: Sayooj K Karun <[email protected]>
Extend the Infineon peripheral clock control driver to support
ADC peripherals. Adds IFX_RSC_ADC resource type handling and
PSOC4-specific clock destination initialization (set to 0 as
PSOC4 peripherals manage their own clock routing).

Signed-off-by: Braeden Lane <[email protected]>
Co-authored-by: Deepika R <[email protected]>
Co-authored-by: Sayooj K Karun <[email protected]>
Enable the SAR ADC peripheral on CY8CKIT-041S-MAX and
CY8CPROTO-041TP boards:

- Add ADC node to psoc4100smax.dtsi and psoc4100tp.dtsi
- Configure clk-dst for peripheral clock routing
  - 041S-MAX: PCLK_PASS0_CLOCK_SAR (0x12)
  - 041TP: PCLK_PASS0_CLOCK_SAR (0xc)
- Reference peri_clk_div4 for ADC clock source
- Enable peri_clk_div4 in board common devicetree includes

Signed-off-by: Braeden Lane <[email protected]>
Co-authored-by: Deepika R <[email protected]>
Co-authored-by: Sayooj K Karun <[email protected]>
Add device tree overlays for ADC samples and tests on
CY8CKIT-041S-MAX and CY8CPROTO-041TP boards.

Configures ADC channels with pinctrl for analog inputs on
available header pins. Includes single-ended and differential
channel configurations demonstrating various ADC features.

Added overlays for:
- samples/drivers/adc/adc_dt
- samples/drivers/adc/adc_sequence
- tests/drivers/adc/adc_api
- tests/drivers/adc/adc_error_cases

Signed-off-by: Braeden Lane <[email protected]>
Co-authored-by: Deepika R <[email protected]>
Co-authored-by: Sayooj K Karun <[email protected]>
@sonarqubecloud
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ADC Analog-to-Digital Converter (ADC) area: Boards/SoCs area: Clock Control area: Devicetree Binding PR modifies or adds a Device Tree binding area: Samples Samples area: Tests Issues related to a particular existing or missing test platform: Infineon Infineon Technologies AG

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants