199d14b01SJoseph Chen /* 299d14b01SJoseph Chen * (C) Copyright 2019 Rockchip Electronics Co., Ltd 399d14b01SJoseph Chen * 499d14b01SJoseph Chen * SPDX-License-Identifier: GPL-2.0+ 599d14b01SJoseph Chen */ 699d14b01SJoseph Chen 799d14b01SJoseph Chen #include <common.h> 899d14b01SJoseph Chen #include <adc.h> 999d14b01SJoseph Chen #include <console.h> 1099d14b01SJoseph Chen #include <dm.h> 1199d14b01SJoseph Chen #include <key.h> 1299d14b01SJoseph Chen #include <misc.h> 1399d14b01SJoseph Chen #include <rc.h> 1499d14b01SJoseph Chen #ifdef CONFIG_IRQ 1599d14b01SJoseph Chen #include <irq-generic.h> 1699d14b01SJoseph Chen #include <rk_timer_irq.h> 1799d14b01SJoseph Chen #endif 1899d14b01SJoseph Chen #include <asm/io.h> 1999d14b01SJoseph Chen #include <linux/input.h> 2099d14b01SJoseph Chen #include "test-rockchip.h" 2199d14b01SJoseph Chen 2299d14b01SJoseph Chen #ifdef CONFIG_IRQ 2399d14b01SJoseph Chen /* Must use volatile to avoid being optimized by complier */ 2499d14b01SJoseph Chen static int volatile irq_exit; 2599d14b01SJoseph Chen static ulong seconds; 2699d14b01SJoseph Chen 2799d14b01SJoseph Chen static void timer_irq_handler(int irq, void *data) 2899d14b01SJoseph Chen { 2999d14b01SJoseph Chen int period; 3099d14b01SJoseph Chen 3199d14b01SJoseph Chen writel(TIMER_CLR_INT, TIMER_BASE + TIMER_INTSTATUS); 3299d14b01SJoseph Chen period = get_timer(seconds); 3399d14b01SJoseph Chen printf(" Hello, this is timer isr: irq=%d, period=%dms\n", irq, period); 3499d14b01SJoseph Chen 3599d14b01SJoseph Chen irq_exit = 1; 3699d14b01SJoseph Chen } 3799d14b01SJoseph Chen 3899d14b01SJoseph Chen static int timer_interrupt_test(void) 3999d14b01SJoseph Chen { 4099d14b01SJoseph Chen printf("Timer interrupt:\n"); 4199d14b01SJoseph Chen 4299d14b01SJoseph Chen /* Disable before config */ 4399d14b01SJoseph Chen writel(0, TIMER_BASE + TIMER_CTRL); 4499d14b01SJoseph Chen 4599d14b01SJoseph Chen /* Configure 1s */ 4699d14b01SJoseph Chen writel(COUNTER_FREQUENCY, TIMER_BASE + TIMER_LOAD_COUNT0); 4799d14b01SJoseph Chen writel(0, TIMER_BASE + TIMER_LOAD_COUNT1); 4899d14b01SJoseph Chen writel(TIMER_CLR_INT, TIMER_BASE + TIMER_INTSTATUS); 4999d14b01SJoseph Chen writel(TIMER_EN | TIMER_INT_EN, TIMER_BASE + TIMER_CTRL); 5099d14b01SJoseph Chen 5199d14b01SJoseph Chen /* Request irq */ 5299d14b01SJoseph Chen irq_install_handler(TIMER_IRQ, timer_irq_handler, NULL); 5399d14b01SJoseph Chen irq_handler_enable(TIMER_IRQ); 5499d14b01SJoseph Chen 5539e1dbd6SJoseph Chen irq_exit = 0; 5699d14b01SJoseph Chen seconds = get_timer(0); 5799d14b01SJoseph Chen while (!irq_exit) 5899d14b01SJoseph Chen ; 5999d14b01SJoseph Chen 6099d14b01SJoseph Chen irq_free_handler(TIMER_IRQ); 6199d14b01SJoseph Chen 6299d14b01SJoseph Chen return 0; 6399d14b01SJoseph Chen } 6499d14b01SJoseph Chen #endif 6599d14b01SJoseph Chen 6699d14b01SJoseph Chen static void timer_delay_test(void) 6799d14b01SJoseph Chen { 6899d14b01SJoseph Chen ulong delay = 100, delta; 6999d14b01SJoseph Chen u64 start; 7099d14b01SJoseph Chen 7199d14b01SJoseph Chen printf("Timer delay:\n"); 7299d14b01SJoseph Chen 7399d14b01SJoseph Chen start = get_ticks(); 7499d14b01SJoseph Chen udelay(delay); 7599d14b01SJoseph Chen delta = (get_ticks() - start) / 24UL; 7699d14b01SJoseph Chen printf(" Set %4luus, real %4luus\n", delay, delta); 7799d14b01SJoseph Chen 7899d14b01SJoseph Chen start = get_ticks(); 7999d14b01SJoseph Chen mdelay(delay); 8099d14b01SJoseph Chen delta = (get_ticks() - start) / 24000UL; 8199d14b01SJoseph Chen printf(" Set %4lums, real %4lums\n", delay, delta); 8299d14b01SJoseph Chen 8399d14b01SJoseph Chen start = get_ticks(); 8499d14b01SJoseph Chen mdelay(delay * 10UL); 8599d14b01SJoseph Chen delta = (get_ticks() - start) / 24000UL; 8699d14b01SJoseph Chen printf(" Set %4lums, real %4lums\n\n", delay * 10UL, delta); 8799d14b01SJoseph Chen } 8899d14b01SJoseph Chen 8999d14b01SJoseph Chen int do_test_timer(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 9099d14b01SJoseph Chen { 9199d14b01SJoseph Chen timer_delay_test(); 9299d14b01SJoseph Chen 9399d14b01SJoseph Chen #ifdef CONFIG_IRQ 9499d14b01SJoseph Chen timer_interrupt_test(); 9599d14b01SJoseph Chen #endif 9699d14b01SJoseph Chen return 0; 9799d14b01SJoseph Chen } 9899d14b01SJoseph Chen 9999d14b01SJoseph Chen #ifdef CONFIG_RK_IR 10099d14b01SJoseph Chen static int ir_test(void) 10199d14b01SJoseph Chen { 10299d14b01SJoseph Chen struct udevice *dev; 10399d14b01SJoseph Chen int keycode, repeat; 10499d14b01SJoseph Chen int last_keycode; 10599d14b01SJoseph Chen int last_repeat; 10699d14b01SJoseph Chen ulong start; 10799d14b01SJoseph Chen int ret; 10899d14b01SJoseph Chen 10999d14b01SJoseph Chen printf("\nYou have 30s to test ir, press them, start!\n"); 11099d14b01SJoseph Chen 11199d14b01SJoseph Chen ret = uclass_get_device(UCLASS_RC, 0, &dev); 11299d14b01SJoseph Chen if (ret) { 113443feaabSJoseph Chen ut_err("ir: failed to get device, ret=%d\n", ret); 11499d14b01SJoseph Chen goto out; 11599d14b01SJoseph Chen } 11699d14b01SJoseph Chen 11799d14b01SJoseph Chen keycode = rc_get_keycode(dev); 11899d14b01SJoseph Chen if (keycode == -ENOSYS) { 119443feaabSJoseph Chen ut_err("ir: failed to bind driver\n"); 12099d14b01SJoseph Chen goto out; 12199d14b01SJoseph Chen } 12299d14b01SJoseph Chen 12399d14b01SJoseph Chen last_keycode = KEY_RESERVED; 12499d14b01SJoseph Chen last_repeat = KEY_RESERVED; 12599d14b01SJoseph Chen start = get_timer(0); 12699d14b01SJoseph Chen while (get_timer(start) <= 30000) { 12799d14b01SJoseph Chen mdelay(100); 12899d14b01SJoseph Chen 12999d14b01SJoseph Chen keycode = rc_get_keycode(dev); 13099d14b01SJoseph Chen repeat = rc_get_repeat(dev); 13199d14b01SJoseph Chen if (keycode == KEY_RESERVED) 13299d14b01SJoseph Chen continue; 13399d14b01SJoseph Chen 13499d14b01SJoseph Chen if (keycode != last_keycode || repeat != last_repeat) { 135443feaabSJoseph Chen printf("ir: press key:0x%x repeat:%d\n", 13699d14b01SJoseph Chen keycode, repeat); 13799d14b01SJoseph Chen last_keycode = keycode; 13899d14b01SJoseph Chen last_repeat = repeat; 13999d14b01SJoseph Chen } 14099d14b01SJoseph Chen } 14199d14b01SJoseph Chen 14299d14b01SJoseph Chen return 0; 14399d14b01SJoseph Chen 14499d14b01SJoseph Chen out: 14599d14b01SJoseph Chen return -EINVAL; 14699d14b01SJoseph Chen } 14799d14b01SJoseph Chen 14899d14b01SJoseph Chen int do_test_ir(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 14999d14b01SJoseph Chen { 15099d14b01SJoseph Chen return ir_test(); 15199d14b01SJoseph Chen } 15299d14b01SJoseph Chen #endif 15399d14b01SJoseph Chen 15499d14b01SJoseph Chen #ifdef CONFIG_DM_KEY 15599d14b01SJoseph Chen int do_test_key(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 15699d14b01SJoseph Chen { 15799d14b01SJoseph Chen struct dm_key_uclass_platdata *key; 15899d14b01SJoseph Chen struct udevice *dev; 15999d14b01SJoseph Chen struct uclass *uc; 16099d14b01SJoseph Chen int ret, evt; 16199d14b01SJoseph Chen 16299d14b01SJoseph Chen ret = uclass_get(UCLASS_KEY, &uc); 16399d14b01SJoseph Chen if (ret) 16499d14b01SJoseph Chen return ret; 16599d14b01SJoseph Chen 16699d14b01SJoseph Chen printf("Please press any key button...\n"); 16799d14b01SJoseph Chen while (!ctrlc()) { 16899d14b01SJoseph Chen for (uclass_first_device(UCLASS_KEY, &dev); 16999d14b01SJoseph Chen dev; 17099d14b01SJoseph Chen uclass_next_device(&dev)) { 17199d14b01SJoseph Chen key = dev_get_uclass_platdata(dev); 17299d14b01SJoseph Chen evt = key_read(key->code); 17399d14b01SJoseph Chen if (evt == KEY_PRESS_DOWN) 17499d14b01SJoseph Chen printf("'%s' key pressed...\n", key->name); 17599d14b01SJoseph Chen else if (evt == KEY_PRESS_LONG_DOWN) 17699d14b01SJoseph Chen printf("'%s' key long pressed...\n", key->name); 17799d14b01SJoseph Chen 17899d14b01SJoseph Chen mdelay(25); 17999d14b01SJoseph Chen } 18099d14b01SJoseph Chen } 18199d14b01SJoseph Chen 18299d14b01SJoseph Chen return 0; 18399d14b01SJoseph Chen } 18499d14b01SJoseph Chen #endif 18599d14b01SJoseph Chen 18699d14b01SJoseph Chen #ifdef CONFIG_DM_CRYPTO 18799d14b01SJoseph Chen static int do_test_crypto(cmd_tbl_t *cmdtp, int flag, 18899d14b01SJoseph Chen int argc, char *const argv[]) 18999d14b01SJoseph Chen { 19099d14b01SJoseph Chen return run_command("crypto", 0); 19199d14b01SJoseph Chen } 19299d14b01SJoseph Chen #endif 19399d14b01SJoseph Chen 19499d14b01SJoseph Chen #ifdef CONFIG_ADC 19599d14b01SJoseph Chen static int do_test_adc(cmd_tbl_t *cmdtp, int flag, 19699d14b01SJoseph Chen int argc, char *const argv[]) 19799d14b01SJoseph Chen { 19899d14b01SJoseph Chen uint val, chn; 19999d14b01SJoseph Chen int ret; 20099d14b01SJoseph Chen 20199d14b01SJoseph Chen chn = argc < 2 ? 0 : strtoul(argv[1], NULL, 10); 20299d14b01SJoseph Chen ret = adc_channel_single_shot("saradc", chn, &val); 203443feaabSJoseph Chen if (ret) 204*a6c9ff86SJoseph Chen ret = adc_channel_single_shot("adc", chn, &val); 205*a6c9ff86SJoseph Chen if (ret) 206443feaabSJoseph Chen ut_err("adc: failed to get channel%d value, ret=%d\n", chn, ret); 207443feaabSJoseph Chen 20899d14b01SJoseph Chen printf("adc channel%d: adc value is %d\n", chn, val); 20999d14b01SJoseph Chen 21099d14b01SJoseph Chen return ret; 21199d14b01SJoseph Chen } 21299d14b01SJoseph Chen #endif 21399d14b01SJoseph Chen 21499d14b01SJoseph Chen static cmd_tbl_t sub_cmd[] = { 21599d14b01SJoseph Chen #ifdef CONFIG_DM_CRYPTO 21699d14b01SJoseph Chen UNIT_CMD_DEFINE(crypto, 0), 21799d14b01SJoseph Chen #endif 21899d14b01SJoseph Chen #ifdef CONFIG_RK_IR 21999d14b01SJoseph Chen UNIT_CMD_ATTR_DEFINE(ir, 0, CMD_FLG_INTERACTIVE), 22099d14b01SJoseph Chen #endif 22199d14b01SJoseph Chen #ifdef CONFIG_DM_KEY 22299d14b01SJoseph Chen UNIT_CMD_ATTR_DEFINE(key, 0, CMD_FLG_INTERACTIVE), 22399d14b01SJoseph Chen #endif 22499d14b01SJoseph Chen #ifdef CONFIG_ADC 22599d14b01SJoseph Chen UNIT_CMD_DEFINE(adc, 0), 22699d14b01SJoseph Chen #endif 22799d14b01SJoseph Chen #ifdef CONFIG_IRQ 22899d14b01SJoseph Chen UNIT_CMD_DEFINE(timer, 0), 22999d14b01SJoseph Chen #endif 23099d14b01SJoseph Chen }; 23199d14b01SJoseph Chen 23299d14b01SJoseph Chen static const char sub_cmd_help[] = 23399d14b01SJoseph Chen #ifdef CONFIG_DM_CRYPTO 23499d14b01SJoseph Chen " [.] rktest crypto - test crypto\n" 23599d14b01SJoseph Chen #endif 23699d14b01SJoseph Chen #ifdef CONFIG_RK_IR 23799d14b01SJoseph Chen " [i] rktest ir - test pwm ir remoter\n" 23899d14b01SJoseph Chen #endif 23999d14b01SJoseph Chen #ifdef CONFIG_DM_KEY 24099d14b01SJoseph Chen " [i] rktest key - test key buttons\n" 24199d14b01SJoseph Chen #endif 24299d14b01SJoseph Chen #ifdef CONFIG_ADC 24399d14b01SJoseph Chen " [.] rktest adc [chn] - test adc channel\n" 24499d14b01SJoseph Chen #endif 24599d14b01SJoseph Chen #ifdef CONFIG_IRQ 24699d14b01SJoseph Chen " [.] rktest timer - test timer and interrupt\n" 24799d14b01SJoseph Chen #endif 24899d14b01SJoseph Chen ; 24999d14b01SJoseph Chen 25099d14b01SJoseph Chen const struct cmd_group cmd_grp_misc = { 25199d14b01SJoseph Chen .id = TEST_ID_MISC, 25299d14b01SJoseph Chen .help = sub_cmd_help, 25399d14b01SJoseph Chen .cmd = sub_cmd, 25499d14b01SJoseph Chen .cmd_n = ARRAY_SIZE(sub_cmd), 25599d14b01SJoseph Chen }; 256