1 /*
2 * (C) Copyright 2019 Rockchip Electronics Co., Ltd
3 *
4 * SPDX-License-Identifier: GPL-2.0+
5 */
6
7 #include <common.h>
8 #include <adc.h>
9 #include <console.h>
10 #include <dm.h>
11 #include <key.h>
12 #include <misc.h>
13 #include <rc.h>
14 #ifdef CONFIG_IRQ
15 #include <irq-generic.h>
16 #include <rk_timer_irq.h>
17 #endif
18 #include <asm/io.h>
19 #include <linux/input.h>
20 #include "test-rockchip.h"
21
22 #ifdef CONFIG_IRQ
23 /* Must use volatile to avoid being optimized by complier */
24 static int volatile irq_exit;
25 static ulong seconds;
26
timer_irq_handler(int irq,void * data)27 static void timer_irq_handler(int irq, void *data)
28 {
29 int period;
30
31 writel(TIMER_CLR_INT, TIMER_BASE + TIMER_INTSTATUS);
32 period = get_timer(seconds);
33 printf(" Hello, this is timer isr: irq=%d, period=%dms\n", irq, period);
34
35 irq_exit = 1;
36 }
37
timer_interrupt_test(void)38 static int timer_interrupt_test(void)
39 {
40 printf("Timer interrupt:\n");
41
42 /* Disable before config */
43 writel(0, TIMER_BASE + TIMER_CTRL);
44
45 /* Configure 1s */
46 writel(COUNTER_FREQUENCY, TIMER_BASE + TIMER_LOAD_COUNT0);
47 writel(0, TIMER_BASE + TIMER_LOAD_COUNT1);
48 writel(TIMER_CLR_INT, TIMER_BASE + TIMER_INTSTATUS);
49 writel(TIMER_EN | TIMER_INT_EN, TIMER_BASE + TIMER_CTRL);
50
51 /* Request irq */
52 irq_install_handler(TIMER_IRQ, timer_irq_handler, NULL);
53 irq_handler_enable(TIMER_IRQ);
54
55 irq_exit = 0;
56 seconds = get_timer(0);
57 while (!irq_exit)
58 ;
59
60 irq_free_handler(TIMER_IRQ);
61
62 return 0;
63 }
64 #endif
65
timer_delay_test(void)66 static void timer_delay_test(void)
67 {
68 ulong delay = 100, delta;
69 u64 start;
70
71 printf("Timer delay:\n");
72
73 start = get_ticks();
74 udelay(delay);
75 delta = (get_ticks() - start) / 24UL;
76 printf(" Set %4luus, real %4luus\n", delay, delta);
77
78 start = get_ticks();
79 mdelay(delay);
80 delta = (get_ticks() - start) / 24000UL;
81 printf(" Set %4lums, real %4lums\n", delay, delta);
82
83 start = get_ticks();
84 mdelay(delay * 10UL);
85 delta = (get_ticks() - start) / 24000UL;
86 printf(" Set %4lums, real %4lums\n\n", delay * 10UL, delta);
87 }
88
do_test_timer(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])89 int do_test_timer(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
90 {
91 timer_delay_test();
92
93 #ifdef CONFIG_IRQ
94 timer_interrupt_test();
95 #endif
96 return 0;
97 }
98
99 #ifdef CONFIG_RK_IR
ir_test(void)100 static int ir_test(void)
101 {
102 struct udevice *dev;
103 int keycode, repeat;
104 int last_keycode;
105 int last_repeat;
106 ulong start;
107 int ret;
108
109 printf("\nYou have 30s to test ir, press them, start!\n");
110
111 ret = uclass_get_device(UCLASS_RC, 0, &dev);
112 if (ret) {
113 ut_err("ir: failed to get device, ret=%d\n", ret);
114 goto out;
115 }
116
117 keycode = rc_get_keycode(dev);
118 if (keycode == -ENOSYS) {
119 ut_err("ir: failed to bind driver\n");
120 goto out;
121 }
122
123 last_keycode = KEY_RESERVED;
124 last_repeat = KEY_RESERVED;
125 start = get_timer(0);
126 while (get_timer(start) <= 30000) {
127 mdelay(100);
128
129 keycode = rc_get_keycode(dev);
130 repeat = rc_get_repeat(dev);
131 if (keycode == KEY_RESERVED)
132 continue;
133
134 if (keycode != last_keycode || repeat != last_repeat) {
135 printf("ir: press key:0x%x repeat:%d\n",
136 keycode, repeat);
137 last_keycode = keycode;
138 last_repeat = repeat;
139 }
140 }
141
142 return 0;
143
144 out:
145 return -EINVAL;
146 }
147
do_test_ir(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])148 int do_test_ir(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
149 {
150 return ir_test();
151 }
152 #endif
153
154 #ifdef CONFIG_DM_KEY
do_test_key(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])155 int do_test_key(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
156 {
157 struct dm_key_uclass_platdata *key;
158 struct udevice *dev;
159 struct uclass *uc;
160 int ret, evt;
161
162 ret = uclass_get(UCLASS_KEY, &uc);
163 if (ret)
164 return ret;
165
166 printf("Please press any key button...\n");
167 while (!ctrlc()) {
168 for (uclass_first_device(UCLASS_KEY, &dev);
169 dev;
170 uclass_next_device(&dev)) {
171 key = dev_get_uclass_platdata(dev);
172 evt = key_read(key->code);
173 if (evt == KEY_PRESS_DOWN)
174 printf("'%s' key pressed...\n", key->name);
175 else if (evt == KEY_PRESS_LONG_DOWN)
176 printf("'%s' key long pressed...\n", key->name);
177
178 mdelay(25);
179 }
180 }
181
182 return 0;
183 }
184 #endif
185
186 #ifdef CONFIG_DM_CRYPTO
do_test_crypto(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])187 static int do_test_crypto(cmd_tbl_t *cmdtp, int flag,
188 int argc, char *const argv[])
189 {
190 return run_command("crypto", 0);
191 }
192 #endif
193
194 #ifdef CONFIG_ADC
do_test_adc(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])195 static int do_test_adc(cmd_tbl_t *cmdtp, int flag,
196 int argc, char *const argv[])
197 {
198 uint val, chn;
199 int ret;
200
201 chn = argc < 2 ? 0 : strtoul(argv[1], NULL, 10);
202 ret = adc_channel_single_shot("saradc", chn, &val);
203 if (ret)
204 ut_err("adc: failed to get channel%d value, ret=%d\n", chn, ret);
205
206 printf("adc channel%d: adc value is %d\n", chn, val);
207
208 return ret;
209 }
210 #endif
211
212 static cmd_tbl_t sub_cmd[] = {
213 #ifdef CONFIG_DM_CRYPTO
214 UNIT_CMD_DEFINE(crypto, 0),
215 #endif
216 #ifdef CONFIG_RK_IR
217 UNIT_CMD_ATTR_DEFINE(ir, 0, CMD_FLG_INTERACTIVE),
218 #endif
219 #ifdef CONFIG_DM_KEY
220 UNIT_CMD_ATTR_DEFINE(key, 0, CMD_FLG_INTERACTIVE),
221 #endif
222 #ifdef CONFIG_ADC
223 UNIT_CMD_DEFINE(adc, 0),
224 #endif
225 #ifdef CONFIG_IRQ
226 UNIT_CMD_DEFINE(timer, 0),
227 #endif
228 };
229
230 static const char sub_cmd_help[] =
231 #ifdef CONFIG_DM_CRYPTO
232 " [.] rktest crypto - test crypto\n"
233 #endif
234 #ifdef CONFIG_RK_IR
235 " [i] rktest ir - test pwm ir remoter\n"
236 #endif
237 #ifdef CONFIG_DM_KEY
238 " [i] rktest key - test key buttons\n"
239 #endif
240 #ifdef CONFIG_ADC
241 " [.] rktest adc [chn] - test adc channel\n"
242 #endif
243 #ifdef CONFIG_IRQ
244 " [.] rktest timer - test timer and interrupt\n"
245 #endif
246 ;
247
248 const struct cmd_group cmd_grp_misc = {
249 .id = TEST_ID_MISC,
250 .help = sub_cmd_help,
251 .cmd = sub_cmd,
252 .cmd_n = ARRAY_SIZE(sub_cmd),
253 };
254