Zephyr ADC Configuration

Overview

ADC is used to measure VBUS, temperature and other values depending on a board.

Kconfig Options

The CONFIG_ADC option enables ADC support in the Zephyr EC application. Use the CONFIG_ADC_SHELL option to enable ADC related shell commands.

Refer to Kconfig.adc for all sub-options related to ADC support that are specific to the Zephyr EC application.

Devicetree Nodes

The EC chip disables all Analog-to-Digital Converters by default. Enable ADC used on your design by changing the chip-specific ADC status property to "okay".

ADC properties:

PropertyDescriptionSettings
statusEnables or disables the ADC module"okay"
"disabled"
labelOverride the EC chip specific label."ADC_<number>"

Either Nuvoton NPCX and ITE IT8xxx2 ECs use single a devicetree node adc0 to describe ADC, but it supports multiple ADC channels.

To enable the ADC set the status property to "okay":

&adc0 {
	status = "okay";
};

Mapping legacy ADC enums to ADC channels

The legacy ADC API for the Chromium EC application uses an enumeration (e.g. ADC_VBUS, ADC_AMON_BMON) to specify the ADC channel to measure voltage.

The named-adc-channels node creates the mapping between the legacy ADC channels enumeration and the Zephyr ADC driver's channel_id.

named-adc-channels {
	compatible = "named-adc-channels";
	vbus {
		enum-name = "ADC_VBUS";
		io-channels = <&adc0 1>;
		/* Measure VBUS through a 1/10 voltage divider */
		mul = <10>;
	};
};

Refer to the named-adc.yaml child-binding file for details about each property.

Board Specific Code

None required.

Threads

ADC support does not enable any threads.

Testing and Debugging

Unfortunately, the are two adc console commands: a Zephyr command and the one implemented in CrosEC. Only one of them can be enabled with CONFIG_ADC_SHELL or CONFIG_PLATFORM_EC_ADC_CMD respectively.

Zephyr command

The Zephyr adc includes the following subcommands:

SubcommandDescriptionUsage
acq_timeConfigure acquisition timeadc <adc_label> acq_time <time> <unit>
channelConfigure ADC channeladc <adc_label> channel id <channel_id>
gainConfigure gainadc <adc_label> gain <gain>
printPrint current configurationadc <adc_label> print
readRead adc valueadc <adc_label> read <channel>
referenceConfigure referenceadc <adc_label> reference <reference>
resolutionConfigure resolution for the read subcommandadc <adc_label> resolution <resolution>

Parameters summary:

ParameterDescription
<adc_label>The ADC label property. By default, this is specified by the EC vendor in the respective devicetree include file unless you override the label in your devicetree.
<time>For the acq_time subcommand, specifies the time of acquisition.
<unit>For the acq_time subcommand, specifies the unit of the time of acquisition: us, ns, ticks.
<channel_id>For the channel subcommand, specifies the channel ID.
<gain>For the gain subcommand, specifies the gain of the ADC measurement, e.g. GAIN_1_6, GAIN_2, GAIN_64.
<channel>ADC channel.
<reference>For the reference subcommand, specifies the reference for the ADC measurement, e.g. VDD_1, INTERNAL.
<resolution>For the resolution subcommand, specifies the resolution for the ADC conversion for the read subcommand.

E.g.

21-12-22 13:51:11.380 uart:~$ adc ADC_0 read 5
adc ADC_0 read 5
21-12-22 13:51:26.031 read: 1023

CrosEC command

The CrosEC shell command adc displays current ADC measurements, e.g.

21-12-21 09:58:03.746 uart:~$ adc
adc
21-12-21 09:58:05.322   ADC_VBUS = 14850 mV
21-12-21 09:58:05.325   ADC_AMON_BMON = 37111 mV
21-12-21 09:58:05.325   ADC_PSYS = 8432000 mV

Example

The image below shows the ADC wiring for the Volteer reference board.

ADC Example

The Volteer board uses Nuvoton NPCX EC that has one Analog-to-Digital Converter adc0, so enable it:

&adc0 {
	status = "okay";
};

The board has four temperature sensors handled with ADC. Map legacy cros-ec enums to ADC channels with the following values:

ADC Enumeration NameVolteer ADC channel
ADC_TEMP_SENSOR_CHARGERADC0
ADC_TEMP_SENSOR_PP3300_REGULATORADC1
ADC_TEMP_SENSOR_DDR_SOCADC8
ADC_TEMP_SENSOR_FANADC3

The Volteer project establishes this map using the named-adc-channels as shown below:

named-adc-channels {
	compatible = "named-adc-channels";

	adc_charger: charger {
		enum-name = "ADC_TEMP_SENSOR_CHARGER";
		io-channels = <&adc0 0>;
	};
	adc_pp3300_regulator: pp3300_regulator {
		enum-name = "ADC_TEMP_SENSOR_PP3300_REGULATOR";
		io-channels = <&adc0 1>;
	};
	adc_ddr_soc: ddr_soc {
		enum-name = "ADC_TEMP_SENSOR_DDR_SOC";
		io-channels = <&adc0 8>;
	};
	adc_fan: fan {
		enum-name = "ADC_TEMP_SENSOR_FAN";
		io-channels = <&adc0 3>;
	};
};