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