summaryrefslogtreecommitdiff
path: root/common/enter_fastboot_mode.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/enter_fastboot_mode.c')
-rwxr-xr-xcommon/enter_fastboot_mode.c300
1 files changed, 300 insertions, 0 deletions
diff --git a/common/enter_fastboot_mode.c b/common/enter_fastboot_mode.c
new file mode 100755
index 0000000..afbb939
--- /dev/null
+++ b/common/enter_fastboot_mode.c
@@ -0,0 +1,300 @@
+/*++
+Copyright (c) 2014 WonderMedia Technologies, Inc.
+
+This program is free software: you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free Software
+Foundation, either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+should have received a copy of the GNU General Public License along with this
+program. If not, see http://www.gnu.org/licenses/>.
+
+WonderMedia Technologies, Inc.
+2014-06-20, HowayHuo, ShenZhen
+--*/
+
+/*--- History -------------------------------------------------------------------
+* DATE | AUTHORS | DESCRIPTION
+* 2014/06/20 Howay Huo v1.0, First Release
+*
+*------------------------------------------------------------------------------*/
+
+#include <common.h>
+#include "../board/wmt/include/wmt_pmc.h"
+#include "../board/wmt/include/wmt_iomux.h"
+#include "wmt_display/wmt_display.h"
+#include "wmt_display/minivgui.h"
+
+/*
+* Format:
+* setenv wmt.fastboot.key enable:powerkey:gpiono:active
+* Example:
+* Press PowerKey and GPIO10(volume-) key in the same time to force enter fastboot
+* The GPIO10 is low level when pressing the volume- key
+*
+* setenv wmt.fastboot.key 1:1:10:0
+*/
+#define ENV_FASTBOOT_KEY "wmt.fastboot.key"
+
+/*
+* setenv wmt.fastboot.checktime 1000
+*/
+#define ENV_FASTBOOT_CHECKTIME "wmt.fastboot.checktime"
+
+static char* CMD_LOAD_FASTBOOT_FILE_FROM_SDCARD = "fatload mmc 0 0 fastboot.enter";
+static char* CMD_LOAD_FASTBOOT_FILE_FROM_UDISK = "fatload usb 0 0 fastboot.enter";
+
+typedef struct _FASTBOOT_KEY_ENV_ {
+ int enable; // 1: enable the function of pressing key to enter fastboot. 0: don't enable
+ int powerkey; // 1: press powerkey+gpiokey combination 0: don't press powerkey, only press gpiokey
+ int gpiono; // the gpio no of gpiokey
+ int active; // 1: the gpio level is 1 when the gpiokey is pressed. 0: the gpio level is 0 when the gpiokey is pressed
+} FASTBOOT_KEY_ENV;
+
+static FASTBOOT_KEY_ENV default_fastboot_key = {
+ .enable = 1, // enable pressing key to enter fastboot
+ .powerkey = 1, // powerkey+gpiokey combination
+ .gpiono = 10, // Using GPIO10. GPIO10 is volume- key
+ .active = 0 // the gpio level is 0 when the volume- key is pressed
+};
+
+extern int usb_plugin(void);
+extern void udc_fastboot_exit(void);
+extern int fastboot_loop(int check_usb_plugin);
+
+void run_fastboot(int backlight_on)
+{
+ if(backlight_on)
+ show_text_to_screen("Enter Fastboot Mode", 0xFF00);
+ else
+ show_text_to_screen_no_backlight("Enter Fastboot Mode", 0xFF00);
+
+ printf("Enter Fastboot Mode\n");
+ fastboot_loop(1);
+}
+
+static void set_pwm_duty(int duty_percent)
+{
+ int duty;
+
+ if(!(g_display_vaild & DISPLAY_ENABLE))
+ return;
+
+ if (g_display_param.vout == VPP_VOUT_LCD) {
+ if ((g_display_vaild & PWMDEFMASK) == PWMDEFTP) {
+ if(duty_percent <= g_pwm_setting.duty) {
+ lcd_blt_set_pwm(g_pwm_setting.pwm_no,
+ duty_percent, g_pwm_setting.period);
+
+ mdelay(10);
+ }
+ } else {
+ duty = (duty_percent * g_pwm_setting.period) / 100;
+ if(duty <= g_pwm_setting.duty) {
+ pwm_set_duty(g_pwm_setting.pwm_no, duty - 1);
+
+ mdelay(10);
+ }
+ }
+ }
+}
+
+static void enter_fastboot_mode(FASTBOOT_KEY_ENV *p_fastboot_key)
+{
+ char tmpbuf[50];
+ int len;
+
+ if(p_fastboot_key->powerkey)
+ len = sprintf(tmpbuf, "Power key and GPIO%d key are pressed", p_fastboot_key->gpiono);
+ else
+ len = sprintf(tmpbuf, "GPIO%d key is long pressed", p_fastboot_key->gpiono);
+
+ tmpbuf[len] = 0;
+
+ printf("%s\n", tmpbuf);
+ printf("Enter Fastboot Mode\n");
+
+ /*
+ Why set the pwm to 30%?
+ If the MID no battery, the board maybe be reset by PMIC when light the backlight.
+ Set pwm duty to 30% for avoiding the board is reset
+ */
+ set_pwm_duty(30);
+
+ show_2lines_text_to_screen(tmpbuf, "Enter Fastboot Mode", 0xFF00);
+
+ fastboot_loop(0);
+}
+
+static int parse_fastboot_key_env(char *name, FASTBOOT_KEY_ENV *p_env)
+{
+ enum
+ {
+ idx_enable,
+ idx_powerkey,
+ idx_gpiono,
+ idx_active,
+ idx_max
+ };
+
+ char *p;
+ long ps[idx_max] = {0};
+ char * endp;
+ int i = 0;
+
+ p = getenv(name);
+ if (!p)
+ return -1;
+
+ while (i < idx_max) {
+ ps[i++] = simple_strtoul(p, &endp, 0);
+
+ if (*endp == '\0')
+ break;
+ p = endp + 1;
+
+ if (*p == '\0')
+ break;
+ }
+
+ p_env->enable = ps[0];
+ p_env->powerkey = ps[1];
+ p_env->gpiono = ps[2];
+ p_env->active = ps[3];
+
+ if(i != 4) {
+ printf("parse_fastboot_key_env: wrong env num in %s\n", name);
+ return -1;
+ }
+
+ if(p_env->enable == 0)
+ return 0;
+
+ if(gpio_is_valid(p_env->gpiono))
+ return 0;
+ else {
+ printf("parse_fastboot_key_env: wrong gpio no in %s\n", name);
+ return -1;
+ }
+}
+
+#define PERIOD_OF_CHECKING_PRESS_KEY 100 // 100 ms //How long time to check whether the keys are pressed
+#define CHECK_TIME_OF_PRESSING_KEY 1000 // 1s //The Total check time
+
+/*
+* Function: enter_fastboot_by_press_key
+* Purpose:
+* long press power key + volume- key to force enter fastboot
+* or long press volume- key to force enter fastboot
+*
+* Return:
+* 0 : success to enter fastboot
+* -1: fail to enter fastboot
+*
+*/
+int enter_fastboot_by_press_key(void)
+{
+ int i, ret;
+ int gpio_key_pressed;
+ unsigned int checktime, checkcount;
+ char *s;
+ FASTBOOT_KEY_ENV fastboot_key;
+
+ ret = parse_fastboot_key_env(ENV_FASTBOOT_KEY, &fastboot_key);
+ if(ret)
+ memcpy(&fastboot_key, &default_fastboot_key, sizeof(FASTBOOT_KEY_ENV));
+
+ if(fastboot_key.enable == 0)
+ return -1;
+
+ if(fastboot_key.powerkey == 1) {
+ if(!(PMPB_VAL & BIT24))
+ return -1;
+ }
+
+ s = getenv(ENV_FASTBOOT_CHECKTIME);
+ if(s) {
+ checktime = simple_strtoul(s, NULL, 0);
+ printf("Manually set fastboot checktime: %u ms\n", checktime);
+ } else
+ checktime = CHECK_TIME_OF_PRESSING_KEY;
+
+ checkcount = checktime / PERIOD_OF_CHECKING_PRESS_KEY;
+ if(checkcount == 0)
+ return -1;
+
+ if(fastboot_key.active != 0)
+ fastboot_key.active = 1;
+
+ gpio_direction_input(fastboot_key.gpiono);
+ gpio_setpull(fastboot_key.gpiono, fastboot_key.active? GPIO_PULL_DOWN : GPIO_PULL_UP);
+
+ for(i = 0; i < checkcount; i++) {
+ if(i != 0)
+ udelay(PERIOD_OF_CHECKING_PRESS_KEY * 1000);
+
+ if(fastboot_key.powerkey == 1) {
+ if(!(PMPB_VAL & BIT24))
+ return -1;
+ }
+
+ gpio_key_pressed = (gpio_get_value(fastboot_key.gpiono) == fastboot_key.active);
+ if(gpio_key_pressed == 0)
+ return -1;
+ }
+
+ udc_fastboot_exit();
+ enter_fastboot_mode(&fastboot_key);
+
+ return 0;
+}
+
+/*
+* Function: enter_fastboot_by_special_file
+* Purpose:
+* If the "fastboot.enter" file in the root directory of SD Card or U Disk,
+* and the USB Adapter is plugined, force enter fastboot
+*
+* Parameter:
+* in_sdcard: 1: the "fastboot.enter" file in SD Card
+* 0: the "fastboot.enter" file in U Disk
+*
+* Return:
+* 0 : success to enter fastboot
+* -1: fail to enter fastboot
+*
+*/
+int enter_fastboot_by_special_file(int in_sdcard)
+{
+ int len;
+ char tmpbuf[50] = {0};
+
+ if(usb_plugin() == 0)
+ return -1;
+
+ if(in_sdcard) {
+ if(run_command(CMD_LOAD_FASTBOOT_FILE_FROM_SDCARD, 0) == -1)
+ return -1;
+ } else {
+ if(run_command(CMD_LOAD_FASTBOOT_FILE_FROM_UDISK, 0) == -1)
+ return -1;
+ }
+
+ len = sprintf(tmpbuf, "fastboot.enter in %s and USB Adapter Plugin", in_sdcard ? "SDCard" : "UDISK");
+ tmpbuf[len] = 0;
+
+ printf("%s\n", tmpbuf);
+ printf("Enter Fastboot Mode\n");
+
+ set_pwm_duty(30);
+
+ show_2lines_text_to_screen(tmpbuf, "Enter Fastboot Mode", 0xFF00);
+
+ udc_fastboot_exit();
+ fastboot_loop(0);
+
+ return 0;
+}
+