/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ /* * common/cmd_irkey.c * * Copyright (C) 2020 Amlogic, Inc. All rights reserved. * */ #include #include #include #include #include #include #include #define KEY_PARAMS_NUM 10 #define OTHER_PARAMS_NUM 1 #define MAX_KEY_NUM 16 enum IrMboxCmdType { IR_MBOX_CMD_SET_WAKEUP_LIST, IR_MBOX_CMD_SET_DEBUG_LOG, IR_MBOX_CMD_GET_WAKEUP_KEY, IR_MBOX_CMD_SET_STATUS, IR_MBOX_CMD_GET_PREBOOT_KEY }; extern uint32_t get_time(void); void init_custom_trigger(void) { #ifdef P_AO_RTI_PIN_MUX_REG if (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_GXTVBB) { setbits_le32(P_AO_RTI_PIN_MUX_REG, 1 << 12); // SET IR_DEC_INPUT } else { setbits_le32(P_AO_RTI_PIN_MUX_REG, 1 << 0); // SET IR_DEC_INPUT clrbits_le32(P_AO_RTI_PIN_MUX_REG, 1 << 21); //CLEAR IR_REMOTE_OUTPUT } #endif #ifdef AO_RTI_PINMUX_REG0 writel((readl(AO_RTI_PINMUX_REG0) & ~(0xf << 20)), AO_RTI_PINMUX_REG0); writel((readl(AO_RTI_PINMUX_REG0) | (0x1 << 20)), AO_RTI_PINMUX_REG0); #endif writel((readl(P_AO_MF_IR_DEC_REG1) | (1 << 15)), P_AO_MF_IR_DEC_REG1); } void ir_release(void) { #ifdef P_AO_RTI_PIN_MUX_REG if (get_cpu_id().family_id == MESON_CPU_MAJOR_ID_GXTVBB) { clrbits_le32(P_AO_RTI_PIN_MUX_REG, 1 << 12); } else { clrbits_le32(P_AO_RTI_PIN_MUX_REG, 1 << 0); } #endif } uint32_t read_key(void) { unsigned int keycode; if (!(readl(P_AO_MF_IR_DEC_STATUS) & (1<<3))) { return 0; } keycode = readl(P_AO_MF_IR_DEC_FRAME); printf("keycode = %x\n",keycode); return keycode; } int update_for_dtb_wakeup_key(void) { const void *nodep; /* property node pointer */ int nodeoffset; /* node offset from libfdt */ int len, j, i; /* length of the property */ const __be32 *p; u32 framecode, ret; u32 data[MAX_KEY_NUM + 3] = {IR_MBOX_CMD_SET_WAKEUP_LIST, 0, 0}; run_command("fdt addr $dtb_mem_addr", 0); nodeoffset = fdt_path_offset(working_fdt, "/ir_wakeup_key"); if (nodeoffset < 0) { printf("libfdt fdt_path_offset() returned %s\n", fdt_strerror(nodeoffset)); return 1; } nodep = fdt_getprop(working_fdt, nodeoffset, "wakeup_key", &len); if (!nodep || len <= 0) { printf("libfdt fdt_getprop(): %s\n", fdt_strerror(len)); return 1; } for (i = 0, j = 0, p = nodep; j < len / 4; j += 3) { data[i + 3] = fdt32_to_cpu(p[j]); i++; if (i != MAX_KEY_NUM) continue; i = 0; data[1] = 16; ret = scpi_send_data(AOCPU_REE_CHANNEL, CMD_SET_IR_STATE, data, sizeof(data), &framecode, sizeof(framecode)); if (ret != 0) printf("CMD_SET_IR_STATE failed\n"); } data[1] = i; ret = scpi_send_data(AOCPU_REE_CHANNEL, CMD_SET_IR_STATE, data, sizeof(data), &framecode, sizeof(framecode)); if (ret != 0) printf("CMD_SET_IR_STATE failed\n"); printf("update bl30 wakeup key from DTB\n"); return 0; } static int do_irkey(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint32_t key_buf[KEY_PARAMS_NUM]; uint32_t time_out = 0; uint32_t time_base = 0; uint32_t key; char *endp; char str[8]; u8 i; /*at least set a key*/ if (argc < 3) return -1; /*obtain timeout time*/ time_out = simple_strtoul(argv[1], &endp, 0); printf("time_out = %x\n",time_out); if (*argv[1] == 0 || *endp != 0) return -1; /*obtain IR keys value which need to detect*/ for (i=2; i ... - maximum value of N: 10", NULL ); U_BOOT_CMD(irkey_wakeup, (MAX_KEY_NUM + 3 + 1), 0, do_irkey_wakeup, "irkey_wakeup", "0 ... \n" " - set wakeup table\n" "irkey_wakeup 1 <1|0> - enable/disable bl30 ir debug log\n" "irkey_wakeup 2 - get ir_wakeup_key\n" "irkey_wakeup 3 <1|0> - enable/disable bl30 ir\n" "irkey_wakeup 4 - get ir_preboot_key\n" "irkey_wakeup update4dtb - update wakeup key for dtb\n" );