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 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 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 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 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 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 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 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 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 ret = adc_channel_single_shot("adc", chn, &val); 205 if (ret) 206 ut_err("adc: failed to get channel%d value, ret=%d\n", chn, ret); 207 208 printf("adc channel%d: adc value is %d\n", chn, val); 209 210 return ret; 211 } 212 #endif 213 214 static cmd_tbl_t sub_cmd[] = { 215 #ifdef CONFIG_DM_CRYPTO 216 UNIT_CMD_DEFINE(crypto, 0), 217 #endif 218 #ifdef CONFIG_RK_IR 219 UNIT_CMD_ATTR_DEFINE(ir, 0, CMD_FLG_INTERACTIVE), 220 #endif 221 #ifdef CONFIG_DM_KEY 222 UNIT_CMD_ATTR_DEFINE(key, 0, CMD_FLG_INTERACTIVE), 223 #endif 224 #ifdef CONFIG_ADC 225 UNIT_CMD_DEFINE(adc, 0), 226 #endif 227 #ifdef CONFIG_IRQ 228 UNIT_CMD_DEFINE(timer, 0), 229 #endif 230 }; 231 232 static const char sub_cmd_help[] = 233 #ifdef CONFIG_DM_CRYPTO 234 " [.] rktest crypto - test crypto\n" 235 #endif 236 #ifdef CONFIG_RK_IR 237 " [i] rktest ir - test pwm ir remoter\n" 238 #endif 239 #ifdef CONFIG_DM_KEY 240 " [i] rktest key - test key buttons\n" 241 #endif 242 #ifdef CONFIG_ADC 243 " [.] rktest adc [chn] - test adc channel\n" 244 #endif 245 #ifdef CONFIG_IRQ 246 " [.] rktest timer - test timer and interrupt\n" 247 #endif 248 ; 249 250 const struct cmd_group cmd_grp_misc = { 251 .id = TEST_ID_MISC, 252 .help = sub_cmd_help, 253 .cmd = sub_cmd, 254 .cmd_n = ARRAY_SIZE(sub_cmd), 255 }; 256