Product: Import prouct app for aocpu base on riscv to RTOS SDK [1/1]

PD#SWPL-61470

Problem:
Import prouct app for aocpu base on riscv to RTOS SDK.

Solution:
Import prouct app for aocpu base on riscv to RTOS SDK.

Verify:
T5D_AM301

Change-Id: Ic56c1455903ecd8ff312433323bd88f49746ed41
Signed-off-by: Xiaohu.Huang <xiaohu.huang@amlogic.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..0b68162
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,19 @@
+cmake_minimum_required(VERSION 3.13.1)
+project(aml-rtos)
+
+include($ENV{SDK_BASE}/build/cmake/root.cmake)
+
+target_include_directories(
+	${TARGET_NAME} PUBLIC include
+	${SDK_BASE}/products/${PRODUCT}/include
+)
+
+aml_sources(
+	util.c
+	fsm.c
+	btwake.c
+	keypad.c
+	power.c
+	main.c
+)
+
diff --git a/btwake.c b/btwake.c
new file mode 100644
index 0000000..bcd6f89
--- /dev/null
+++ b/btwake.c
@@ -0,0 +1,44 @@
+#include <string.h>
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "suspend.h"
+#include "task.h"
+#include "gpio.h"
+
+#include "queue.h"    /* RTOS queue related API prototypes. */
+#include "timers.h"   /* Software timer related API prototypes. */
+#include "semphr.h"   /* Semaphore related API prototypes. */
+
+#define BT_WAKE_HOST GPIOB_13  //bt_wake_host pin
+#define INFO(fmt, args...) printf("[%s] " fmt "\n", __func__, ##args)
+
+void Bt_IRQHandle(void);
+void Bt_GpioIRQRegister(void);
+void Bt_GpioIRQFree(void);
+
+void Bt_IRQHandle(void)
+{
+	uint32_t buf[4] = {0};
+
+	INFO("bt resume");
+	vDisableGpioIRQ(BT_WAKE_HOST);
+	if (!xGpioGetValue(BT_WAKE_HOST)) {
+		buf[0] = BT_WAKEUP;
+		INFO("power key");
+		STR_Wakeup_src_Queue_Send_FromISR(buf);
+	}
+}
+
+void Bt_GpioIRQRegister(void)
+{
+	INFO();
+	xGpioSetDir(BT_WAKE_HOST, GPIO_DIR_IN);
+	xRequestGpioIRQ(BT_WAKE_HOST, Bt_IRQHandle, IRQF_TRIGGER_FALLING);
+}
+
+void Bt_GpioIRQFree(void)
+{
+	vFreeGpioIRQ(BT_WAKE_HOST);
+}
+
+
diff --git a/fsm.c b/fsm.c
new file mode 100644
index 0000000..ffab7b2
--- /dev/null
+++ b/fsm.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2014-2018 Amlogic, Inc. All rights reserved.
+ *
+ * All information contained herein is Amlogic confidential.
+ *
+ * This software is provided to you pursuant to Software License Agreement
+ * (SLA) with Amlogic Inc ("Amlogic"). This software may be used
+ * only in accordance with the terms of this agreement.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification is strictly prohibited without prior written permission from
+ * Amlogic.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "FreeRTOS.h" /* Must come first. */
+#include "task.h"     /* RTOS task related API prototypes. */
+#include "queue.h"    /* RTOS queue related API prototypes. */
+#include "timers.h"   /* Software timer related API prototypes. */
+#include "semphr.h"   /* Semaphore related API prototypes. */
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include "n200_func.h"
+#include "common.h"
+#include "riscv_encoding.h"
+#include "mailbox-api.h"
+#include "irq.h"
+
+typedef enum a {
+    PM_CPU_PWR,
+    PM_CPU_CORE0,
+    PM_CPU_CORE1,
+    PM_CPU_CORE2,
+    PM_CPU_CORE3,
+} PM_E;
+
+static void *xMboxCoreFsmIdle(void *msg)
+{
+	PM_E domain = *(uint32_t *)msg;
+
+	switch (domain) {
+		case PM_CPU_CORE0:
+			REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 0), 0);
+			EnableIrq(IRQ_NUM_OUT_0);
+			break;
+		case PM_CPU_CORE1:
+			REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 1), 0);
+			EnableIrq(IRQ_NUM_OUT_1);
+			break;
+		case PM_CPU_CORE2:
+			REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 2), 0);
+			EnableIrq(IRQ_NUM_OUT_2);
+			break;
+		case PM_CPU_CORE3:
+			REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << 3), 0);
+			EnableIrq(IRQ_NUM_OUT_3);
+			break;
+		default:
+			break;
+	}
+	return NULL;
+}
+
+static void xSetCoreFsmAwakeIrq(int cpuid)
+{
+	REG32_UPDATE_BITS(ISA_SOFT_IRQ, (1 << cpuid), (1 << cpuid));
+}
+static void xCore0FsmIdleHandleIsr(void)
+{
+	xSetCoreFsmAwakeIrq(0);
+	DisableIrq(IRQ_NUM_OUT_0);
+}
+
+static void xCore1FsmIdleHandleIsr(void)
+{
+	xSetCoreFsmAwakeIrq(1);
+	DisableIrq(IRQ_NUM_OUT_1);
+}
+
+static void xCore2FsmIdleHandleIsr(void)
+{
+	xSetCoreFsmAwakeIrq(2);
+	DisableIrq(IRQ_NUM_OUT_2);
+}
+
+static void xCore3FsmIdleHandleIsr(void)
+{
+	xSetCoreFsmAwakeIrq(3);
+	DisableIrq(IRQ_NUM_OUT_3);
+}
+
+#if 0
+#define     PWRCTRL_CPU1_FSM_STS0   (0xff644000 + (0x097 << 2))
+void checkstatus(void)
+{
+	unsigned value;
+
+	printf("\n\n");
+	value = REG32(PWRCTRL_CPU0_FSM_STS0);
+	value = ((value >> 12) & 0x1f);
+	if (value != 0)
+		printf("sts0:%x\n", value);
+
+	value = REG32(PWRCTRL_CPU1_FSM_STS0);
+	value = ((value >> 12) & 0x1f);
+	if (value != 0)
+		printf("sts1:%x\n", value);
+
+	value = REG32(PWRCTRL_CPU2_FSM_STS0);
+	value = ((value >> 12) & 0x1f);
+	if (value != 0)
+		printf("sts2:%x\n", value);
+
+	value = REG32(PWRCTRL_CPU3_FSM_STS0);
+	value = ((value >> 12) & 0x1f);
+	if (value != 0)
+		printf("sts3:%x\n", value);
+}
+#endif
+
+void vCoreFsmIdleInit(void);
+void vCoreFsmIdleInit(void)
+{
+	int ret;
+
+	ret = xInstallRemoteMessageCallbackFeedBack(AOTEE_CHANNEL, MBX_CMD_CPU_FSM_IDLE,
+						xMboxCoreFsmIdle, 0);
+	if (ret == MBOX_CALL_MAX)
+		printf("mbox cmd 0x%x register fail\n", MBX_CMD_CPU_FSM_IDLE);
+
+	RegisterIrq(IRQ_NUM_OUT_0, 1, xCore0FsmIdleHandleIsr);
+	RegisterIrq(IRQ_NUM_OUT_1, 1, xCore1FsmIdleHandleIsr);
+	RegisterIrq(IRQ_NUM_OUT_2, 1, xCore2FsmIdleHandleIsr);
+	RegisterIrq(IRQ_NUM_OUT_3, 1, xCore3FsmIdleHandleIsr);
+	REG32_UPDATE_BITS(SEC_SYS_CPU_CFG10, 0xF << 10, 0xF << 10);
+}
diff --git a/include/keypad.h b/include/keypad.h
new file mode 100644
index 0000000..f3aff62
--- /dev/null
+++ b/include/keypad.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2014-2018 Amlogic, Inc. All rights reserved.
+ *
+ * All information contained herein is Amlogic confidential.
+ *
+ * This software is provided to you pursuant to Software License Agreement
+ * (SLA) with Amlogic Inc ("Amlogic"). This software may be used
+ * only in accordance with the terms of this agreement.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification is strictly prohibited without prior written permission from
+ * Amlogic.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef __MESON_Button_H
+#define __MESON_Button_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "common.h"
+#include <stdlib.h>
+#include <string.h>
+#include "FreeRTOS.h"
+#include <timers.h>
+#include <task.h>
+#include <gpio.h>
+#include <saradc.h>
+
+/*common macro*/
+#define TIMER_CYCLE_TIME		20
+#define KEY_JITTER_COUNT		1
+
+/* adc key param */
+#define SAMPLE_DEVIATION		40
+#define ADCKEY_ID_BASE			512
+
+/* key event */
+#define EVENT_SHORT			(1 << 0)
+#define EVENT_LONG			(1 << 1)
+
+/* key threshold */
+#define THRESHOLD_LONG			2000
+
+enum KeyType{
+	GPIO_KEY = 0,
+	ADC_KEY,
+	KEY_TYPE_NUM
+};
+
+enum GpioLevel {
+	LOW = 0,
+	HIGH
+};
+
+enum KeyState{
+	UP = 0,
+	DOWN,
+};
+
+struct xReportEvent {
+	uint32_t ulCode;
+	uint32_t event;
+	TickType_t responseTime;
+	void *data;
+};
+
+struct xKeyInitInfo {
+	uint32_t ulKeyId;
+	uint32_t eventMask;
+	uint32_t repeatTimeMs;
+	uint32_t repeatDelayTimeMs;
+	uint32_t longDTTMs;
+	uint32_t doubleDTTMs;
+	uint32_t combLongDTTMs;
+	uint32_t combDTTMs;
+	void (*CallBack)(struct xReportEvent);
+	void *data;
+};
+
+struct xGpioKeyInfo {
+	int ulInitLevel;
+	struct xKeyInitInfo keyInitInfo;
+};
+
+struct xAdcKeyInfo {
+	int32_t ulValue;
+	AdcInstanceConfig_t xAdcDecp;
+	struct xKeyInitInfo keyInitInfo;
+};
+
+#define KEY_INIT_INFO(_ulKeyId, _eventMask,	_repeatTimeMs,\
+		      _repeatDelayTimeMs, _longDTTMs, _doubleDTTMs,\
+		      _combLongDTTMs, _combDTTMs, _CallBack, _data) {	\
+	.ulKeyId = _ulKeyId,		\
+	.eventMask = _eventMask,		\
+	.repeatTimeMs = _repeatTimeMs,		\
+	.repeatDelayTimeMs = _repeatDelayTimeMs,	\
+	.longDTTMs = _longDTTMs,		\
+	.doubleDTTMs = _doubleDTTMs,	\
+	.combLongDTTMs = _combLongDTTMs,		\
+	.combDTTMs = _combDTTMs,		\
+	.CallBack = _CallBack,		\
+	.data = _data,			\
+}
+
+#define GPIO_KEY_INFO(_ulKeyId, _ulInitLevel, _eventMask,\
+		      _CallBack, _data) {	\
+	.ulInitLevel = _ulInitLevel,		\
+	.keyInitInfo = KEY_INIT_INFO(_ulKeyId, _eventMask, 0, 0, 0,\
+				     0, 0, 0, _CallBack, _data),\
+}
+
+#define ADC_KEY_INFO(_ulKeyId, _ulValue, _adcChan, _eventMask,\
+		     _CallBack, _data) {	\
+	.ulValue = _ulValue,			\
+	.xAdcDecp = {_adcChan, NO_AVERAGING, 1},			\
+	.keyInitInfo = KEY_INIT_INFO(_ulKeyId, _eventMask, 0, 0, 0,\
+				     0, 0, 0, _CallBack, _data),\
+}
+
+void vCreateGpioKey(struct xGpioKeyInfo *keyArr, uint16_t keyNum);
+void vDestoryGpioKey(void);
+void vGpioKeyEnable(void);
+void vGpioKeyDisable(void);
+int  vGpioKeyIsEmpty(void);
+
+void vCreateAdcKey(struct xAdcKeyInfo *keyArr, uint16_t keyNum);
+void vDestoryAdcKey(void);
+void vAdcKeyEnable(void);
+void vAdcKeyDisable(void);
+int  vAdcKeyIsEmpty(void);
+
+void vKeyPadCreate(void);
+void vKeyPadInit(void);
+void vKeyPadDeinit(void);
+
+void vDynamicKeypadInit(void);
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/include/power.h b/include/power.h
new file mode 100644
index 0000000..97001b0
--- /dev/null
+++ b/include/power.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2014-2018 Amlogic, Inc. All rights reserved.
+ *
+ * All information contained herein is Amlogic confidential.
+ *
+ * This software is provided to you pursuant to Software License Agreement
+ * (SLA) with Amlogic Inc ("Amlogic"). This software may be used
+ * only in accordance with the terms of this agreement.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification is strictly prohibited without prior written permission from
+ * Amlogic.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+extern void str_hw_init(void);
+extern void str_hw_disable(void);
+extern void str_power_on(int shutdown_flag);
+extern void str_power_off(int shutdown_flag);
+
diff --git a/include/util.h b/include/util.h
new file mode 100644
index 0000000..c5faa2e
--- /dev/null
+++ b/include/util.h
@@ -0,0 +1,165 @@
+/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Various utility functions and macros */
+
+#ifndef __CROS_EC_UTIL_H
+#define __CROS_EC_UTIL_H
+
+#include "common.h"
+
+#include <stddef.h>
+
+/**
+ * Trigger a debug exception if the condition
+ * is not verified at runtime.
+ */
+
+
+/* Standard macros / definitions */
+#ifndef MAX
+#define MAX(a, b)					\
+	({						\
+		__typeof__(a) temp_a = (a);		\
+		__typeof__(b) temp_b = (b);		\
+							\
+		temp_a > temp_b ? temp_a : temp_b;	\
+	})
+#endif
+#ifndef MIN
+#define MIN(a, b)					\
+	({						\
+		__typeof__(a) temp_a = (a);		\
+		__typeof__(b) temp_b = (b);		\
+							\
+		temp_a < temp_b ? temp_a : temp_b;	\
+	})
+#endif
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+/*
+ * Convert a pointer to a base struct into a pointer to the struct that
+ * contains the base struct.  This requires knowing where in the contained
+ * struct the base struct resides, this is the member parameter to downcast.
+ */
+#define DOWNCAST(pointer, type, member)					\
+	((type *)(((uint8_t *) pointer) - offsetof(type, member)))
+
+/* True of x is a power of two */
+#define POWER_OF_TWO(x) (x && !(x & (x - 1)))
+
+/**
+ * macros for integer division with various rounding variants
+ * default integer division rounds down.
+ */
+#define DIV_ROUND_UP(x, y) (((x) + ((y) - 1)) / (y))
+#define DIV_ROUND_NEAREST(x, y) (((x) + ((y) / 2)) / (y))
+#define DIV_ROUND_CLOSEST(x, divisor)(                  \
+{                                                       \
+        typeof(x) __x = x;                              \
+        typeof(divisor) __d = divisor;                  \
+        (((typeof(x))-1) > 0 ||                         \
+         ((typeof(divisor))-1) > 0 || (__x) > 0) ?      \
+                (((__x) + ((__d) / 2)) / (__d)) :       \
+                (((__x) - ((__d) / 2)) / (__d));        \
+}                                                       \
+)
+
+/**
+ * Parses a boolean option from a string.
+ *
+ * Strings that set *dest=0 and return 1 (all case-insensitive):
+ *   "off"
+ *   "dis*"
+ *   "n*"
+ *   "f*"
+ *
+ * Strings that set *dest=1 and return 1 (all case-insensitive):
+ *   "on"
+ *   "ena*"
+ *   "y*"
+ *   "t*"
+ *
+ * Other strings return 0 and leave *dest unchanged.
+ */
+int parse_bool(const char *s, int *dest);
+
+/* 64-bit divide-and-modulo.  Does the equivalent of:
+ *
+ *   r = *n % d;
+ *   *n /= d;
+ *   return r;
+ */
+int uint64divmod(uint64_t *v, int by);
+
+/**
+ * Get-and-clear next bit from mask.
+ *
+ * Starts with most significant bit.
+ *
+ * @param mask Bitmask to extract next bit from. Must NOT be zero.
+ * @return bit position (0..31)
+ */
+int get_next_bit(uint32_t *mask);
+
+
+/****************************************************************************/
+/* Conditional stuff.
+ *
+ * We often need to watch for transitions between one state and another, so
+ * that we can issue warnings or take action ONCE. This abstracts that "have I
+ * already reacted to this" stuff into a single set of functions.
+ *
+ * For example:
+ *
+ *     cond_t c;
+ *
+ *     cond_init_false(&c);
+ *
+ *     while(1) {
+ *         int val = read_some_gpio();
+ *         cond_set(&c, val);
+ *
+ *         if (cond_went_true(&c))
+ *             host_event(SOMETHING_HAPPENED);
+ *     }
+ *
+ */
+typedef uint8_t cond_t;
+
+/* Initialize a conditional to a specific state. Do this first. */
+void cond_init(cond_t *c, int boolean);
+static inline void cond_init_false(cond_t *c) { cond_init(c, 0); }
+static inline void cond_init_true(cond_t *c) { cond_init(c, 1); }
+
+/* Set the current state. Do this as often as you like. */
+void cond_set(cond_t *c, int boolean);
+static inline void cond_set_false(cond_t *c) { cond_set(c, 0); }
+static inline void cond_set_true(cond_t *c) { cond_set(c, 1); }
+
+/* Get the current state. Do this as often as you like. */
+int cond_is(cond_t *c, int boolean);
+static inline int cond_is_false(cond_t *c) { return cond_is(c, 0); }
+static inline int cond_is_true(cond_t *c) { return cond_is(c, 1); }
+
+/* See if the state has transitioned. If it has, the corresponding function
+ * will return true ONCE only, until it's changed back.
+ */
+int cond_went(cond_t *c, int boolean);
+static inline int cond_went_false(cond_t *c) { return cond_went(c, 0); }
+static inline int cond_went_true(cond_t *c) { return cond_went(c, 1); }
+
+/****************************************************************************/
+/* Console command parsing */
+
+/* Parse command-line arguments given integer shift value to obtain
+ * offset and size.
+ */
+
+int __clzsi2(int x);
+
+#endif  /* __CROS_EC_UTIL_H */
diff --git a/keypad.c b/keypad.c
new file mode 100644
index 0000000..5364973
--- /dev/null
+++ b/keypad.c
@@ -0,0 +1,58 @@
+#include <string.h>
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "ir.h"
+#include "keypad.h"
+#include "gpio.h"
+#include "saradc.h"
+#include "suspend.h"
+
+/*KEY ID*/
+#define ADC_KEY_ID_HOME		520
+
+static void vAdcKeyCallBack(struct xReportEvent event)
+{
+	uint32_t buf[4] = {0};
+
+	switch (event.ulCode) {
+	case ADC_KEY_ID_HOME:
+		buf[0] = POWER_KEY_WAKEUP;
+		STR_Wakeup_src_Queue_Send(buf);
+		break;
+	default:
+		break;
+	}
+
+	printf("ADC key event 0x%x, key code %d, responseTicks %d\n",
+		event.event, event.ulCode, event.responseTime);
+}
+
+struct xAdcKeyInfo adcKeyInfo[] = {
+	ADC_KEY_INFO(ADC_KEY_ID_HOME, 0, SARADC_CH1,
+		     EVENT_SHORT,
+		     vAdcKeyCallBack, NULL)
+};
+
+void vKeyPadCreate(void)
+{
+	vCreateAdcKey(adcKeyInfo,
+			sizeof(adcKeyInfo)/sizeof(struct xAdcKeyInfo));
+
+	vDynamicKeypadInit();
+}
+
+void vKeyPadInit(void)
+{
+	if (vAdcKeyIsEmpty())
+		vCreateAdcKey(adcKeyInfo,
+				sizeof(adcKeyInfo)/sizeof(struct xAdcKeyInfo));
+
+	vAdcKeyEnable();
+	vGpioKeyEnable();
+}
+
+void vKeyPadDeinit(void)
+{
+	vAdcKeyDisable();
+	vGpioKeyDisable();
+}
diff --git a/lscript.h b/lscript.h
new file mode 100644
index 0000000..d01eb2a
--- /dev/null
+++ b/lscript.h
@@ -0,0 +1,7 @@
+#ifndef _LSCRIPT_H_
+#define _LSCRIPT_H_
+
+#define configMEM_START		0x10000000
+#define configMEM_LEN		(64 * 1024)
+
+#endif
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..4782a35
--- /dev/null
+++ b/main.c
@@ -0,0 +1,402 @@
+#if 1
+/*
+ * IntTest.c
+ *
+ *  Created on: 2018��10��17��
+ *      Author: danialxie
+ *
+ *        This is an PIC interrupt nesting test for N200 SOC, NUCLEI, Inc.
+ *      Attention:
+ *         This test need hardware board supporting.
+ * 	       A GPIO interrupt is stimulated by another GPIO using wire connection.
+ * 	       Wire connection:
+ * 	          Source  --> Target
+ * 	          GPIO 0  --> GPIO 8
+ * 	          GPIO 1  --> GPIO 9
+ * 	          GPIO 2  --> GPIO 10
+ * 	          GPIO 3  --> GPIO 11
+ * 	          GPIO 4  --> GPIO 12
+ * 	          GPIO 5  --> GPIO 13
+ * 	          GPIO 6  --> GPIO 14
+ * 	          GPIO 7  --> GPIO 15
+ */
+
+/* Kernel includes. */
+#include "FreeRTOS.h" /* Must come first. */
+#include "task.h"     /* RTOS task related API prototypes. */
+#include "queue.h"    /* RTOS queue related API prototypes. */
+#include "timers.h"   /* Software timer related API prototypes. */
+#include "semphr.h"   /* Semaphore related API prototypes. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "n200_pic_tmr.h"
+#include "n200_func.h"
+#include "uart.h"
+#include "common.h"
+#include "mailbox-api.h"
+#include "version.h"
+#include "hdmi_cec.h"
+#include "stick_mem.h"
+#include "keypad.h"
+
+#define INT_TEST_NEST_DEPTH  6
+#define INT_TEST_GPIO_NUM  6
+#define INT_TEST_TASK_DELAY  50 // ms
+#define TASK_TEST_STACK_DEPTH  200
+
+#define TASK_TEST_QUEUE_NUM  2
+#define TASK_TEST_QUEUE_LENGTH  3
+
+//#define GPIO_INT_SOURCE(x) (SOC_PIC_INT_GPIO_BASE + x)
+
+/* Configure board type:
+ *   Board under test :        SIGNAL_BOARD_ENABLE     0
+ *   Signal generation board : SIGNAL_BOARD_ENABLE     1
+ */
+#define SIGNAL_BOARD_ENABLE       0
+
+#define INT_TEST_INT_WAVE_ENABLE  1
+
+#if INT_TEST_INT_WAVE_ENABLE
+    #define INT_TEST_TIMER_PERIOD  500    // ms
+    #define INT_TEST_INT_DELAY    10    // ms
+#else
+    #define INT_TEST_TIMER_PERIOD  500    // ms
+    #define INT_TEST_INT_DELAY    0x3ff    // ms
+#endif
+
+#define INT_TEST_MAX_TIMER_PERIOD	100 // ms
+#define INT_TEST_MIN_TIMER_PERIOD	50 // ms
+#define INT_TEST_MUTE_TIMER_PERIOD	200 // ms
+
+/* Interrupt handler */
+void GPIOInterruptHandler(uint32_t num, uint32_t priority);
+void vApplicationIdleHook( void );
+
+
+extern void trap_entry(void);
+extern void irq_entry(void);
+
+
+/* Binary Semaphore */
+QueueHandle_t xGPIOSemaphore[INT_TEST_NEST_DEPTH];
+QueueHandle_t xMessageQueue[TASK_TEST_QUEUE_NUM];
+
+/* Timer handle */
+#if BRINGUP_TEST
+TimerHandle_t xSoftTimer = NULL;
+#endif
+/*
+static void vPrintString(const char* msg)
+{
+	taskENTER_CRITICAL();
+
+	taskEXIT_CRITICAL();
+}
+*/
+/* function: vPICInit */
+static void vPICInit(void) {
+
+	// Disable global interrupter
+	clear_csr(mstatus, MSTATUS_MIE);
+
+	// Initialize interrupter handler
+	for (int i = 0; i < PIC_NUM_INTERRUPTS; i ++) {
+		pic_interrupt_handlers[i] = DefaultInterruptHandler;
+	}
+#if 0
+#if !(SIGNAL_BOARD_ENABLE)
+
+   // Enable GPIO interrupter
+	enable_interrupt(GPIO_INT_SOURCE(8),  1, GPIOInterruptHandler8);
+	enable_interrupt(GPIO_INT_SOURCE(9),  2, GPIOInterruptHandler9);
+	enable_interrupt(GPIO_INT_SOURCE(10),  3, GPIOInterruptHandler10);
+	enable_interrupt(GPIO_INT_SOURCE(11),  4, GPIOInterruptHandler11);
+	enable_interrupt(GPIO_INT_SOURCE(12),  5, GPIOInterruptHandler12);
+	enable_interrupt(GPIO_INT_SOURCE(13),  6, GPIOInterruptHandler13);
+	//enable_interrupt(GPIO_INT_SOURCE(14),  7, GPIOInterruptHandler14);
+	//enable_interrupt(GPIO_INT_SOURCE(15),  7, GPIOInterruptHandler15);
+
+#endif
+#endif
+	// Enable global interrupt
+	set_csr(mstatus, MSTATUS_MIE);
+}
+
+#if BRINGUP_TEST
+static void vPrintSystemStatus(TimerHandle_t xTimer) {
+	xTimer = xTimer;
+	taskENTER_CRITICAL();
+
+//	vUartPuts("\nTimer ...\n");
+	taskEXIT_CRITICAL();
+}
+
+static void vPrintTask1( void *pvParameters )
+{
+    /*make compiler happy*/
+    pvParameters = pvParameters;
+
+	for ( ;; )
+	{
+//		vUartPuts("\nvPTask1 %d\n");
+
+		vTaskDelay(pdMS_TO_TICKS(50));
+	}
+}
+
+static void vPrintTask2( void *pvParameters )
+{
+    /*make compiler happy*/
+    pvParameters = pvParameters;
+	vTaskDelay(pdMS_TO_TICKS(50));
+	for ( ;; )
+	{
+//		vUartPuts("\nvPTask2 %d\n");
+		vTaskDelay(pdMS_TO_TICKS(50));
+	}
+}
+#endif
+extern void vMbInit(void);
+extern void vCoreFsmIdleInit(void);
+extern void vRtcInit(void);
+extern void create_str_task(void);
+// Test target board
+int main(void)
+{
+	vUartPuts("Starting AOCPU FreeRTOS\n");
+	version();
+
+	// Initialize GPIOs, PIC and timer
+	//vGPIOInit();
+	vPICInit();
+	stick_mem_init();
+	//write watchdog flag
+	stick_mem_write(STICK_REBOOT_FLAG, 0xd);
+
+	// Delay
+	for (uint32_t i = 0; i < 0xffff; ++i);
+
+	vMbInit();
+	vCoreFsmIdleInit();
+	// Create timer
+#if BRINGUP_TEST
+	xSoftTimer = xTimerCreate("Timer", pdMS_TO_TICKS(INT_TEST_TIMER_PERIOD), pdTRUE, NULL, vPrintSystemStatus);
+
+	vUartPuts("Starting timer ...\n");
+	xTimerStart(xSoftTimer, 0);
+
+	xTaskCreate( vPrintTask1, "Print1", configMINIMAL_STACK_SIZE, NULL, 2, NULL );
+	xTaskCreate( vPrintTask2, "Print2", configMINIMAL_STACK_SIZE, NULL, 2, NULL );
+#endif
+
+	vCecCallbackInit(CEC_CHIP_T5);
+	write_csr(mtvec, &trap_entry);
+	write_csr_mivec(&irq_entry);
+
+	vRtcInit();
+	create_str_task();
+	vKeyPadCreate();
+
+	vUartPuts("Starting task scheduler ...\n");
+	vTaskStartScheduler();
+
+	for (;;)
+
+	return 0;
+}
+
+void vApplicationIdleHook( void )
+{
+   //vPrintString("enter idle task\n");
+
+   //write_csr(mie, 1); // open mstatue.mie
+   //asm volatile ("wfi"); // enter low power mode
+}
+/*-----------------------------------------------------------*/
+void vApplicationMallocFailedHook( void );
+
+void vApplicationMallocFailedHook( void )
+{
+    /* The malloc failed hook is enabled by setting
+    configUSE_MALLOC_FAILED_HOOK to 1 in FreeRTOSConfig.h.
+
+    Called if a call to pvPortMalloc() fails because there is insufficient
+    free memory available in the FreeRTOS heap.  pvPortMalloc() is called
+    internally by FreeRTOS API functions that create tasks, queues, software
+    timers, and semaphores.  The size of the FreeRTOS heap is set by the
+    configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
+	//write(1,"malloc failed\n", 14);
+
+	vUartPuts("vApplicationMallocFailedHook\n");
+	vPrintFreeListAfterMallocFail();
+    for ( ;; );
+}
+/*-----------------------------------------------------------*/
+
+void vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName );
+
+void vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName )
+{
+    ( void ) pcTaskName;
+    ( void ) xTask;
+
+    /* Run time stack overflow checking is performed if
+    configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2.  This hook
+    function is called if a stack overflow is detected.  pxCurrentTCB can be
+    inspected in the debugger if the task name passed into this function is
+    corrupt. */
+    //write(1, "Stack Overflow\n", 15);
+    for ( ;; );
+}
+/*-----------------------------------------------------------*/
+#else
+
+#include "stdint.h"
+#include "sys/cdefs.h"
+#include "FreeRTOS.h"
+#include "task.h"
+#include "timers.h"
+
+#include "common.h"
+#include "riscv_encoding.h"
+#include "n200_func.h"
+
+#if 1
+#define REG32_ADDR(addr)                        ((volatile uint32_t *)(uintptr_t)(addr))
+#define REG32(addr)                             (*REG32_ADDR(addr))
+
+#define UART_WFIFO                              (0 << 2)
+#define UART_STATUS                             (3 << 2)
+#ifdef UART_PORT_CONS
+#undef UART_PORT_CONS
+#define UART_PORT_CONS                          ((0x8c00  << 2) + 0xffd00000)
+#endif
+#define P_UART(uart_base, reg)                  (uart_base + reg)
+#define P_UART_STATUS(uart_base)                P_UART(uart_base, UART_STATUS)
+#define P_UART_WFIFO(uart_base)                 P_UART(uart_base, UART_WFIFO)
+#define UART_STAT_MASK_TFIFO_FULL               (1<<21)
+#define UART_STAT_MASK_TFIFO_EMPTY              (1<<22)
+#endif
+
+#define INT_TEST_TIMER_PERIOD_MS                (2000)
+
+#define write_csr(reg, val) ({                                \
+  if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \
+    asm volatile ("csrw " #reg ", %0" :: "i"(val));           \
+  else                                                        \
+    asm volatile ("csrw " #reg ", %0" :: "r"(val)); })
+
+int prvUartTxIsFull(void)
+{
+	return REG32(P_UART_STATUS(UART_PORT_CONS)) & UART_STAT_MASK_TFIFO_FULL;
+}
+
+void vUartTxFlush(void)
+{
+	while (! (REG32(P_UART_STATUS(UART_PORT_CONS)) & UART_STAT_MASK_TFIFO_EMPTY));
+}
+
+void vUartPutc(const char c)
+{
+	if (c == '\n')
+	{
+		vUartPutc('\r');
+	}
+
+	while (prvUartTxIsFull());
+	REG32(P_UART_WFIFO(UART_PORT_CONS)) = c;
+	vUartTxFlush();
+}
+
+void vUartPuts(const char *s)
+{
+    while (*s)
+	{
+        vUartPutc(*s++);
+	}
+}
+
+static void vPrintSystemStatus(TimerHandle_t xTimer)
+{
+	(void)xTimer;
+
+	taskENTER_CRITICAL();
+	vUartPuts("[AOCPU]:Timer ...\n");
+	taskEXIT_CRITICAL();
+}
+
+static void vPrintTask1( void *pvParameters )
+{
+    /* to be void gnerate warning from the compiler */
+    (void)pvParameters;
+
+	for ( ;; )
+	{
+		vUartPuts("[AOCPU]:Task1 process...\r\n");
+		vTaskDelay(pdMS_TO_TICKS(1000));
+	}
+}
+
+static void vPrintTask2( void *pvParameters )
+{
+    /* to be void gnerate warning from the compiler */
+    (void)pvParameters;
+
+	for ( ;; )
+	{
+		vUartPuts("[AOCPU]:Task2 process...\r\n");
+		printf("[AOCPU]:build time:[%s-%s]\r\n", __DATE__, __TIME__);
+		vTaskDelay(pdMS_TO_TICKS(1000));
+	}
+}
+
+int print_lastword_crash(const char *fmt, ...)
+{
+        return 0;
+}
+
+static void vPICInit(void) {
+
+	// Disable global interrupter
+	clear_csr(mstatus, MSTATUS_MIE);
+
+	// Initialize interrupter handler
+	for (int i = 0; i < PIC_NUM_INTERRUPTS; i ++) {
+		pic_interrupt_handlers[i] = DefaultInterruptHandler;
+	}
+
+	// Enable global interrupt
+	set_csr(mstatus, MSTATUS_MIE);
+}
+
+extern void trap_entry(void);
+extern void irq_entry(void);
+
+TimerHandle_t xSoftTimer = NULL;
+
+int main(void)
+{
+	vUartPuts("[AOCPU]:Starting AOCPU FreeRTOS\n");
+	vPICInit();
+
+	vUartPuts("[AOCPU]:Starting timer ...\n");
+	xSoftTimer = xTimerCreate("Timer", pdMS_TO_TICKS(INT_TEST_TIMER_PERIOD_MS), pdTRUE, NULL, vPrintSystemStatus);
+	xTimerStart(xSoftTimer, 0);
+
+	xTaskCreate( vPrintTask1, "Print1", configMINIMAL_STACK_SIZE, NULL, 2, NULL );
+	xTaskCreate( vPrintTask2, "Print2", configMINIMAL_STACK_SIZE, NULL, 2, NULL );
+
+	write_csr(mtvec, &trap_entry);
+	write_csr_mivec(&irq_entry);
+
+	vUartPuts("[AOCPU]:Starting task scheduler ...\n");
+	vTaskStartScheduler();
+
+	return 0;
+}
+#endif
diff --git a/power.c b/power.c
new file mode 100644
index 0000000..6f4211a
--- /dev/null
+++ b/power.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2014-2018 Amlogic, Inc. All rights reserved.
+ *
+ * All information contained herein is Amlogic confidential.
+ *
+ * This software is provided to you pursuant to Software License Agreement
+ * (SLA) with Amlogic Inc ("Amlogic"). This software may be used
+ * only in accordance with the terms of this agreement.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification is strictly prohibited without prior written permission from
+ * Amlogic.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include "FreeRTOS.h"
+#include "common.h"
+#include "gpio.h"
+#include "ir.h"
+#include "suspend.h"
+#include "task.h"
+#include "gpio.h"
+#include "pwm.h"
+#include "pwm_plat.h"
+#include "keypad.h"
+#include "hdmi_cec.h"
+
+/*#define CONFIG_ETH_WAKEUP*/
+
+#ifdef CONFIG_ETH_WAKEUP
+#include "interrupt_control.h"
+#include "eth.h"
+#include "irq.h"
+#endif
+
+static TaskHandle_t cecTask = NULL;
+static int vdd_ee;
+static int vdd_cpu;
+
+static IRPowerKey_t prvPowerKeyList[] = {
+	{ 0xef10fe01, IR_NORMAL}, /* ref tv pwr */
+	{ 0xba45bd02, IR_NORMAL}, /* small ir pwr */
+	{ 0xef10fb04, IR_NORMAL}, /* old ref tv pwr */
+	{ 0xf20dfe01, IR_NORMAL},
+	{ 0xe51afb04, IR_NORMAL},
+	{ 0xff00fe06, IR_NORMAL},
+	{ 0x3ac5bd02, IR_CUSTOM},
+	{}
+        /* add more */
+};
+
+static void vIRHandler(IRPowerKey_t *pkey)
+{
+	uint32_t buf[4] = {0};
+	if (pkey->type == IR_NORMAL)
+		buf[0] = REMOTE_WAKEUP;
+	else if (pkey->type == IR_CUSTOM)
+		buf[0] = REMOTE_CUS_WAKEUP;
+
+        /* do sth below  to wakeup*/
+	STR_Wakeup_src_Queue_Send_FromISR(buf);
+};
+
+void str_hw_init(void);
+void str_hw_disable(void);
+void str_power_on(int shutdown_flag);
+void str_power_off(int shutdown_flag);
+void Bt_GpioIRQRegister(void);
+void Bt_GpioIRQFree(void);
+
+void str_hw_init(void)
+{
+	/*enable device & wakeup source interrupt*/
+	vIRInit(MODE_HARD_NEC, GPIOD_5, PIN_FUNC1, prvPowerKeyList, ARRAY_SIZE(prvPowerKeyList), vIRHandler);
+#ifdef CONFIG_ETH_WAKEUP
+	vETHInit(IRQ_ETH_PMT_NUM,eth_handler_t5);
+#endif
+	xTaskCreate(vCEC_task, "CECtask", configMINIMAL_STACK_SIZE,
+		    NULL, CEC_TASK_PRI, &cecTask);
+	vBackupAndClearGpioIrqReg();
+	vKeyPadInit();
+	vGpioIRQInit();
+	Bt_GpioIRQRegister();
+}
+
+
+void str_hw_disable(void)
+{
+	/*disable wakeup source interrupt*/
+	vIRDeint();
+#ifdef CONFIG_ETH_WAKEUP
+	vETHDeint_t5();
+#endif
+	if (cecTask) {
+		vTaskDelete(cecTask);
+		cec_req_irq(0);
+	}
+	Bt_GpioIRQFree();
+	vKeyPadDeinit();
+	vRestoreGpioIrqReg();
+}
+
+void str_power_on(int shutdown_flag)
+{
+	int ret;
+
+	/***set vdd_ee val***/
+	ret = vPwmMesonsetvoltage(VDDEE_VOLT,vdd_ee);
+	if (ret < 0) {
+		printf("vdd_EE pwm set fail\n");
+		return;
+	}
+
+	/***set vdd_ee val***/
+	ret = vPwmMesonsetvoltage(VDDCPU_VOLT,vdd_cpu);
+	if (ret < 0) {
+		printf("vdd_CPU pwm set fail\n");
+		return;
+	}
+
+	/***power on vcc3.3***/
+	ret = xGpioSetDir(GPIOD_10,GPIO_DIR_OUT);
+	if (ret < 0) {
+		printf("vcc3.3 set gpio dir fail\n");
+		return;
+	}
+
+	ret = xGpioSetValue(GPIOD_10,GPIO_LEVEL_HIGH);
+	if (ret < 0) {
+		printf("vcc3.3 set gpio val fail\n");
+		return;
+	}
+
+	if (shutdown_flag) {
+		/***power on VDDQ/VDDCPU***/
+		ret = xGpioSetDir(GPIOD_4,GPIO_DIR_OUT);
+		if (ret < 0) {
+			printf("VDDCPU/VDDQ set gpio dir fail\n");
+			return;
+		}
+
+		ret = xGpioSetValue(GPIOD_4,GPIO_LEVEL_HIGH);
+		if (ret < 0) {
+			printf("VDDCPU/VDDQ set gpio val fail\n");
+			return;
+		}
+		/*Wait 200ms for VDDCPU statble*/
+		vTaskDelay(pdMS_TO_TICKS(200));
+	}
+
+	/***power on 5v***/
+	REG32(AO_GPIO_TEST_N) = REG32(AO_GPIO_TEST_N) | (1 << 31);
+}
+
+void str_power_off(int shutdown_flag)
+{
+	int ret;
+
+	printf("poweroff 5v\n");
+	printf("0x%x\n", REG32(AO_GPIO_TEST_N));
+
+	REG32(AO_GPIO_TEST_N) = (REG32(AO_GPIO_TEST_N) << 1) >> 1;
+
+	if (shutdown_flag) {
+		/***power off VDDQ/VDDCPU***/
+		ret = xGpioSetDir(GPIOD_4,GPIO_DIR_OUT);
+		if (ret < 0) {
+			printf("VDDCPU/VDDQ set gpio dir fail\n");
+			return;
+		}
+
+		ret = xGpioSetValue(GPIOD_4,GPIO_LEVEL_LOW);
+		if (ret < 0) {
+			printf("VDDCPU/VDDQ set gpio val fail\n");
+			return;
+		}
+	}
+
+	/***power off vcc3.3***/
+	ret = xGpioSetDir(GPIOD_10,GPIO_DIR_OUT);
+	if (ret < 0) {
+		printf("vcc3.3 set gpio dir fail\n");
+		return;
+	}
+
+#ifndef CONFIG_ETH_WAKEUP
+	ret= xGpioSetValue(GPIOD_10,GPIO_LEVEL_LOW);
+	if (ret < 0) {
+		printf("vcc3.3 set gpio val fail\n");
+		return;
+	}
+#endif
+
+	/***set vdd_cpu val***/
+	vdd_cpu = vPwmMesongetvoltage(VDDCPU_VOLT);
+	if (vdd_cpu < 0) {
+		printf("vdd_CPU pwm get fail\n");
+		return;
+	}
+
+	ret = vPwmMesonsetvoltage(VDDCPU_VOLT,700);
+	if (ret < 0) {
+		printf("vdd_CPU pwm set fail\n");
+		return;
+	}
+
+	/***set vdd_ee val***/
+	vdd_ee = vPwmMesongetvoltage(VDDEE_VOLT);
+	if (vdd_ee < 0) {
+		printf("vdd_EE pwm get fail\n");
+		return;
+	}
+
+	ret = vPwmMesonsetvoltage(VDDEE_VOLT,770);
+	if (ret < 0) {
+		printf("vdd_EE pwm set fail\n");
+		return;
+	}
+
+	//REG32( ((0x0000 << 2) + 0xff638c00)) = 0;
+}
+
diff --git a/prj.conf b/prj.conf
new file mode 100644
index 0000000..c5b6c9e
--- /dev/null
+++ b/prj.conf
@@ -0,0 +1,4 @@
+#CONFIG_LIBC_AML and CONFIG_LIBC_STD must has one to be selected
+CONFIG_LIBC_AML=y
+CONFIG_LIBC_STD=n
+
diff --git a/util.c b/util.c
new file mode 100644
index 0000000..e5a71e9
--- /dev/null
+++ b/util.c
@@ -0,0 +1,167 @@
+/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* Utility functions for Chrome EC */
+
+#include "util.h"
+#include <string.h>
+#include <ctype.h>
+
+int parse_bool(const char *s, int *dest)
+{
+	if (!strcasecmp(s, "off") || !strncasecmp(s, "dis", 3) ||
+	    tolower(*s) == 'f' || tolower(*s) == 'n') {
+		*dest = 0;
+		return 1;
+	} else if (!strcasecmp(s, "on") || !strncasecmp(s, "ena", 3) ||
+	    tolower(*s) == 't' || tolower(*s) == 'y') {
+		*dest = 1;
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+int uint64divmod(uint64_t *n, int d)
+{
+	uint64_t q = 0, mask;
+	int r = 0;
+
+	/* Divide-by-zero returns zero */
+	if (!d) {
+		*n = 0;
+		return 0;
+	}
+
+	/* Common powers of 2 = simple shifts */
+	if (d == 2) {
+		r = *n & 1;
+		*n >>= 1;
+		return r;
+	} else if (d == 16) {
+		r = *n & 0xf;
+		*n >>= 4;
+		return r;
+	}
+
+	/* If v fits in 32-bit, we're done. */
+	if (*n <= 0xffffffff) {
+		uint32_t v32 = *n;
+		r = v32 % d;
+		*n = v32 / d;
+		return r;
+	}
+
+	/* Otherwise do integer division the slow way. */
+	for (mask = (1ULL << 63); mask; mask >>= 1) {
+		r <<= 1;
+		if (*n & mask)
+			r |= 1;
+		if (r >= d) {
+			r -= d;
+			q |= mask;
+		}
+	}
+	*n = q;
+	return r;
+}
+
+int __clzsi2(int x)
+{
+	int r = 0;
+
+	if (!x)
+		return 32;
+	if (!(x & 0xffff0000u)) {
+		x <<= 16;
+		r += 16;
+	}
+	if (!(x & 0xff000000u)) {
+		x <<= 8;
+		r += 8;
+	}
+	if (!(x & 0xf0000000u)) {
+		x <<= 4;
+		r += 4;
+	}
+	if (!(x & 0xc0000000u)) {
+		x <<= 2;
+		r += 2;
+	}
+	if (!(x & 0x80000000u)) {
+		x <<= 1;
+		r += 1;
+	}
+	return r;
+}
+
+int get_next_bit(uint32_t *mask)
+{
+	int bit = 31 - __clzsi2(*mask);
+	*mask &= ~(1 << bit);
+	return bit;
+}
+
+char *strncpy (char *s1, const char *s2, size_t n)
+{
+	char c;
+	char *s = s1;
+
+	--s1;
+
+	if (n >= 4)
+	{
+		size_t n4 = n >> 2;
+
+		for (;;)
+		{
+			c = *s2++;
+			*++s1 = c;
+			if (c == '\0')
+			break;
+			c = *s2++;
+			*++s1 = c;
+			if (c == '\0')
+			break;
+			c = *s2++;
+			*++s1 = c;
+			if (c == '\0')
+			break;
+			c = *s2++;
+			*++s1 = c;
+			if (c == '\0')
+			break;
+			if (--n4 == 0)
+			goto last_chars;
+		}
+		n = n - (s1 - s) - 1;
+		if (n == 0)
+			return s;
+		goto zero_fill;
+	}
+
+	last_chars:
+	n &= 3;
+	if (n == 0)
+		return s;
+
+	do
+	{
+		c = *s2++;
+		*++s1 = c;
+		if (--n == 0)
+		return s;
+	}
+	while (c != '\0');
+
+	zero_fill:
+	do
+		*++s1 = '\0';
+	while (--n > 0);
+
+	return s;
+}
+
+