xref: /openbmc/u-boot/test/dm/adc.c (revision e070dc422d98cd232a928ceba87ac448854b8f25)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2c48cb7ebSPrzemyslaw Marczak /*
3c48cb7ebSPrzemyslaw Marczak  * Tests for the driver model ADC API
4c48cb7ebSPrzemyslaw Marczak  *
5c48cb7ebSPrzemyslaw Marczak  * Copyright (c) 2015 Samsung Electronics
6c48cb7ebSPrzemyslaw Marczak  * Przemyslaw Marczak <p.marczak@samsung.com>
7c48cb7ebSPrzemyslaw Marczak  */
8c48cb7ebSPrzemyslaw Marczak 
9c48cb7ebSPrzemyslaw Marczak #include <common.h>
10c48cb7ebSPrzemyslaw Marczak #include <adc.h>
11c48cb7ebSPrzemyslaw Marczak #include <dm.h>
12c48cb7ebSPrzemyslaw Marczak #include <dm/root.h>
13c48cb7ebSPrzemyslaw Marczak #include <dm/util.h>
14c48cb7ebSPrzemyslaw Marczak #include <dm/test.h>
15c48cb7ebSPrzemyslaw Marczak #include <errno.h>
16c48cb7ebSPrzemyslaw Marczak #include <fdtdec.h>
17c48cb7ebSPrzemyslaw Marczak #include <power/regulator.h>
18c48cb7ebSPrzemyslaw Marczak #include <power/sandbox_pmic.h>
19c48cb7ebSPrzemyslaw Marczak #include <sandbox-adc.h>
20c48cb7ebSPrzemyslaw Marczak #include <test/ut.h>
21c48cb7ebSPrzemyslaw Marczak 
dm_test_adc_bind(struct unit_test_state * uts)22c48cb7ebSPrzemyslaw Marczak static int dm_test_adc_bind(struct unit_test_state *uts)
23c48cb7ebSPrzemyslaw Marczak {
24c48cb7ebSPrzemyslaw Marczak 	struct udevice *dev;
25*63f004e7SFabrice Gasnier 	unsigned int channel_mask;
26c48cb7ebSPrzemyslaw Marczak 
27c48cb7ebSPrzemyslaw Marczak 	ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev));
28c48cb7ebSPrzemyslaw Marczak 	ut_asserteq_str(SANDBOX_ADC_DEVNAME, dev->name);
29c48cb7ebSPrzemyslaw Marczak 
30*63f004e7SFabrice Gasnier 	ut_assertok(adc_channel_mask(dev, &channel_mask));
31*63f004e7SFabrice Gasnier 	ut_asserteq((1 << SANDBOX_ADC_CHANNELS) - 1, channel_mask);
32*63f004e7SFabrice Gasnier 
33c48cb7ebSPrzemyslaw Marczak 	return 0;
34c48cb7ebSPrzemyslaw Marczak }
35c48cb7ebSPrzemyslaw Marczak DM_TEST(dm_test_adc_bind, DM_TESTF_SCAN_FDT);
36c48cb7ebSPrzemyslaw Marczak 
dm_test_adc_wrong_channel_selection(struct unit_test_state * uts)37c48cb7ebSPrzemyslaw Marczak static int dm_test_adc_wrong_channel_selection(struct unit_test_state *uts)
38c48cb7ebSPrzemyslaw Marczak {
39c48cb7ebSPrzemyslaw Marczak 	struct udevice *dev;
40c48cb7ebSPrzemyslaw Marczak 
41c48cb7ebSPrzemyslaw Marczak 	ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev));
42c48cb7ebSPrzemyslaw Marczak 	ut_asserteq(-EINVAL, adc_start_channel(dev, SANDBOX_ADC_CHANNELS));
43c48cb7ebSPrzemyslaw Marczak 
44c48cb7ebSPrzemyslaw Marczak 	return 0;
45c48cb7ebSPrzemyslaw Marczak }
46c48cb7ebSPrzemyslaw Marczak DM_TEST(dm_test_adc_wrong_channel_selection, DM_TESTF_SCAN_FDT);
47c48cb7ebSPrzemyslaw Marczak 
dm_test_adc_supply(struct unit_test_state * uts)48c48cb7ebSPrzemyslaw Marczak static int dm_test_adc_supply(struct unit_test_state *uts)
49c48cb7ebSPrzemyslaw Marczak {
50c48cb7ebSPrzemyslaw Marczak 	struct udevice *supply;
51c48cb7ebSPrzemyslaw Marczak 	struct udevice *dev;
52c48cb7ebSPrzemyslaw Marczak 	int uV;
53c48cb7ebSPrzemyslaw Marczak 
54c48cb7ebSPrzemyslaw Marczak 	ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev));
55c48cb7ebSPrzemyslaw Marczak 
56c48cb7ebSPrzemyslaw Marczak 	/* Test Vss value - predefined 0 uV */
57c48cb7ebSPrzemyslaw Marczak 	ut_assertok(adc_vss_value(dev, &uV));
58c48cb7ebSPrzemyslaw Marczak 	ut_asserteq(SANDBOX_ADC_VSS_VALUE, uV);
59c48cb7ebSPrzemyslaw Marczak 
60c48cb7ebSPrzemyslaw Marczak 	/* Test Vdd initial value - buck2 */
61c48cb7ebSPrzemyslaw Marczak 	ut_assertok(adc_vdd_value(dev, &uV));
62c48cb7ebSPrzemyslaw Marczak 	ut_asserteq(SANDBOX_BUCK2_INITIAL_EXPECTED_UV, uV);
63c48cb7ebSPrzemyslaw Marczak 
64c48cb7ebSPrzemyslaw Marczak 	/* Change Vdd value - buck2 manual preset */
65c48cb7ebSPrzemyslaw Marczak 	ut_assertok(regulator_get_by_devname(SANDBOX_BUCK2_DEVNAME, &supply));
66c48cb7ebSPrzemyslaw Marczak 	ut_assertok(regulator_set_value(supply, SANDBOX_BUCK2_SET_UV));
67c48cb7ebSPrzemyslaw Marczak 	ut_asserteq(SANDBOX_BUCK2_SET_UV, regulator_get_value(supply));
68c48cb7ebSPrzemyslaw Marczak 
69c48cb7ebSPrzemyslaw Marczak 	/* Update ADC platdata and get new Vdd value */
70c48cb7ebSPrzemyslaw Marczak 	ut_assertok(adc_vdd_value(dev, &uV));
71c48cb7ebSPrzemyslaw Marczak 	ut_asserteq(SANDBOX_BUCK2_SET_UV, uV);
72c48cb7ebSPrzemyslaw Marczak 
73c48cb7ebSPrzemyslaw Marczak 	/* Disable buck2 and test ADC supply enable function */
74c48cb7ebSPrzemyslaw Marczak 	ut_assertok(regulator_set_enable(supply, false));
75c48cb7ebSPrzemyslaw Marczak 	ut_asserteq(false, regulator_get_enable(supply));
76c48cb7ebSPrzemyslaw Marczak 	/* adc_start_channel() should enable the supply regulator */
77c48cb7ebSPrzemyslaw Marczak 	ut_assertok(adc_start_channel(dev, 0));
78c48cb7ebSPrzemyslaw Marczak 	ut_asserteq(true, regulator_get_enable(supply));
79c48cb7ebSPrzemyslaw Marczak 
80c48cb7ebSPrzemyslaw Marczak 	return 0;
81c48cb7ebSPrzemyslaw Marczak }
82c48cb7ebSPrzemyslaw Marczak DM_TEST(dm_test_adc_supply, DM_TESTF_SCAN_FDT);
83c48cb7ebSPrzemyslaw Marczak 
84c48cb7ebSPrzemyslaw Marczak struct adc_channel adc_channel_test_data[] = {
85c48cb7ebSPrzemyslaw Marczak 	{ 0, SANDBOX_ADC_CHANNEL0_DATA },
86c48cb7ebSPrzemyslaw Marczak 	{ 1, SANDBOX_ADC_CHANNEL1_DATA },
87c48cb7ebSPrzemyslaw Marczak 	{ 2, SANDBOX_ADC_CHANNEL2_DATA },
88c48cb7ebSPrzemyslaw Marczak 	{ 3, SANDBOX_ADC_CHANNEL3_DATA },
89c48cb7ebSPrzemyslaw Marczak };
90c48cb7ebSPrzemyslaw Marczak 
dm_test_adc_single_channel_conversion(struct unit_test_state * uts)91c48cb7ebSPrzemyslaw Marczak static int dm_test_adc_single_channel_conversion(struct unit_test_state *uts)
92c48cb7ebSPrzemyslaw Marczak {
93c48cb7ebSPrzemyslaw Marczak 	struct adc_channel *tdata = adc_channel_test_data;
94c48cb7ebSPrzemyslaw Marczak 	unsigned int i, data;
95c48cb7ebSPrzemyslaw Marczak 	struct udevice *dev;
96c48cb7ebSPrzemyslaw Marczak 
97c48cb7ebSPrzemyslaw Marczak 	ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev));
98c48cb7ebSPrzemyslaw Marczak 	/* Test each ADC channel's value */
99c48cb7ebSPrzemyslaw Marczak 	for (i = 0; i < SANDBOX_ADC_CHANNELS; i++, tdata++) {
100c48cb7ebSPrzemyslaw Marczak 		ut_assertok(adc_start_channel(dev, tdata->id));
101c48cb7ebSPrzemyslaw Marczak 		ut_assertok(adc_channel_data(dev, tdata->id, &data));
102c48cb7ebSPrzemyslaw Marczak 		ut_asserteq(tdata->data, data);
103c48cb7ebSPrzemyslaw Marczak 	}
104c48cb7ebSPrzemyslaw Marczak 
105c48cb7ebSPrzemyslaw Marczak 	return 0;
106c48cb7ebSPrzemyslaw Marczak }
107c48cb7ebSPrzemyslaw Marczak DM_TEST(dm_test_adc_single_channel_conversion, DM_TESTF_SCAN_FDT);
108c48cb7ebSPrzemyslaw Marczak 
dm_test_adc_multi_channel_conversion(struct unit_test_state * uts)109c48cb7ebSPrzemyslaw Marczak static int dm_test_adc_multi_channel_conversion(struct unit_test_state *uts)
110c48cb7ebSPrzemyslaw Marczak {
111c48cb7ebSPrzemyslaw Marczak 	struct adc_channel channels[SANDBOX_ADC_CHANNELS];
112c48cb7ebSPrzemyslaw Marczak 	struct udevice *dev;
113c48cb7ebSPrzemyslaw Marczak 	struct adc_channel *tdata = adc_channel_test_data;
114c48cb7ebSPrzemyslaw Marczak 	unsigned int i, channel_mask;
115c48cb7ebSPrzemyslaw Marczak 
116c48cb7ebSPrzemyslaw Marczak 	channel_mask = ADC_CHANNEL(0) | ADC_CHANNEL(1) |
117c48cb7ebSPrzemyslaw Marczak 		       ADC_CHANNEL(2) | ADC_CHANNEL(3);
118c48cb7ebSPrzemyslaw Marczak 
119c48cb7ebSPrzemyslaw Marczak 	/* Start multi channel conversion */
120c48cb7ebSPrzemyslaw Marczak 	ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev));
121c48cb7ebSPrzemyslaw Marczak 	ut_assertok(adc_start_channels(dev, channel_mask));
122c48cb7ebSPrzemyslaw Marczak 	ut_assertok(adc_channels_data(dev, channel_mask, channels));
123c48cb7ebSPrzemyslaw Marczak 
124c48cb7ebSPrzemyslaw Marczak 	/* Compare the expected and returned conversion data. */
125c48cb7ebSPrzemyslaw Marczak 	for (i = 0; i < SANDBOX_ADC_CHANNELS; i++, tdata++)
126c48cb7ebSPrzemyslaw Marczak 		ut_asserteq(tdata->data, channels[i].data);
127c48cb7ebSPrzemyslaw Marczak 
128c48cb7ebSPrzemyslaw Marczak 	return 0;
129c48cb7ebSPrzemyslaw Marczak }
130c48cb7ebSPrzemyslaw Marczak DM_TEST(dm_test_adc_multi_channel_conversion, DM_TESTF_SCAN_FDT);
131c48cb7ebSPrzemyslaw Marczak 
dm_test_adc_single_channel_shot(struct unit_test_state * uts)132c48cb7ebSPrzemyslaw Marczak static int dm_test_adc_single_channel_shot(struct unit_test_state *uts)
133c48cb7ebSPrzemyslaw Marczak {
134c48cb7ebSPrzemyslaw Marczak 	struct adc_channel *tdata = adc_channel_test_data;
135c48cb7ebSPrzemyslaw Marczak 	unsigned int i, data;
136c48cb7ebSPrzemyslaw Marczak 
137c48cb7ebSPrzemyslaw Marczak 	for (i = 0; i < SANDBOX_ADC_CHANNELS; i++, tdata++) {
138c48cb7ebSPrzemyslaw Marczak 		/* Start single channel conversion */
139c48cb7ebSPrzemyslaw Marczak 		ut_assertok(adc_channel_single_shot("adc", tdata->id, &data));
140c48cb7ebSPrzemyslaw Marczak 		/* Compare the expected and returned conversion data. */
141c48cb7ebSPrzemyslaw Marczak 		ut_asserteq(tdata->data, data);
142c48cb7ebSPrzemyslaw Marczak 	}
143c48cb7ebSPrzemyslaw Marczak 
144c48cb7ebSPrzemyslaw Marczak 	return 0;
145c48cb7ebSPrzemyslaw Marczak }
146c48cb7ebSPrzemyslaw Marczak DM_TEST(dm_test_adc_single_channel_shot, DM_TESTF_SCAN_FDT);
147c48cb7ebSPrzemyslaw Marczak 
dm_test_adc_multi_channel_shot(struct unit_test_state * uts)148c48cb7ebSPrzemyslaw Marczak static int dm_test_adc_multi_channel_shot(struct unit_test_state *uts)
149c48cb7ebSPrzemyslaw Marczak {
150c48cb7ebSPrzemyslaw Marczak 	struct adc_channel channels[SANDBOX_ADC_CHANNELS];
151c48cb7ebSPrzemyslaw Marczak 	struct adc_channel *tdata = adc_channel_test_data;
152c48cb7ebSPrzemyslaw Marczak 	unsigned int i, channel_mask;
153c48cb7ebSPrzemyslaw Marczak 
154c48cb7ebSPrzemyslaw Marczak 	channel_mask = ADC_CHANNEL(0) | ADC_CHANNEL(1) |
155c48cb7ebSPrzemyslaw Marczak 		       ADC_CHANNEL(2) | ADC_CHANNEL(3);
156c48cb7ebSPrzemyslaw Marczak 
157c48cb7ebSPrzemyslaw Marczak 	/* Start single call and multi channel conversion */
158c48cb7ebSPrzemyslaw Marczak 	ut_assertok(adc_channels_single_shot("adc", channel_mask, channels));
159c48cb7ebSPrzemyslaw Marczak 
160c48cb7ebSPrzemyslaw Marczak 	/* Compare the expected and returned conversion data. */
161c48cb7ebSPrzemyslaw Marczak 	for (i = 0; i < SANDBOX_ADC_CHANNELS; i++, tdata++)
162c48cb7ebSPrzemyslaw Marczak 		ut_asserteq(tdata->data, channels[i].data);
163c48cb7ebSPrzemyslaw Marczak 
164c48cb7ebSPrzemyslaw Marczak 	return 0;
165c48cb7ebSPrzemyslaw Marczak }
166c48cb7ebSPrzemyslaw Marczak DM_TEST(dm_test_adc_multi_channel_shot, DM_TESTF_SCAN_FDT);
167*63f004e7SFabrice Gasnier 
168*63f004e7SFabrice Gasnier static const int dm_test_adc_uV_data[SANDBOX_ADC_CHANNELS] = {
169*63f004e7SFabrice Gasnier 	((u64)SANDBOX_ADC_CHANNEL0_DATA * SANDBOX_BUCK2_INITIAL_EXPECTED_UV) /
170*63f004e7SFabrice Gasnier 		SANDBOX_ADC_DATA_MASK,
171*63f004e7SFabrice Gasnier 	((u64)SANDBOX_ADC_CHANNEL1_DATA * SANDBOX_BUCK2_INITIAL_EXPECTED_UV) /
172*63f004e7SFabrice Gasnier 		SANDBOX_ADC_DATA_MASK,
173*63f004e7SFabrice Gasnier 	((u64)SANDBOX_ADC_CHANNEL2_DATA * SANDBOX_BUCK2_INITIAL_EXPECTED_UV) /
174*63f004e7SFabrice Gasnier 		SANDBOX_ADC_DATA_MASK,
175*63f004e7SFabrice Gasnier 	((u64)SANDBOX_ADC_CHANNEL3_DATA * SANDBOX_BUCK2_INITIAL_EXPECTED_UV) /
176*63f004e7SFabrice Gasnier 		SANDBOX_ADC_DATA_MASK,
177*63f004e7SFabrice Gasnier };
178*63f004e7SFabrice Gasnier 
dm_test_adc_raw_to_uV(struct unit_test_state * uts)179*63f004e7SFabrice Gasnier static int dm_test_adc_raw_to_uV(struct unit_test_state *uts)
180*63f004e7SFabrice Gasnier {
181*63f004e7SFabrice Gasnier 	struct adc_channel *tdata = adc_channel_test_data;
182*63f004e7SFabrice Gasnier 	unsigned int i, data;
183*63f004e7SFabrice Gasnier 	struct udevice *dev;
184*63f004e7SFabrice Gasnier 	int uV;
185*63f004e7SFabrice Gasnier 
186*63f004e7SFabrice Gasnier 	ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc", &dev));
187*63f004e7SFabrice Gasnier 	/* Test each ADC channel's value in microvolts */
188*63f004e7SFabrice Gasnier 	for (i = 0; i < SANDBOX_ADC_CHANNELS; i++, tdata++) {
189*63f004e7SFabrice Gasnier 		ut_assertok(adc_start_channel(dev, tdata->id));
190*63f004e7SFabrice Gasnier 		ut_assertok(adc_channel_data(dev, tdata->id, &data));
191*63f004e7SFabrice Gasnier 		ut_assertok(adc_raw_to_uV(dev, data, &uV));
192*63f004e7SFabrice Gasnier 		ut_asserteq(dm_test_adc_uV_data[i], uV);
193*63f004e7SFabrice Gasnier 	}
194*63f004e7SFabrice Gasnier 
195*63f004e7SFabrice Gasnier 	return 0;
196*63f004e7SFabrice Gasnier }
197*63f004e7SFabrice Gasnier DM_TEST(dm_test_adc_raw_to_uV, DM_TESTF_SCAN_FDT);
198