You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2132 lines
61 KiB
2132 lines
61 KiB
/*
|
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
|
|
* Description: ioctl functions
|
|
*/
|
|
|
|
#define LOG_MODULE_ID SOC_ID_PM
|
|
#define LOG_FUNC_TRACE 1
|
|
|
|
#include "drv_pmoc.h"
|
|
#include "drv_pmoc_debug.h"
|
|
|
|
#include <linux/huanglong/securec.h>
|
|
#include <asm/io.h>
|
|
|
|
#include "soc_log.h"
|
|
#include "drv_sys_ext.h"
|
|
#include "td_type.h"
|
|
#include "osal_ext.h"
|
|
#include "drv_ioctl_pmoc.h"
|
|
#include "drv_pmoc_adapt.h"
|
|
#include "drv_pmoc_lpmcu_config.h"
|
|
|
|
|
|
#define INVALID_VALUE 0xffffffff
|
|
|
|
#define GPIO_BITS_PER_GROUP 8
|
|
|
|
#define PMOC_LOG_PRINT_LEN 65
|
|
|
|
#define MCU_NODE "huanglong-mcu-custom0"
|
|
|
|
typedef struct {
|
|
td_u32 cmd;
|
|
td_s32(*f_driver_cmd_process)(td_void *arg);
|
|
} pmoc_ioctl_map;
|
|
|
|
typedef struct {
|
|
ext_pmoc_wakeup_src source;
|
|
td_s32(*f_driver_suspend_param_process)(td_bool set, pmoc_cmd_suspend_attr *attr);
|
|
} pmoc_suspend_param_process_map;
|
|
|
|
#ifndef CONFIG_SOCT_COMMON_KERNEL
|
|
#ifndef CONFIG_SOCT_OH_KERNEL
|
|
static td_u32 g_s3_s4_gpio_num;
|
|
static td_u32 g_s3_s4_gpio_group[S3_S4_OPERATION_NUM];
|
|
static td_u32 g_s3_s4_gpio_bit[S3_S4_OPERATION_NUM];
|
|
static td_u32 g_s3_gpio_level[S3_S4_OPERATION_NUM];
|
|
static td_u32 g_s4_gpio_level[S3_S4_OPERATION_NUM];
|
|
#endif
|
|
#endif
|
|
|
|
static pmoc_wakeup_message g_wakeup_message;
|
|
static td_u32 *g_lpmcu_base = TD_NULL;
|
|
static osal_semaphore g_pmoc_sem;
|
|
static ext_pmoc_wakeup_type g_wakeup_type = EXT_PMOC_WAKEUP_TO_DDR;
|
|
static pmoc_dts_info g_dts_info;
|
|
static osal_task *g_pmoc_thread = TD_NULL;
|
|
|
|
td_void pmoc_set_shutdown_type(ext_pmoc_wakeup_type type)
|
|
{
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_RESUME_RESET_ADDR / sizeof(td_u32);
|
|
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
tmp.val8[2] = type; /* 2: array offset value */
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
|
|
soc_dbg_func_exit();
|
|
|
|
return;
|
|
}
|
|
|
|
static td_s32 pmoc_ir_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
td_u32 i;
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_IR_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
if (attr->param.ir_param.ir_num >= EXT_PMOC_WAKEUP_IRKEY_MAXNUM) {
|
|
attr->param.ir_param.ir_num = EXT_PMOC_WAKEUP_IRKEY_MAXNUM;
|
|
}
|
|
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = attr->enable;
|
|
tmp.val8[1] = attr->param.ir_param.ir_type;
|
|
tmp.val8[2] = attr->param.ir_param.ir_num; /* 2: array offset value */
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
|
|
for (i = 0; i < attr->param.ir_param.ir_num; i++) {
|
|
writel(attr->param.ir_param.ir_low_val[i], lpmcu_vir_addr++);
|
|
writel(attr->param.ir_param.ir_high_val[i], lpmcu_vir_addr++);
|
|
}
|
|
} else {
|
|
tmp.val32 = readl(lpmcu_vir_addr++);
|
|
attr->enable = tmp.val8[0];
|
|
attr->param.ir_param.ir_type = tmp.val8[1];
|
|
attr->param.ir_param.ir_num = tmp.val8[2]; /* 2: array offset value */
|
|
|
|
if (attr->param.ir_param.ir_num >= EXT_PMOC_WAKEUP_IRKEY_MAXNUM) {
|
|
attr->param.ir_param.ir_num = EXT_PMOC_WAKEUP_IRKEY_MAXNUM;
|
|
}
|
|
|
|
for (i = 0; i < attr->param.ir_param.ir_num; i++) {
|
|
attr->param.ir_param.ir_low_val[i] = readl(lpmcu_vir_addr++);
|
|
attr->param.ir_param.ir_high_val[i] = readl(lpmcu_vir_addr++);
|
|
}
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_keyled_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_KEYLED_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
writel(attr->enable, lpmcu_vir_addr++);
|
|
writel(attr->param.keyled_param.keyled_type, lpmcu_vir_addr++);
|
|
writel(attr->param.keyled_param.wakeup_key, lpmcu_vir_addr++);
|
|
} else {
|
|
attr->enable = readl(lpmcu_vir_addr++);
|
|
attr->param.keyled_param.keyled_type = readl(lpmcu_vir_addr++);
|
|
attr->param.keyled_param.wakeup_key = readl(lpmcu_vir_addr++);
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_gpio_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
td_u32 i;
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_GPIO_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
if (attr->param.gpio_param.num >= EXT_PMOC_WAKEUP_GPIO_MAXNUM) {
|
|
attr->param.gpio_param.num = EXT_PMOC_WAKEUP_GPIO_MAXNUM;
|
|
}
|
|
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = attr->enable;
|
|
tmp.val8[1] = attr->param.gpio_param.num;
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
|
|
for (i = 0; i < attr->param.gpio_param.num; i++) {
|
|
if (attr->param.gpio_param.group[i] > g_dts_info.gpio_aon_group_max ||
|
|
attr->param.gpio_param.group[i] < g_dts_info.gpio_aon_group_min) {
|
|
soc_err_print_info("gpio aon group is illegal\n");
|
|
soc_err_print_u32(i);
|
|
soc_err_print_u32(attr->param.gpio_param.group[i]);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = attr->param.gpio_param.group[i];
|
|
tmp.val8[1] = attr->param.gpio_param.bit[i];
|
|
tmp.val8[2] = attr->param.gpio_param.interrupt_type[i]; /* 2: array offset value */
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
}
|
|
} else {
|
|
tmp.val32 = readl(lpmcu_vir_addr++);
|
|
attr->enable = tmp.val8[0];
|
|
attr->param.gpio_param.num = tmp.val8[1];
|
|
|
|
if (attr->param.gpio_param.num >= EXT_PMOC_WAKEUP_GPIO_MAXNUM) {
|
|
attr->param.gpio_param.num = EXT_PMOC_WAKEUP_GPIO_MAXNUM;
|
|
}
|
|
|
|
for (i = 0; i < attr->param.gpio_param.num; i++) {
|
|
tmp.val32 = readl(lpmcu_vir_addr++);
|
|
attr->param.gpio_param.group[i] = tmp.val8[0];
|
|
attr->param.gpio_param.bit[i] = tmp.val8[1];
|
|
attr->param.gpio_param.interrupt_type[i] = tmp.val8[2]; /* 2: array offset value */
|
|
}
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_lsadc_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
td_u32 i;
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_LSADC_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = attr->enable;
|
|
tmp.val8[1] = attr->param.lsadc_param.channel_mask;
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
|
|
for (i = 0; i < EXT_PMOC_LSADC_CHANNEL_MAXNUM; i++) {
|
|
tmp.val32 = 0;
|
|
tmp.val16[0] = attr->param.lsadc_param.key_value_range[i].low;
|
|
tmp.val16[1] = attr->param.lsadc_param.key_value_range[i].high;
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
}
|
|
} else {
|
|
tmp.val32 = readl(lpmcu_vir_addr++);
|
|
attr->enable = tmp.val8[0];
|
|
attr->param.lsadc_param.channel_mask = tmp.val8[1];
|
|
|
|
for (i = 0; i < EXT_PMOC_LSADC_CHANNEL_MAXNUM; i++) {
|
|
tmp.val32 = readl(lpmcu_vir_addr++);
|
|
attr->param.lsadc_param.key_value_range[i].low = tmp.val16[0];
|
|
attr->param.lsadc_param.key_value_range[i].high = tmp.val16[1];
|
|
}
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_uart_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_UART_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = attr->enable;
|
|
tmp.val8[1] = attr->param.uart_param.wakeup_key;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
} else {
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
attr->enable = tmp.val8[0];
|
|
attr->param.uart_param.wakeup_key = tmp.val8[1];
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_eth_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_ETH_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = attr->enable;
|
|
tmp.val8[1] = attr->param.eth_param.mute_wakeup_enable;
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
writel(attr->param.eth_param.time_to_passive_standby, lpmcu_vir_addr);
|
|
} else {
|
|
tmp.val32 = readl(lpmcu_vir_addr++);
|
|
attr->enable = tmp.val8[0];
|
|
attr->param.eth_param.mute_wakeup_enable = tmp.val8[1];
|
|
attr->param.eth_param.time_to_passive_standby = readl(lpmcu_vir_addr);
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_usb_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 usb_mask;
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_USB_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = attr->enable;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
|
|
soc_info_print_h32(attr->param.usb_param.usb_wakeup_mask);
|
|
ret = pmoc_set_usb_wakeup_mask(attr->param.usb_param.usb_wakeup_mask);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_set_usb_wakeup_mask, ret);
|
|
return ret;
|
|
}
|
|
} else {
|
|
ret = pmoc_get_usb_wakeup_mask(&usb_mask);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_get_usb_wakeup_mask, ret);
|
|
return ret;
|
|
}
|
|
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
attr->enable = tmp.val8[0];
|
|
attr->param.usb_param.usb_wakeup_mask = usb_mask;
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_voice_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_VOICE_WAKEUP_ENABLE_VALUE / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = attr->enable;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
} else {
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
attr->enable = tmp.val8[0];
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_vga_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_VGA_WAKEUP_ENABLE_VALUE / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = attr->enable;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
} else {
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
attr->enable = tmp.val8[0];
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_scart_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
soc_dbg_func_enter();
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_hdmirx_plugin_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_HDMI_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
tmp.val8[2] = attr->enable; /* 2: array offset value */
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_HDMIRX_PLUGIN_PORT_ADDR / sizeof(td_u32);
|
|
writel(attr->param.hdmirx_plugin_param.port, lpmcu_vir_addr);
|
|
} else {
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
attr->enable = tmp.val8[2]; /* 2: array offset value */
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_HDMIRX_PLUGIN_PORT_ADDR / sizeof(td_u32);
|
|
attr->param.hdmirx_plugin_param.port = readl(lpmcu_vir_addr);
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
|
|
static td_s32 pmoc_hdmirx_cec_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_HDMI_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
tmp.val8[1] = attr->enable;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
} else {
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
attr->enable = tmp.val8[1];
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_hdmitx_cec_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
u32_data tmp;
|
|
td_u8 i;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_HDMI_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
tmp.val8[0] = attr->enable;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_HDMITX_CEC_PARAM_ADDR / sizeof(td_u32);
|
|
for (i = 0; i < LPMCU_WAKEUP_HDMITX_ID_MAXNUM; i++) {
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = attr->param.hdmitx_cec_param.id[i];
|
|
tmp.val8[1] = attr->param.hdmitx_cec_param.cec_control[i];
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
}
|
|
} else {
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
attr->enable = tmp.val8[0];
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_HDMITX_CEC_PARAM_ADDR / sizeof(td_u32);
|
|
for (i = 0; i < LPMCU_WAKEUP_HDMITX_ID_MAXNUM; i++) {
|
|
tmp.val32 = readl(lpmcu_vir_addr++);
|
|
attr->param.hdmitx_cec_param.id[i] = tmp.val8[0];
|
|
attr->param.hdmitx_cec_param.cec_control[i] = tmp.val8[1];
|
|
}
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_timeout_suspend_param(td_bool set, pmoc_cmd_suspend_attr *attr)
|
|
{
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_TIMEOUT_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
if (set) {
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = attr->enable;
|
|
tmp.val8[1] = attr->param.timeout_param.pvr_enable;
|
|
tmp.val8[2] = attr->param.timeout_param.mute_wakeup_enable; /* 2: array offset value */
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
writel(attr->param.timeout_param.suspend_period, lpmcu_vir_addr);
|
|
} else {
|
|
tmp.val32 = readl(lpmcu_vir_addr++);
|
|
attr->enable = tmp.val8[0];
|
|
attr->param.timeout_param.pvr_enable = tmp.val8[1];
|
|
attr->param.timeout_param.mute_wakeup_enable = tmp.val8[2]; /* 2: array offset value */
|
|
|
|
attr->param.timeout_param.suspend_period = readl(lpmcu_vir_addr);
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static pmoc_suspend_param_process_map g_suspend_param_process_func[] = {
|
|
{ EXT_PMOC_WAKEUP_TYPE_IR, pmoc_ir_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_KEYLED, pmoc_keyled_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_GPIO, pmoc_gpio_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_LSADC, pmoc_lsadc_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_UART, pmoc_uart_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_ETH, pmoc_eth_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_USB, pmoc_usb_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_VOICE, pmoc_voice_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_VGA, pmoc_vga_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_SCART, pmoc_scart_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_HDMIRX_PLUGIN, pmoc_hdmirx_plugin_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_HDMIRX_CEC, pmoc_hdmirx_cec_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_HDMITX_CEC, pmoc_hdmitx_cec_suspend_param },
|
|
{ EXT_PMOC_WAKEUP_TYPE_TIMEOUT, pmoc_timeout_suspend_param },
|
|
};
|
|
|
|
static td_s32 pmoc_set_suspend_param(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
td_u8 i;
|
|
td_u8 source_num;
|
|
pmoc_cmd_suspend_attr attr = {0};
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
ret = memcpy_s(&attr, sizeof(pmoc_cmd_suspend_attr), arg, sizeof(pmoc_cmd_suspend_attr));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
source_num = sizeof(g_suspend_param_process_func) / sizeof(g_suspend_param_process_func[0]);
|
|
for (i = 0; i < source_num; i++) {
|
|
if (attr.source == g_suspend_param_process_func[i].source) {
|
|
ret = g_suspend_param_process_func[i].f_driver_suspend_param_process(TD_TRUE, &attr);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_h32(attr.source);
|
|
soc_err_print_s32(ret);
|
|
return ret;
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
td_s32 pmoc_get_suspend_param(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
td_u8 i;
|
|
td_u8 source_num;
|
|
pmoc_cmd_suspend_attr attr = {0};
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
ret = memcpy_s(&attr, sizeof(pmoc_cmd_suspend_attr), arg, sizeof(pmoc_cmd_suspend_attr));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
source_num = sizeof(g_suspend_param_process_func) / sizeof(g_suspend_param_process_func[0]);
|
|
|
|
for (i = 0; i < source_num; i++) {
|
|
if (attr.source == g_suspend_param_process_func[i].source) {
|
|
ret = g_suspend_param_process_func[i].f_driver_suspend_param_process(TD_FALSE, &attr);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_h32(attr.source);
|
|
soc_err_print_s32(ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = memcpy_s(arg, sizeof(pmoc_cmd_suspend_attr), &attr, sizeof(pmoc_cmd_suspend_attr));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
static td_s32 pmoc_set_wakeup_type(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
u32_data tmp;
|
|
ext_pmoc_wakeup_type type;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
ret = memcpy_s(&type, sizeof(ext_pmoc_wakeup_type), arg, sizeof(ext_pmoc_wakeup_type));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
g_wakeup_type = type;
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_RESUME_RESET_ADDR / sizeof(td_u32);
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
tmp.val8[0] = type;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_standby_ready(td_void *arg)
|
|
{
|
|
soc_dbg_func_enter();
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_set_gpio_power_off(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 i;
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
ext_pmoc_poweroff_gpio_param param = {0};
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
ret = memcpy_s(¶m, sizeof(ext_pmoc_poweroff_gpio_param), arg, sizeof(ext_pmoc_poweroff_gpio_param));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (param.num >= EXT_PMOC_POWEROFF_GPIO_MAXNUM) {
|
|
param.num = EXT_PMOC_POWEROFF_GPIO_MAXNUM;
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_GPIO_POWEROFF_PARAM_ADDR / sizeof(td_u32);
|
|
writel(param.num, lpmcu_vir_addr++);
|
|
|
|
for (i = 0; i < param.num; i++) {
|
|
if (param.group[i] > g_dts_info.gpio_aon_group_max || param.group[i] < g_dts_info.gpio_aon_group_min) {
|
|
soc_err_print_info("gpio aon group is illegal\n");
|
|
soc_err_print_u32(i);
|
|
soc_err_print_u32(param.group[i]);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = param.group[i];
|
|
tmp.val8[1] = param.bit[i];
|
|
tmp.val8[2] = param.level[i]; /* 2: array offset value */
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_set_display_param(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
ext_pmoc_display_param display_param = {0};
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
ret = memcpy_s(&display_param, sizeof(ext_pmoc_display_param), arg, sizeof(ext_pmoc_display_param));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_KEYLED_TYPE_ADDR / sizeof(td_u32);
|
|
writel(display_param.keyled_type, lpmcu_vir_addr);
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_KEYLED_DISPLAY_ADDR / sizeof(td_u32);
|
|
writel(display_param.display_type, lpmcu_vir_addr++);
|
|
writel(display_param.display_value, lpmcu_vir_addr++);
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 pmoc_get_standby_period(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 period;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
if (g_wakeup_message.wakeup_type >= EXT_PMOC_WAKEUP_TYPE_MAX) {
|
|
soc_err_print_info("wakeup type is illegal");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
period = g_wakeup_message.standby_period;
|
|
|
|
ret = memcpy_s(arg, sizeof(td_u32), &period, sizeof(td_u32));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 pmoc_get_wakeup_attr(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
ext_pmoc_wakeup_attr attr = {0};
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
if (g_wakeup_message.wakeup_type >= EXT_PMOC_WAKEUP_TYPE_MAX) {
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
attr.source = g_wakeup_message.wakeup_type;
|
|
|
|
if (attr.source == EXT_PMOC_WAKEUP_TYPE_IR) {
|
|
attr.wakeup_param.ir_param.ir_low_val = g_wakeup_message.ir_low_val;
|
|
attr.wakeup_param.ir_param.ir_high_val = g_wakeup_message.ir_high_val;
|
|
} else if (attr.source == EXT_PMOC_WAKEUP_TYPE_GPIO) {
|
|
attr.wakeup_param.gpio_param.group = g_wakeup_message.gpio_wakeup_port / GPIO_BITS_PER_GROUP;
|
|
attr.wakeup_param.gpio_param.bit = g_wakeup_message.gpio_wakeup_port % GPIO_BITS_PER_GROUP;
|
|
} else if (attr.source == EXT_PMOC_WAKEUP_TYPE_LSADC) {
|
|
attr.wakeup_param.lsadc_param.channel = g_wakeup_message.lsadc_channel;
|
|
attr.wakeup_param.lsadc_param.key_value = g_wakeup_message.lsadc_wakeup_key;
|
|
}
|
|
|
|
ret = memcpy_s(arg, sizeof(ext_pmoc_wakeup_attr), &attr, sizeof(ext_pmoc_wakeup_attr));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_clean_wakeup_param(td_void *arg)
|
|
{
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_WAKEUP_DATA_ADDR / sizeof(td_u32);
|
|
|
|
writel(INVALID_VALUE, lpmcu_vir_addr++);
|
|
writel(INVALID_VALUE, lpmcu_vir_addr++);
|
|
writel(INVALID_VALUE, lpmcu_vir_addr++);
|
|
writel(INVALID_VALUE, lpmcu_vir_addr++);
|
|
writel(INVALID_VALUE, lpmcu_vir_addr);
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_enter_active_standby(td_void *arg)
|
|
{
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_quit_active_standby(td_void *arg)
|
|
{
|
|
soc_dbg_func_enter();
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_get_chip_temprature(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
td_s16 real_temp;
|
|
td_s32 temperature;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
ret = pmoc_tsensor_read(&real_temp);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_tsensor_read, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
temperature = real_temp;
|
|
|
|
ret = memcpy_s(arg, sizeof(td_u32), &temperature, sizeof(td_u32));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_set_standby_led(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
u32_data param;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
ret = memcpy_s(¶m.val32, sizeof(td_u32), arg, sizeof(td_u32));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_STANDBY_LED_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
if (param.val8[0] > g_dts_info.gpio_aon_group_max || param.val8[0] < g_dts_info.gpio_aon_group_min) {
|
|
soc_err_print_info("gpio aon group is illegal\n");
|
|
soc_err_print_u32(param.val8[0]);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
writel(param.val32, lpmcu_vir_addr);
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_set_breath_led(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
ext_pmoc_breath_led_param param = {0};
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
ret = memcpy_s(¶m, sizeof(ext_pmoc_breath_led_param), arg, sizeof(ext_pmoc_breath_led_param));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (param.group > g_dts_info.gpio_aon_group_max || param.group < g_dts_info.gpio_aon_group_min) {
|
|
soc_err_print_info("gpio aon group is illegal\n");
|
|
soc_err_print_u32(param.group);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_BREATH_LED_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = param.group;
|
|
tmp.val8[1] = param.bit;
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
writel(param.led_breath_cycle, lpmcu_vir_addr);
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_set_mcu_msg(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
ext_pmoc_mcu_message msg = {0};
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
ret = memcpy_s(&msg, sizeof(ext_pmoc_mcu_message), arg, sizeof(ext_pmoc_mcu_message));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (msg.index >= EXT_PMOC_CUSTOM_REG_MAX) {
|
|
soc_err_print_info("custom reg index is illegal\n");
|
|
soc_err_print_u32(msg.index);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_CUSTOM_MSG_ADDR / sizeof(td_u32) + msg.index;
|
|
writel(msg.value, lpmcu_vir_addr);
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_get_mcu_msg(td_void *arg)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
ext_pmoc_mcu_message msg = {0};
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
pmoc_check_param_return_if(arg == TD_NULL, TD_FAILURE);
|
|
|
|
ret = memcpy_s(&msg, sizeof(ext_pmoc_mcu_message), arg, sizeof(ext_pmoc_mcu_message));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
if (msg.index >= EXT_PMOC_CUSTOM_REG_MAX) {
|
|
soc_err_print_info("custom reg index is illegal\n");
|
|
soc_err_print_u32(msg.index);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_CUSTOM_MSG_ADDR / sizeof(td_u32) + msg.index;
|
|
msg.value = readl(lpmcu_vir_addr);
|
|
|
|
ret = memcpy_s(arg, sizeof(ext_pmoc_mcu_message), &msg, sizeof(ext_pmoc_mcu_message));
|
|
if (ret != EOK) {
|
|
soc_err_print_call_fun_err(memcpy_s, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static pmoc_ioctl_map g_pmoc_func[] = {
|
|
{ CMD_PMOC_SET_SUSPEND_ATTR, pmoc_set_suspend_param },
|
|
{ CMD_PMOC_GET_SUSPEND_ATTR, pmoc_get_suspend_param },
|
|
{ CMD_PMOC_SET_WAKEUP_TYPE, pmoc_set_wakeup_type },
|
|
{ CMD_PMOC_STANDBY_READY, pmoc_standby_ready },
|
|
{ CMD_PMOC_GET_WAKEUP_ATTR, pmoc_get_wakeup_attr },
|
|
{ CMD_PMOC_GET_STANDBY_PERIOD, pmoc_get_standby_period },
|
|
{ CMD_PMOC_CLEAN_WAKEUP_PARAM, pmoc_clean_wakeup_param },
|
|
{ CMD_PMOC_ENTER_ACTIVE_STANDBY, pmoc_enter_active_standby },
|
|
{ CMD_PMOC_QUIT_ACTIVE_STANDBY, pmoc_quit_active_standby },
|
|
{ CMD_PMOC_SET_DISPLAY_PARAM, pmoc_set_display_param },
|
|
{ CMD_PMOC_SET_GPIO_POWEROFF, pmoc_set_gpio_power_off },
|
|
{ CMD_PMOC_GET_CHIP_TEMPERATURE, pmoc_get_chip_temprature },
|
|
{ CMD_PMOC_SET_STANDBY_LED, pmoc_set_standby_led },
|
|
{ CMD_PMOC_SET_BREATH_LED, pmoc_set_breath_led },
|
|
{ CMD_PMOC_SET_MCU_MSG, pmoc_set_mcu_msg },
|
|
{ CMD_PMOC_GET_MCU_MSG, pmoc_get_mcu_msg },
|
|
};
|
|
|
|
td_s32 pmoc_ioctl(td_u32 cmd, td_void *arg, td_void *private_data)
|
|
{
|
|
td_u8 cmd_num;
|
|
td_u8 i;
|
|
td_s32 ret;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
cmd_num = sizeof(g_pmoc_func) / sizeof(g_pmoc_func[0]);
|
|
|
|
for (i = 0; i < cmd_num; i++) {
|
|
if (cmd == g_pmoc_func[i].cmd) {
|
|
ret = osal_sem_down_interruptible(&g_pmoc_sem);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_sem_down_interruptible, ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = g_pmoc_func[i].f_driver_cmd_process(arg);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_h32(cmd);
|
|
soc_err_print_s32(ret);
|
|
osal_sem_up(&g_pmoc_sem);
|
|
return ret;
|
|
}
|
|
|
|
osal_sem_up(&g_pmoc_sem);
|
|
return TD_SUCCESS;
|
|
}
|
|
}
|
|
|
|
soc_err_print_info("ioctl cmd is not support\n");
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
#ifndef MODULE
|
|
td_void pmoc_inject_timesleep_to_timekeeping(td_void)
|
|
{
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
struct timespec64 sleep_time = {0};
|
|
td_u32 delta;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_STANDBY_PERIOD / sizeof(td_u32);
|
|
|
|
delta = readl(lpmcu_vir_addr);
|
|
|
|
sleep_time.tv_sec += delta;
|
|
|
|
timekeeping_inject_sleeptime64(&sleep_time);
|
|
|
|
soc_dbg_func_exit();
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
static td_void lpmcu_log_to_bbox(td_void)
|
|
{
|
|
td_u32 i, log_len;
|
|
td_u8 log_print[PMOC_LOG_PRINT_LEN + 1] = {0};
|
|
td_u32 log_data[LPMCU_LOG_DATA_SIZE / sizeof(td_u32) + 1] = {0};
|
|
td_char *log_msg = TD_NULL;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_LOG_FLAG_ADDR / sizeof(td_u32);
|
|
|
|
if (readl(lpmcu_vir_addr) == LPMCU_LOG_WRITE_FLAG) {
|
|
writel(0, lpmcu_vir_addr++);
|
|
|
|
log_len = readl(lpmcu_vir_addr);
|
|
log_len = (log_len > LPMCU_LOG_DATA_SIZE) ? LPMCU_LOG_DATA_SIZE : log_len;
|
|
soc_dbg_print_u32(log_len);
|
|
writel(0, lpmcu_vir_addr++);
|
|
|
|
for (i = 0; i < log_len / sizeof(td_u32); i++) {
|
|
log_data[i] = readl(lpmcu_vir_addr + i);
|
|
writel(0, lpmcu_vir_addr + i);
|
|
}
|
|
|
|
log_msg = (td_u8 *)log_data;
|
|
|
|
for (i = 0; *log_msg != '\0'; log_msg++) {
|
|
if (i == PMOC_LOG_PRINT_LEN) {
|
|
log_print[i] = '\0';
|
|
soc_log_alert("%s\n", log_print);
|
|
|
|
i = 0;
|
|
log_print[i++] = *log_msg;
|
|
continue;
|
|
}
|
|
|
|
if (*log_msg == '\n') {
|
|
log_print[i] = '\0';
|
|
soc_log_alert("%s\n", log_print);
|
|
|
|
i = 0;
|
|
continue;
|
|
}
|
|
|
|
log_print[i++] = *log_msg;
|
|
}
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return;
|
|
}
|
|
|
|
td_void pmoc_get_wakeup_message(td_void)
|
|
{
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_WAKEUP_DATA_ADDR / sizeof(td_u32);
|
|
|
|
g_wakeup_message.wakeup_type = readl(lpmcu_vir_addr++);
|
|
g_wakeup_message.gpio_wakeup_port = readl(lpmcu_vir_addr++);
|
|
g_wakeup_message.ir_low_val = readl(lpmcu_vir_addr++);
|
|
g_wakeup_message.ir_high_val = readl(lpmcu_vir_addr++);
|
|
g_wakeup_message.standby_period = readl(lpmcu_vir_addr++);
|
|
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
g_wakeup_message.lsadc_channel = tmp.val16[0];
|
|
g_wakeup_message.lsadc_wakeup_key = tmp.val16[1];
|
|
|
|
lpmcu_log_to_bbox();
|
|
|
|
/* clear reg mute flag */
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_REG_MUTE / sizeof(td_u32);
|
|
writel(0, lpmcu_vir_addr);
|
|
|
|
soc_dbg_func_exit();
|
|
return;
|
|
}
|
|
|
|
td_void pmoc_set_lpmcu_dbg_level(td_u32 value)
|
|
{
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
soc_info_print_u32(value);
|
|
|
|
if ((value != 0) && (value != 1)) {
|
|
soc_err_print_info("plese set dbg level: 0(lpmcu without log), 1(lpmcu with log)\n");
|
|
return;
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_DBG_MASK_ADDR / sizeof(td_u32);
|
|
tmp.val32 = readl(lpmcu_vir_addr);
|
|
tmp.val8[1] = value;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
|
|
soc_dbg_func_exit();
|
|
return;
|
|
}
|
|
|
|
td_s32 pmoc_load_wakeup_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
ret = pmoc_set_wakeup_type_to_hrf(g_wakeup_type);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_set_wakeup_type_to_hrf, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_check_firmware_file(td_void)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 i;
|
|
td_u32 path_num;
|
|
td_void *fp = TD_NULL;
|
|
td_u8 fw_name[128]; /* 128: len */
|
|
td_u8 *path[] = {
|
|
"/lib/firmware/",
|
|
"/vendor/firmware/"
|
|
};
|
|
|
|
path_num = sizeof(path) / sizeof(path[0]);
|
|
for (i = 0; i < path_num; i++) {
|
|
ret = snprintf_s(fw_name, sizeof(fw_name), sizeof(fw_name) - 1, "%s%s", path[i], LPMCU_BIN_PATH);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(snprintf_s, ret);
|
|
return ret;
|
|
}
|
|
|
|
fp = osal_klib_fopen(fw_name, OSAL_O_RDONLY, 0);
|
|
if (fp == TD_NULL) {
|
|
continue;
|
|
}
|
|
|
|
osal_klib_fclose(fp);
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
static td_s32 pmoc_load_lpmcu_code(td_void)
|
|
{
|
|
td_s32 ret;
|
|
osal_firmware *fw = TD_NULL;
|
|
|
|
ret = pmoc_check_firmware_file();
|
|
if (ret != TD_SUCCESS) {
|
|
return ret;
|
|
}
|
|
|
|
ret = osal_request_firmware_into_buf(&fw, LPMCU_BIN_PATH, g_lpmcu_base, LPMCU_CODE_MAXSIZE);
|
|
if (ret != 0) {
|
|
soc_err_print_call_fun_err(osal_request_firmware_into_buf, ret);
|
|
return ret;
|
|
}
|
|
|
|
osal_release_firmware(fw);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_load_firmware_thread(td_void *data)
|
|
{
|
|
td_s32 ret;
|
|
|
|
while (!osal_kthread_should_stop()) {
|
|
osal_msleep(500); /* 500 ms */
|
|
|
|
ret = pmoc_load_lpmcu_code();
|
|
if (ret != TD_SUCCESS) {
|
|
continue;
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_try_loading_firmware(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = pmoc_load_lpmcu_code();
|
|
if (ret == TD_SUCCESS) {
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
g_pmoc_thread = osal_kthread_create(pmoc_load_firmware_thread, TD_NULL, "lpmcu_loading_thread", 0);
|
|
if (g_pmoc_thread == TD_NULL) {
|
|
soc_err_print_call_fun_err(osal_kthread_create, TD_FAILURE);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 set_ddr_gpio_custom_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 ddr_gpio_group, ddr_gpio_bit, ddr_gpio_level;
|
|
td_u32 *lpmcu_vir_addr = NULL;
|
|
u32_data tmp;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "ddr_gpio_group", &ddr_gpio_group);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "ddr_gpio_bit", &ddr_gpio_bit);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "ddr_gpio_level", &ddr_gpio_level);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
lpmcu_vir_addr = (td_u32 *)(g_lpmcu_base + LPMCU_GPIO_POWERCTRL_DDR_PARAM_ADDR / sizeof(td_u32));
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = ddr_gpio_group;
|
|
tmp.val8[1] = ddr_gpio_bit;
|
|
tmp.val8[2] = ddr_gpio_level; /* 2: array offset value */
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_set_gpio_poweroff_custom_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
u32_data tmp;
|
|
td_u32 poweroff_num, i;
|
|
td_u32 poweroff_group[EXT_PMOC_POWEROFF_GPIO_MAXNUM] = {0};
|
|
td_u32 poweroff_bit[EXT_PMOC_POWEROFF_GPIO_MAXNUM] = {0};
|
|
td_u32 poweroff_level[EXT_PMOC_POWEROFF_GPIO_MAXNUM] = {0};
|
|
td_u32 *lpmcu_vir_addr = NULL;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "gpio_poweroff_num", &poweroff_num);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
if (poweroff_num == 0) {
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
poweroff_num = (poweroff_num > EXT_PMOC_POWEROFF_GPIO_MAXNUM) ? EXT_PMOC_POWEROFF_GPIO_MAXNUM : poweroff_num;
|
|
|
|
lpmcu_vir_addr = (td_u32 *)(g_lpmcu_base + LPMCU_GPIO_POWEROFF_PARAM_ADDR / sizeof(td_u32));
|
|
writel(poweroff_num, lpmcu_vir_addr++);
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "gpio_poweroff_group", poweroff_group, poweroff_num);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "gpio_poweroff_bit", poweroff_bit, poweroff_num);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "gpio_poweroff_level", poweroff_level, poweroff_num);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
for (i = 0; i < poweroff_num; i++) {
|
|
if (poweroff_group[i] > g_dts_info.gpio_aon_group_max || poweroff_group[i] < g_dts_info.gpio_aon_group_min) {
|
|
soc_err_print_info("gpio aon group is illegal\n");
|
|
soc_err_print_u32(poweroff_group[i]);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = poweroff_group[i];
|
|
tmp.val8[1] = poweroff_bit[i];
|
|
tmp.val8[2] = poweroff_level[i]; /* 2: array offset value */
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_set_keyled_custom_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 keyled_wakeup_enable;
|
|
td_u32 keyled_type;
|
|
td_u32 keyled_wakeup_key;
|
|
td_u32 keyled_display_mode;
|
|
td_u32 display_value;
|
|
td_u32 *lpmcu_vir_addr = NULL;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "keyled_wakeup_enable", &keyled_wakeup_enable);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
if (keyled_wakeup_enable == 0)
|
|
return TD_SUCCESS;
|
|
|
|
lpmcu_vir_addr = (td_u32 *)(g_lpmcu_base + LPMCU_KEYLED_SUSPEND_PARAM_ADDR / sizeof(td_u32));
|
|
|
|
writel(keyled_wakeup_enable, lpmcu_vir_addr++);
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "keyled_type", &keyled_type);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
writel(keyled_type, lpmcu_vir_addr++);
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "keyled_wakeup_key", &keyled_wakeup_key);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
writel(keyled_wakeup_key, lpmcu_vir_addr++);
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "keyled_display_mode", &keyled_display_mode);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
writel(keyled_display_mode, lpmcu_vir_addr++);
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "display_value", &display_value);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
writel(display_value, lpmcu_vir_addr);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
#ifndef CONFIG_SOCT_COMMON_KERNEL
|
|
#ifndef CONFIG_SOCT_OH_KERNEL
|
|
static td_s32 pmoc_get_s3_s4_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "s3_s4_gpio_num", &g_s3_s4_gpio_num);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
g_s3_s4_gpio_num = (g_s3_s4_gpio_num > S3_S4_OPERATION_NUM) ? S3_S4_OPERATION_NUM : g_s3_s4_gpio_num;
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "s3_s4_gpio_group",
|
|
g_s3_s4_gpio_group, S3_S4_OPERATION_NUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "s3_s4_gpio_bit", g_s3_s4_gpio_bit, S3_S4_OPERATION_NUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "s3_gpio_level", g_s3_gpio_level, S3_S4_OPERATION_NUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "s4_gpio_level", g_s4_gpio_level, S3_S4_OPERATION_NUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_void pmoc_set_s3_s4_param(td_bool is_s3)
|
|
{
|
|
td_u32 i;
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
if (g_dts_info.product_flag != 0x2) { /* 0x2: bit1 is pc product flag */
|
|
return;
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_S3_S4_GPIO_NUM_ADDR / sizeof(td_u32);
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = g_s3_s4_gpio_num;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_S3_S4_GPIO_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
for (i = 0; i < g_s3_s4_gpio_num; i++) {
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = g_s3_s4_gpio_group[i];
|
|
tmp.val8[1] = g_s3_s4_gpio_bit[i];
|
|
tmp.val8[2] = is_s3 ? g_s3_gpio_level[i] : g_s4_gpio_level[i]; /* 2: array offset value */
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_S3_S4_FLAG_ADDR / sizeof(td_u32);
|
|
writel(0, lpmcu_vir_addr);
|
|
|
|
soc_dbg_func_exit();
|
|
return;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
static td_s32 pmoc_get_gpio_message(td_u32 *lpmcu_vir_addr, td_u32 gpio_wakeup_num)
|
|
{
|
|
td_u32 i;
|
|
td_s32 ret;
|
|
u32_data tmp;
|
|
td_u32 gpio_wakeup_group[LPMCU_WAKEUP_GPIO_MAXNUM] = {0};
|
|
td_u32 gpio_wakeup_bit[LPMCU_WAKEUP_GPIO_MAXNUM] = {0};
|
|
td_u32 gpio_interrupt_type[LPMCU_WAKEUP_GPIO_MAXNUM] = {0};
|
|
|
|
pmoc_check_param_return_if(lpmcu_vir_addr == TD_NULL, TD_FAILURE);
|
|
pmoc_check_param_return_if(gpio_wakeup_num > LPMCU_WAKEUP_GPIO_MAXNUM, TD_FAILURE);
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "gpio_wakeup_group",
|
|
gpio_wakeup_group, LPMCU_WAKEUP_GPIO_MAXNUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "gpio_wakeup_bit",
|
|
gpio_wakeup_bit, LPMCU_WAKEUP_GPIO_MAXNUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "gpio_interrupt_type",
|
|
gpio_interrupt_type, LPMCU_WAKEUP_GPIO_MAXNUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
for (i = 0; i < gpio_wakeup_num; i++) {
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = gpio_wakeup_group[i];
|
|
tmp.val8[1] = gpio_wakeup_bit[i];
|
|
tmp.val8[2] = gpio_interrupt_type[i]; /* 2: array offset value */
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_set_gpio_custom_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
u32_data tmp;
|
|
td_u32 gpio_wakeup_enable = 0;
|
|
td_u32 gpio_wakeup_num = 0;
|
|
td_u32 *lpmcu_vir_addr = NULL;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "gpio_wakeup_enable", &gpio_wakeup_enable);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
if (gpio_wakeup_enable == 0)
|
|
return TD_SUCCESS;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "gpio_wakeup_num", &gpio_wakeup_num);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
gpio_wakeup_num = (gpio_wakeup_num > LPMCU_WAKEUP_GPIO_MAXNUM) ? LPMCU_WAKEUP_GPIO_MAXNUM : gpio_wakeup_num;
|
|
|
|
lpmcu_vir_addr = (td_u32 *)(g_lpmcu_base + LPMCU_GPIO_SUSPEND_PARAM_ADDR / sizeof(td_u32));
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = gpio_wakeup_enable;
|
|
tmp.val8[1] = gpio_wakeup_num;
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
|
|
ret = pmoc_get_gpio_message(lpmcu_vir_addr, gpio_wakeup_num);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_get_gpio_message, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_get_ir_message(td_u32 *lpmcu_vir_addr, td_u32 ir_wakeup_num)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 i;
|
|
td_u32 ir_high_value[LPMCU_WAKEUP_IRKEY_MAXNUM] = {0};
|
|
td_u32 ir_low_value[LPMCU_WAKEUP_IRKEY_MAXNUM] = {0};
|
|
|
|
pmoc_check_param_return_if(lpmcu_vir_addr == TD_NULL, TD_FAILURE);
|
|
pmoc_check_param_return_if(ir_wakeup_num > LPMCU_WAKEUP_IRKEY_MAXNUM, TD_FAILURE);
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "ir_low_value", ir_low_value, LPMCU_WAKEUP_IRKEY_MAXNUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "ir_high_value", ir_high_value, LPMCU_WAKEUP_IRKEY_MAXNUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
for (i = 0; i < ir_wakeup_num; i++) {
|
|
writel(ir_low_value[i], lpmcu_vir_addr++);
|
|
writel(ir_high_value[i], lpmcu_vir_addr++);
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_set_ir_custom_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 ir_wakeup_enable;
|
|
td_u32 ir_type;
|
|
td_u32 ir_wakeup_num;
|
|
td_u32 *lpmcu_vir_addr = NULL;
|
|
u32_data tmp;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "ir_wakeup_enable", &ir_wakeup_enable);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
if (ir_wakeup_enable == 0)
|
|
return TD_SUCCESS;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "ir_type", &ir_type);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "ir_wakeup_num", &ir_wakeup_num);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
ir_wakeup_num = (ir_wakeup_num > LPMCU_WAKEUP_IRKEY_MAXNUM) ? LPMCU_WAKEUP_IRKEY_MAXNUM : ir_wakeup_num;
|
|
|
|
lpmcu_vir_addr = (td_u32 *)(g_lpmcu_base + LPMCU_IR_SUSPEND_PARAM_ADDR / sizeof(td_u32));
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = ir_wakeup_enable;
|
|
tmp.val8[1] = ir_type;
|
|
tmp.val8[2] = ir_wakeup_num; /* 2: array offset value */
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
|
|
ret = pmoc_get_ir_message(lpmcu_vir_addr, ir_wakeup_num);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_get_ir_message, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
#ifndef CONFIG_SOCT_COMMON_KERNEL
|
|
#ifndef CONFIG_SOCT_OH_KERNEL
|
|
static td_s32 pmoc_set_usb_custom_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 usb_wakeup_enable = 0;
|
|
td_u32 *lpmcu_vir_addr = NULL;
|
|
u32_data tmp;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "usb_wakeup_enable", &usb_wakeup_enable);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_USB_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = usb_wakeup_enable;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
static td_s32 pmoc_set_timeout_custom_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 timeout_wakeup_enable = 0;
|
|
td_u32 timeout_wakeup_period = 0;
|
|
td_u32 *lpmcu_vir_addr = NULL;
|
|
u32_data tmp;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "timeout_wakeup_enable", &timeout_wakeup_enable);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
if (timeout_wakeup_enable == 0)
|
|
return TD_SUCCESS;
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_TIMEOUT_SUSPEND_PARAM_ADDR / sizeof(td_u32);
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = timeout_wakeup_enable;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "timeout_wakeup_period", &timeout_wakeup_period);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_TIMEOUT_SUSPEND_TIME_ADDR / sizeof(td_u32);
|
|
writel(timeout_wakeup_period, lpmcu_vir_addr);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_set_lsadc_custom_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
td_s32 i;
|
|
td_u32 lsadc_wakeup_enable;
|
|
td_u32 lsadc_channel_mask;
|
|
td_u32 *lpmcu_vir_addr = NULL;
|
|
u32_data tmp;
|
|
td_u32 lsadc_high_value[LPMCU_LSADC_CHANNEL_NUM] = {0};
|
|
td_u32 lsadc_low_value[LPMCU_LSADC_CHANNEL_NUM] = {0};
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "lsadc_wakeup_enable", &lsadc_wakeup_enable);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
if (lsadc_wakeup_enable == 0)
|
|
return TD_SUCCESS;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "lsadc_channel_mask", &lsadc_channel_mask);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
lpmcu_vir_addr = (td_u32 *)(g_lpmcu_base + LPMCU_LSADC_SUSPEND_PARAM_ADDR / sizeof(td_u32));
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = lsadc_wakeup_enable;
|
|
tmp.val8[1] = lsadc_channel_mask;
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "lsadc_low_value", lsadc_low_value, LPMCU_LSADC_CHANNEL_NUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "lsadc_high_value", lsadc_high_value, LPMCU_LSADC_CHANNEL_NUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
for (i = 0; i < LPMCU_LSADC_CHANNEL_NUM; i++) {
|
|
tmp.val32 = 0;
|
|
tmp.val16[0] = lsadc_low_value[i];
|
|
tmp.val16[1] = lsadc_high_value[i];
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_set_dbg_custom_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
td_u32 dbg_mask = 0;
|
|
td_u32 *lpmcu_vir_addr = NULL;
|
|
u32_data tmp;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "dbg_mask", &dbg_mask);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_DBG_MASK_ADDR / sizeof(td_u32);
|
|
tmp.val32 = 0;
|
|
tmp.val8[1] = dbg_mask;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
#ifndef CONFIG_SOCT_COMMON_KERNEL
|
|
#ifndef CONFIG_SOCT_OH_KERNEL
|
|
static td_s32 pmoc_get_state_gpio_message(td_u32 *lpmcu_vir_addr, td_u32 gpio_state_num)
|
|
{
|
|
td_u32 i;
|
|
td_s32 ret;
|
|
u32_data tmp;
|
|
td_u32 gpio_state_group[LPMCU_STATE_GPIO_MAXNUM] = {0};
|
|
td_u32 gpio_state_bit[LPMCU_STATE_GPIO_MAXNUM] = {0};
|
|
|
|
pmoc_check_param_return_if(lpmcu_vir_addr == TD_NULL, TD_FAILURE);
|
|
pmoc_check_param_return_if(gpio_state_num > LPMCU_STATE_GPIO_MAXNUM, TD_FAILURE);
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "gpio_state_group",
|
|
gpio_state_group, LPMCU_STATE_GPIO_MAXNUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = osal_dts_get_array_byname(MCU_NODE, "gpio_state_bit",
|
|
gpio_state_bit, LPMCU_STATE_GPIO_MAXNUM);
|
|
if (ret <= 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_array_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
for (i = 0; i < gpio_state_num; i++) {
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = gpio_state_group[i];
|
|
tmp.val8[1] = gpio_state_bit[i];
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_set_suspend_state_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
u32_data tmp;
|
|
td_u32 gpio_state_enable = 0;
|
|
td_u32 gpio_state_num = 0;
|
|
td_u32 *lpmcu_vir_addr = NULL;
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "gpio_state_enable", &gpio_state_enable);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = osal_dts_get_u32_byname(MCU_NODE, "gpio_state_num", &gpio_state_num);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return ret;
|
|
}
|
|
|
|
gpio_state_num = (gpio_state_num > LPMCU_STATE_GPIO_MAXNUM) ? LPMCU_STATE_GPIO_MAXNUM : gpio_state_num;
|
|
|
|
lpmcu_vir_addr = (td_u32 *)(g_lpmcu_base + LPMCU_MCU_SUSPEND_STATE_ADDR / sizeof(td_u32));
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = gpio_state_enable;
|
|
tmp.val8[1] = gpio_state_num;
|
|
writel(tmp.val32, lpmcu_vir_addr++);
|
|
|
|
ret = pmoc_get_state_gpio_message(lpmcu_vir_addr, gpio_state_num);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_get_state_gpio_message, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
td_s32 pmoc_set_default_custom_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
#ifdef CONFIG_SOCT_COMMON_KERNEL
|
|
ret = set_ddr_gpio_custom_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(set_ddr_gpio_custom_param, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = pmoc_set_gpio_poweroff_custom_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_set_gpio_poweroff_custom_param, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = pmoc_set_keyled_custom_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_set_keyled_custom_param, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = pmoc_set_ir_custom_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_set_ir_custom_param, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = pmoc_set_lsadc_custom_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_set_lsadc_custom_param, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
#endif
|
|
|
|
ret = pmoc_set_gpio_custom_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_set_gpio_custom_param, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = pmoc_set_timeout_custom_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_set_timeout_custom_param, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = pmoc_set_dbg_custom_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_set_dbg_custom_param, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
#ifndef CONFIG_SOCT_COMMON_KERNEL
|
|
#ifndef CONFIG_SOCT_OH_KERNEL
|
|
ret = pmoc_set_usb_custom_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_set_usb_custom_param, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = pmoc_get_s3_s4_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_get_s3_s4_param, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = pmoc_set_suspend_state_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_set_suspend_state_param, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
static td_s32 pmoc_load_standby_param(td_void)
|
|
{
|
|
td_s32 ret;
|
|
u32_data tmp;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
ext_chip_name_id chip_name_id;
|
|
ext_chip_revision chip_revision;
|
|
td_u32 board_id = 0;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
ret = ext_drv_sys_get_chip_name_id(&chip_name_id);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(ext_drv_sys_get_chip_name_id, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = ext_drv_sys_get_chip_revision(&chip_revision);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(ext_drv_sys_get_chip_revision, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
ret = ext_drv_sys_get_board_id(&board_id);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(ext_drv_sys_get_board_id, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_CHIP_NAME_ID_ADDR / sizeof(td_u32);
|
|
writel(chip_name_id, lpmcu_vir_addr);
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_CHIP_REVERSION_ADDR / sizeof(td_u32);
|
|
tmp.val32 = 0;
|
|
tmp.val16[0] = chip_revision;
|
|
tmp.val16[1] = (td_u16)board_id;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_GPIO_AON_GROUP_ADDR / sizeof(td_u32);
|
|
tmp.val32 = 0;
|
|
tmp.val8[0] = (td_u8)g_dts_info.gpio_aon_group_max;
|
|
tmp.val8[1] = (td_u8)g_dts_info.gpio_aon_group_min;
|
|
writel(tmp.val32, lpmcu_vir_addr);
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_REG_MUTE_ADDR / sizeof(td_u32);
|
|
writel(g_dts_info.reg_mute_addr, lpmcu_vir_addr);
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_MUTE_WAKEUP_ENABLE_VALUE / sizeof(td_u32);
|
|
writel(g_dts_info.mute_wakeup_enable, lpmcu_vir_addr);
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_MUTE_WAKEUP_DISABLE_VALUE / sizeof(td_u32);
|
|
writel(g_dts_info.mute_wakeup_disable, lpmcu_vir_addr);
|
|
|
|
#if defined(CONFIG_RESERVED13) || defined(CONFIG_RESERVED9)
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_PRODUCT_FLAG_ADDR / sizeof(td_u32);
|
|
writel(g_dts_info.product_flag, lpmcu_vir_addr);
|
|
#endif
|
|
|
|
ret = pmoc_set_default_custom_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_set_default_custom_param, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 pmoc_load_lpmcu(td_void)
|
|
{
|
|
td_u32 i;
|
|
td_s32 ret;
|
|
td_u32 *lpmcu_vir_addr = TD_NULL;
|
|
|
|
soc_dbg_func_enter();
|
|
|
|
ret = pmoc_try_loading_firmware();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_try_loading_firmware, ret);
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_STANDBY_DATA_ADDR / sizeof(td_u32);
|
|
for (i = 0; i < LPMCU_STANDBY_DATA_SIZE / sizeof(td_u32); i++) {
|
|
writel(0, lpmcu_vir_addr++);
|
|
}
|
|
|
|
lpmcu_vir_addr = g_lpmcu_base + LPMCU_LOG_FLAG_ADDR / sizeof(td_u32);
|
|
if (readl(lpmcu_vir_addr) != LPMCU_LOG_WRITE_FLAG) {
|
|
for (i = 0; i < (LPMCU_LOG_TOTLE_SIZE >> 2); i++) { /* right shift 2 means from byte to word */
|
|
writel(0, lpmcu_vir_addr++);
|
|
}
|
|
}
|
|
|
|
ret = pmoc_load_standby_param();
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(pmoc_load_standby_param, ret);
|
|
goto exit;
|
|
}
|
|
|
|
soc_dbg_func_exit();
|
|
return TD_SUCCESS;
|
|
|
|
exit:
|
|
if (g_pmoc_thread != TD_NULL) {
|
|
osal_kthread_destroy(g_pmoc_thread, 1);
|
|
g_pmoc_thread = TD_NULL;
|
|
}
|
|
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
td_void pmoc_unload_lpmcu(td_void)
|
|
{
|
|
if (g_pmoc_thread != TD_NULL) {
|
|
osal_kthread_destroy(g_pmoc_thread, 1);
|
|
g_pmoc_thread = TD_NULL;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
td_s32 pmoc_sem_init(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = osal_sem_init(&g_pmoc_sem, 1);
|
|
if (ret != TD_SUCCESS) {
|
|
soc_err_print_call_fun_err(osal_sem_init, ret);
|
|
return ret;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_void pmoc_sem_deinit(td_void)
|
|
{
|
|
osal_sem_destroy(&g_pmoc_sem);
|
|
|
|
return;
|
|
}
|
|
|
|
td_s32 pmoc_register_remap(td_void)
|
|
{
|
|
g_lpmcu_base = osal_ioremap_nocache(LPMCU_RAM_BASE, LPMCU_SIZE);
|
|
if (g_lpmcu_base == TD_NULL) {
|
|
soc_err_print_call_fun_err(osal_ioremap_nocache, TD_FAILURE);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_void pmoc_register_unmap(td_void)
|
|
{
|
|
osal_iounmap(g_lpmcu_base, LPMCU_SIZE);
|
|
return;
|
|
}
|
|
|
|
td_s32 pmoc_dts_read(td_void)
|
|
{
|
|
td_s32 ret;
|
|
|
|
ret = osal_dts_get_u32_byname("huanglong,pmoc", "pmoc_gpio_aon_group_min", &g_dts_info.gpio_aon_group_min);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = osal_dts_get_u32_byname("huanglong,pmoc", "pmoc_gpio_aon_group_max", &g_dts_info.gpio_aon_group_max);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = osal_dts_get_u32_byname("huanglong,pmoc", "reg_mute", &g_dts_info.reg_mute_addr);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = osal_dts_get_u32_byname("huanglong,pmoc", "mute_wakeup_enable", &g_dts_info.mute_wakeup_enable);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
ret = osal_dts_get_u32_byname("huanglong,pmoc", "mute_wakeup_disable", &g_dts_info.mute_wakeup_disable);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
|
|
#if defined(CONFIG_RESERVED13) || defined(CONFIG_RESERVED9)
|
|
ret = osal_dts_get_u32_byname("huanglong,pmoc", "product_flag", &g_dts_info.product_flag);
|
|
if (ret < 0) {
|
|
soc_err_print_call_fun_err(osal_dts_get_u32_byname, ret);
|
|
return TD_FAILURE;
|
|
}
|
|
#endif
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|
|
td_s32 pmoc_get_dts_data(pmoc_dts_info *info)
|
|
{
|
|
pmoc_check_param_return_if(info == TD_NULL, TD_FAILURE);
|
|
|
|
*info = g_dts_info;
|
|
|
|
return TD_SUCCESS;
|
|
}
|
|
|