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 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 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 seconds = get_timer(0); 56 while (!irq_exit) 57 ; 58 59 irq_free_handler(TIMER_IRQ); 60 61 return 0; 62 } 63 #endif 64 65 static void timer_delay_test(void) 66 { 67 ulong delay = 100, delta; 68 u64 start; 69 70 printf("Timer delay:\n"); 71 72 start = get_ticks(); 73 udelay(delay); 74 delta = (get_ticks() - start) / 24UL; 75 printf(" Set %4luus, real %4luus\n", delay, delta); 76 77 start = get_ticks(); 78 mdelay(delay); 79 delta = (get_ticks() - start) / 24000UL; 80 printf(" Set %4lums, real %4lums\n", delay, delta); 81 82 start = get_ticks(); 83 mdelay(delay * 10UL); 84 delta = (get_ticks() - start) / 24000UL; 85 printf(" Set %4lums, real %4lums\n\n", delay * 10UL, delta); 86 } 87 88 int do_test_timer(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 89 { 90 timer_delay_test(); 91 92 #ifdef CONFIG_IRQ 93 timer_interrupt_test(); 94 #endif 95 return 0; 96 } 97 98 #ifdef CONFIG_RK_IR 99 static int ir_test(void) 100 { 101 struct udevice *dev; 102 int keycode, repeat; 103 int last_keycode; 104 int last_repeat; 105 ulong start; 106 int ret; 107 108 printf("\nYou have 30s to test ir, press them, start!\n"); 109 110 ret = uclass_get_device(UCLASS_RC, 0, &dev); 111 if (ret) { 112 ut_err("ir: failed to get device, ret=%d\n", ret); 113 goto out; 114 } 115 116 keycode = rc_get_keycode(dev); 117 if (keycode == -ENOSYS) { 118 ut_err("ir: failed to bind driver\n"); 119 goto out; 120 } 121 122 last_keycode = KEY_RESERVED; 123 last_repeat = KEY_RESERVED; 124 start = get_timer(0); 125 while (get_timer(start) <= 30000) { 126 mdelay(100); 127 128 keycode = rc_get_keycode(dev); 129 repeat = rc_get_repeat(dev); 130 if (keycode == KEY_RESERVED) 131 continue; 132 133 if (keycode != last_keycode || repeat != last_repeat) { 134 printf("ir: press key:0x%x repeat:%d\n", 135 keycode, repeat); 136 last_keycode = keycode; 137 last_repeat = repeat; 138 } 139 } 140 141 return 0; 142 143 out: 144 return -EINVAL; 145 } 146 147 int do_test_ir(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 148 { 149 return ir_test(); 150 } 151 #endif 152 153 #ifdef CONFIG_DM_KEY 154 int do_test_key(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 155 { 156 struct dm_key_uclass_platdata *key; 157 struct udevice *dev; 158 struct uclass *uc; 159 int ret, evt; 160 161 ret = uclass_get(UCLASS_KEY, &uc); 162 if (ret) 163 return ret; 164 165 printf("Please press any key button...\n"); 166 while (!ctrlc()) { 167 for (uclass_first_device(UCLASS_KEY, &dev); 168 dev; 169 uclass_next_device(&dev)) { 170 key = dev_get_uclass_platdata(dev); 171 evt = key_read(key->code); 172 if (evt == KEY_PRESS_DOWN) 173 printf("'%s' key pressed...\n", key->name); 174 else if (evt == KEY_PRESS_LONG_DOWN) 175 printf("'%s' key long pressed...\n", key->name); 176 177 mdelay(25); 178 } 179 } 180 181 return 0; 182 } 183 #endif 184 185 #ifdef CONFIG_DM_CRYPTO 186 static int do_test_crypto(cmd_tbl_t *cmdtp, int flag, 187 int argc, char *const argv[]) 188 { 189 return run_command("crypto", 0); 190 } 191 #endif 192 193 #ifdef CONFIG_ADC 194 static int do_test_adc(cmd_tbl_t *cmdtp, int flag, 195 int argc, char *const argv[]) 196 { 197 uint val, chn; 198 int ret; 199 200 chn = argc < 2 ? 0 : strtoul(argv[1], NULL, 10); 201 ret = adc_channel_single_shot("saradc", chn, &val); 202 if (ret) 203 ut_err("adc: failed to get channel%d value, ret=%d\n", chn, ret); 204 205 printf("adc channel%d: adc value is %d\n", chn, val); 206 207 return ret; 208 } 209 #endif 210 211 static cmd_tbl_t sub_cmd[] = { 212 #ifdef CONFIG_DM_CRYPTO 213 UNIT_CMD_DEFINE(crypto, 0), 214 #endif 215 #ifdef CONFIG_RK_IR 216 UNIT_CMD_ATTR_DEFINE(ir, 0, CMD_FLG_INTERACTIVE), 217 #endif 218 #ifdef CONFIG_DM_KEY 219 UNIT_CMD_ATTR_DEFINE(key, 0, CMD_FLG_INTERACTIVE), 220 #endif 221 #ifdef CONFIG_ADC 222 UNIT_CMD_DEFINE(adc, 0), 223 #endif 224 #ifdef CONFIG_IRQ 225 UNIT_CMD_DEFINE(timer, 0), 226 #endif 227 }; 228 229 static const char sub_cmd_help[] = 230 #ifdef CONFIG_DM_CRYPTO 231 " [.] rktest crypto - test crypto\n" 232 #endif 233 #ifdef CONFIG_RK_IR 234 " [i] rktest ir - test pwm ir remoter\n" 235 #endif 236 #ifdef CONFIG_DM_KEY 237 " [i] rktest key - test key buttons\n" 238 #endif 239 #ifdef CONFIG_ADC 240 " [.] rktest adc [chn] - test adc channel\n" 241 #endif 242 #ifdef CONFIG_IRQ 243 " [.] rktest timer - test timer and interrupt\n" 244 #endif 245 ; 246 247 const struct cmd_group cmd_grp_misc = { 248 .id = TEST_ID_MISC, 249 .help = sub_cmd_help, 250 .cmd = sub_cmd, 251 .cmd_n = ARRAY_SIZE(sub_cmd), 252 }; 253