/src/u-boot/test/dm/button.c
Line | Count | Source |
1 | | // SPDX-License-Identifier: GPL-2.0+ |
2 | | /* |
3 | | * Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com> |
4 | | * |
5 | | * Based on led.c |
6 | | */ |
7 | | |
8 | | #include <dm.h> |
9 | | #include <adc.h> |
10 | | #include <button.h> |
11 | | #include <env.h> |
12 | | #include <power/regulator.h> |
13 | | #include <power/sandbox_pmic.h> |
14 | | #include <asm/gpio.h> |
15 | | #include <dm/test.h> |
16 | | #include <dt-bindings/input/input.h> |
17 | | #include <test/ut.h> |
18 | | |
19 | | /* Base test of the button uclass */ |
20 | | static int dm_test_button_base(struct unit_test_state *uts) |
21 | 0 | { |
22 | 0 | struct udevice *dev; |
23 | | |
24 | | /* Get the top-level gpio buttons device */ |
25 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 0, &dev)); |
26 | | /* Get the 2 gpio buttons */ |
27 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &dev)); |
28 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &dev)); |
29 | | |
30 | | /* Get the top-level adc buttons device */ |
31 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 3, &dev)); |
32 | | /* Get the 3 adc buttons */ |
33 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 4, &dev)); |
34 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 5, &dev)); |
35 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 6, &dev)); |
36 | |
|
37 | 0 | ut_asserteq(-ENODEV, uclass_get_device(UCLASS_BUTTON, 7, &dev)); |
38 | |
|
39 | 0 | return 0; |
40 | 0 | } |
41 | | DM_TEST(dm_test_button_base, UTF_SCAN_PDATA | UTF_SCAN_FDT); |
42 | | |
43 | | /* Test of the button uclass using the button_gpio driver */ |
44 | | static int dm_test_button_gpio(struct unit_test_state *uts) |
45 | 0 | { |
46 | 0 | const int offset = 3; |
47 | 0 | struct udevice *dev, *gpio; |
48 | | |
49 | | /* |
50 | | * Check that we can manipulate a BUTTON. BUTTON 1 is connected to GPIO |
51 | | * bank gpio_a, offset 3. |
52 | | */ |
53 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &dev)); |
54 | 0 | ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio)); |
55 | |
|
56 | 0 | ut_asserteq(0, sandbox_gpio_set_value(gpio, offset, 0)); |
57 | 0 | ut_asserteq(0, sandbox_gpio_get_value(gpio, offset)); |
58 | 0 | ut_asserteq(BUTTON_OFF, button_get_state(dev)); |
59 | |
|
60 | 0 | ut_asserteq(0, sandbox_gpio_set_value(gpio, offset, 1)); |
61 | 0 | ut_asserteq(1, sandbox_gpio_get_value(gpio, offset)); |
62 | 0 | ut_asserteq(BUTTON_ON, button_get_state(dev)); |
63 | |
|
64 | 0 | return 0; |
65 | 0 | } |
66 | | DM_TEST(dm_test_button_gpio, UTF_SCAN_PDATA | UTF_SCAN_FDT); |
67 | | |
68 | | /* Test obtaining a BUTTON by label */ |
69 | | static int dm_test_button_label(struct unit_test_state *uts) |
70 | 0 | { |
71 | 0 | struct udevice *dev, *cmp; |
72 | |
|
73 | 0 | ut_assertok(button_get_by_label("button1", &dev)); |
74 | 0 | ut_asserteq(1, device_active(dev)); |
75 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &cmp)); |
76 | 0 | ut_asserteq_ptr(dev, cmp); |
77 | |
|
78 | 0 | ut_assertok(button_get_by_label("button2", &dev)); |
79 | 0 | ut_asserteq(1, device_active(dev)); |
80 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &cmp)); |
81 | 0 | ut_asserteq_ptr(dev, cmp); |
82 | |
|
83 | 0 | ut_asserteq(-ENODEV, button_get_by_label("nobutton", &dev)); |
84 | |
|
85 | 0 | return 0; |
86 | 0 | } |
87 | | DM_TEST(dm_test_button_label, UTF_SCAN_PDATA | UTF_SCAN_FDT); |
88 | | |
89 | | /* Test button has linux,code */ |
90 | | static int dm_test_button_linux_code(struct unit_test_state *uts) |
91 | 0 | { |
92 | 0 | struct udevice *dev; |
93 | |
|
94 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &dev)); |
95 | 0 | ut_asserteq(BTN_1, button_get_code(dev)); |
96 | |
|
97 | 0 | return 0; |
98 | 0 | } |
99 | | DM_TEST(dm_test_button_linux_code, UTF_SCAN_PDATA | UTF_SCAN_FDT); |
100 | | |
101 | | /* Test adc-keys driver */ |
102 | | static int dm_test_button_keys_adc(struct unit_test_state *uts) |
103 | 0 | { |
104 | 0 | struct udevice *supply; |
105 | 0 | struct udevice *dev; |
106 | 0 | int uV; |
107 | |
|
108 | 0 | ut_assertok(uclass_get_device_by_name(UCLASS_ADC, "adc@0", &dev)); |
109 | |
|
110 | 0 | ut_assertok(regulator_get_by_devname(SANDBOX_BUCK2_DEVNAME, &supply)); |
111 | 0 | ut_assertok(regulator_set_value(supply, SANDBOX_BUCK2_SET_UV)); |
112 | 0 | ut_asserteq(SANDBOX_BUCK2_SET_UV, regulator_get_value(supply)); |
113 | | /* Update ADC plat and get new Vdd value */ |
114 | 0 | ut_assertok(adc_vdd_value(dev, &uV)); |
115 | 0 | ut_asserteq(SANDBOX_BUCK2_SET_UV, uV); |
116 | | |
117 | | /* |
118 | | * sandbox-adc returns constant value on channel 3, is used by adc-keys: |
119 | | * SANDBOX_ADC_CHANNEL3_DATA * SANDBOX_BUCK2_SET_UV / SANDBOX_ADC_DATA_MASK = |
120 | | * 0x3000 * 3300000 / 0xffff = 618759uV |
121 | | * This means that button3 and button4 are released and button5 |
122 | | * is pressed. |
123 | | */ |
124 | 0 | ut_assertok(button_get_by_label("button3", &dev)); |
125 | 0 | ut_asserteq(BUTTON_OFF, button_get_state(dev)); |
126 | 0 | ut_assertok(button_get_by_label("button4", &dev)); |
127 | 0 | ut_asserteq(BUTTON_OFF, button_get_state(dev)); |
128 | 0 | ut_assertok(button_get_by_label("button5", &dev)); |
129 | 0 | ut_asserteq(BUTTON_ON, button_get_state(dev)); |
130 | |
|
131 | 0 | return 0; |
132 | 0 | } |
133 | | DM_TEST(dm_test_button_keys_adc, UTF_SCAN_PDATA | UTF_SCAN_FDT); |
134 | | |
135 | | /* Test of the button uclass using the button_gpio driver */ |
136 | | static int dm_test_button_cmd(struct unit_test_state *uts) |
137 | 0 | { |
138 | 0 | struct udevice *btn1_dev, *btn2_dev, *gpio; |
139 | 0 | const char *envstr; |
140 | |
|
141 | 0 | #define BTN1_GPIO 3 |
142 | 0 | #define BTN2_GPIO 4 |
143 | 0 | #define BTN1_PASS_VAR "test_button_cmds_0" |
144 | 0 | #define BTN2_PASS_VAR "test_button_cmds_1" |
145 | | |
146 | | /* |
147 | | * Buttons 1 and 2 are connected to gpio_a gpios 3 and 4 respectively. |
148 | | * set the GPIOs to known values and then check that the appropriate |
149 | | * commands are run when invoking process_button_cmds(). |
150 | | */ |
151 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 1, &btn1_dev)); |
152 | 0 | ut_assertok(uclass_get_device(UCLASS_BUTTON, 2, &btn2_dev)); |
153 | 0 | ut_assertok(uclass_get_device(UCLASS_GPIO, 1, &gpio)); |
154 | | |
155 | | /* |
156 | | * Map a command to button 1 and check that it process_button_cmds() |
157 | | * runs it if called with button 1 pressed. |
158 | | */ |
159 | 0 | ut_assertok(env_set("button_cmd_0_name", "button1")); |
160 | 0 | ut_assertok(env_set("button_cmd_0", "env set " BTN1_PASS_VAR " PASS")); |
161 | 0 | ut_assertok(sandbox_gpio_set_value(gpio, BTN1_GPIO, 1)); |
162 | | /* Sanity check that the button is actually pressed */ |
163 | 0 | ut_asserteq(BUTTON_ON, button_get_state(btn1_dev)); |
164 | 0 | process_button_cmds(); |
165 | 0 | ut_assertnonnull((envstr = env_get(BTN1_PASS_VAR))); |
166 | 0 | ut_asserteq_str(envstr, "PASS"); |
167 | | |
168 | | /* Clear result */ |
169 | 0 | ut_assertok(env_set(BTN1_PASS_VAR, NULL)); |
170 | | |
171 | | /* |
172 | | * Map a command for button 2, press it, check that only the command |
173 | | * for button 1 runs because it comes first and is also pressed. |
174 | | */ |
175 | 0 | ut_assertok(env_set("button_cmd_1_name", "button2")); |
176 | 0 | ut_assertok(env_set("button_cmd_1", "env set " BTN2_PASS_VAR " PASS")); |
177 | 0 | ut_assertok(sandbox_gpio_set_value(gpio, BTN2_GPIO, 1)); |
178 | 0 | ut_asserteq(BUTTON_ON, button_get_state(btn2_dev)); |
179 | 0 | process_button_cmds(); |
180 | | /* Check that button 1 triggered again */ |
181 | 0 | ut_assertnonnull((envstr = env_get(BTN1_PASS_VAR))); |
182 | 0 | ut_asserteq_str(envstr, "PASS"); |
183 | | /* And button 2 didn't */ |
184 | 0 | ut_assertnull(env_get(BTN2_PASS_VAR)); |
185 | | |
186 | | /* Clear result */ |
187 | 0 | ut_assertok(env_set(BTN1_PASS_VAR, NULL)); |
188 | | |
189 | | /* |
190 | | * Release button 1 and check that the command for button 2 is run |
191 | | */ |
192 | 0 | ut_assertok(sandbox_gpio_set_value(gpio, BTN1_GPIO, 0)); |
193 | 0 | process_button_cmds(); |
194 | 0 | ut_assertnull(env_get(BTN1_PASS_VAR)); |
195 | | /* Check that the command for button 2 ran */ |
196 | 0 | ut_assertnonnull((envstr = env_get(BTN2_PASS_VAR))); |
197 | 0 | ut_asserteq_str(envstr, "PASS"); |
198 | | |
199 | | /* Clear result */ |
200 | 0 | ut_assertok(env_set(BTN2_PASS_VAR, NULL)); |
201 | | |
202 | | /* |
203 | | * Unset "button_cmd_0_name" and check that no commands run even |
204 | | * with both buttons pressed. |
205 | | */ |
206 | 0 | ut_assertok(env_set("button_cmd_0_name", NULL)); |
207 | | /* Press button 1 (button 2 is already pressed )*/ |
208 | 0 | ut_assertok(sandbox_gpio_set_value(gpio, BTN1_GPIO, 1)); |
209 | 0 | ut_asserteq(BUTTON_ON, button_get_state(btn1_dev)); |
210 | 0 | process_button_cmds(); |
211 | 0 | ut_assertnull(env_get(BTN1_PASS_VAR)); |
212 | 0 | ut_assertnull(env_get(BTN2_PASS_VAR)); |
213 | | |
214 | | /* |
215 | | * Check that no command is run if the button name is wrong. |
216 | | */ |
217 | 0 | ut_assertok(env_set("button_cmd_0_name", "invalid_button")); |
218 | 0 | process_button_cmds(); |
219 | 0 | ut_assertnull(env_get(BTN1_PASS_VAR)); |
220 | 0 | ut_assertnull(env_get(BTN2_PASS_VAR)); |
221 | |
|
222 | 0 | #undef BTN1_PASS_VAR |
223 | 0 | #undef BTN2_PASS_VAR |
224 | 0 | #undef BTN1_GPIO |
225 | 0 | #undef BTN2_GPIO |
226 | |
|
227 | 0 | return 0; |
228 | 0 | } |
229 | | DM_TEST(dm_test_button_cmd, UTF_SCAN_PDATA | UTF_SCAN_FDT); |