static int board_probe_power_level(void) { int power_status; int power_start; //清除power按键 axp_probe_key(); //获取电源状态 power_status = axp_get_power_vol_level(); debug("power status = %d\n", power_status); if(power_status == BATTERY_RATIO_TOO_LOW_WITHOUT_DCIN) { tick_printf("battery power is low without no dc or ac, should be set off\n"); sunxi_bmp_display("bat\\low_pwr.bmp"); __msdelay(3000); return -1; } power_start = 0; //power_start的含义 //0: 不允许插火牛直接开机,必须通过判断:满足以下条件可以直接开机:长按power按键,前次是系统状态,如果电池电量过低,则不允许开机 //1: 任意状态下,允许插火牛直接开机,同时要求电池电量足够高 //2: 不允许插火牛直接开机,必须通过判断:满足以下条件可以直接开机:长按power按键,前次是系统状态,不要求电池电量 //3: 任意状态下,允许插火牛直接开机,不要求电池电量 script_parser_fetch(PMU_SCRIPT_NAME, "power_start", &power_start, 1); debug("power start cause = %d\n", power_start); if(power_status == BATTERY_RATIO_TOO_LOW_WITH_DCIN)//低电,同时带外部电源状态下 { if(!(power_start & 0x02)) //需要判断当前电池电量,要求power_start的第1bit的值为0 { //此种情况下,直接关机 tick_printf("battery low power with dc or ac, should charge longer\n"); sunxi_bmp_display("bat\\bempty.bmp"); __msdelay(3000); return -2; } else { if(power_start == 3) //不需要判断当前电池电量,如果为3,则进入系统,如果为0,则进行后续判断 { return 0; } } } else //电池电量足够情况下,或者没有电池 { if(power_start & 0x01) //如果第0bit的值为1,则进入系统 { return 0; } } return 1; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : standby_mode: 0, 普通模式,需要检测电源状态 * * 1, 测试模式,强制进入standby模式,不论电源状态 * * return : * * note : probe power and other condition * * * ************************************************************************************************************ */ void board_status_probe(int standby_mode) { int ret; //清除power按键 axp_probe_key(); //启动条件判断,第一阶段,检测电源电压状态 if(!standby_mode) { ret = board_probe_power_level(); //负数:关机;0:进入系统;正数:待机 debug("stage1 resule %d\n", ret); if(ret < 0) { do_shutdown(NULL, 0, 1, NULL); } else if(!ret) { return ; } //启动条件判断,第二阶段,检测开机原因 ret = board_probe_poweron_cause(); //负数,0:进入系统;正数:待机或者直接关机 debug("stage2 resule %d\n", ret); if(ret <= 0) { return ; } else if(ret == AXP_VBUS_DCIN_NOT_EXIST) //当前一次为boot standby状态,但是启动时检查无外部电源,直接关机 { do_shutdown(NULL, 0, 1, NULL); } } //启动条件判断,第三阶段,检测电池存在 //负数:关机;0:进入系统;正数:待机 ret = board_probe_bat_status(standby_mode); debug("stage3 resule %d\n", ret); if(ret < 0) { do_shutdown(NULL, 0, 1, NULL); } else if(!ret) { return ; } //启动条件判断,第四阶段,进入boot待机 //负数:关机,其它:进入系统 ret = board_standby_status(ret); debug("stage4 resule %d\n", ret); if(ret < 0) { do_shutdown(NULL, 0, 1, NULL); } return ; }
int do_key_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct sunxi_lradc *sunxi_key_base = (struct sunxi_lradc *)SUNXI_KEYADC_BASE; u32 power_key = 0; puts(" press a key:\n"); sunxi_key_base->ints = 0x1f1f; while(!ctrlc()) { sunxi_key_read(); power_key = axp_probe_key(); if(power_key > 0) { break; } } return 0; }
int check_update_key(void) { int ret; int fel_key_max; int power_plug_count = 0; int new_power_status = 0; int old_power_status = 0; int time_tick = 0 ; int fel_key_mode = 0; int user_mode_used = 0; gd->key_pressd_value = 0; if(uboot_spare_head.boot_data.work_mode != WORK_MODE_BOOT) { return 0; } old_power_status = axp_probe_power_source(); sunxi_key_init(); //detect user_mode exist script_parser_fetch("platform", "user_mode_used", &user_mode_used, 1); if(user_mode_used) { printf("user_mode found\n"); fel_key_mode = 2; } //detect fel_key exist else { ret = script_parser_fetch("fel_key", "fel_key_max", &fel_key_max, 1); if(ret) { printf("fel key old mode\n"); fel_key_mode = 1; } else { printf("fel key new mode\n"); } } printf("run key detect\n"); sunxi_key_read(); __msdelay(10); if(!fel_key_mode) { int key_value; int fel_key_max, fel_key_min; time_tick = 0; key_value = sunxi_key_read(); //读取按键信息 if(key_value < 0) //没有按键按下 { printf("no key found\n"); return 0; } gd->key_pressd_value = key_value; ret = script_parser_fetch("fel_key", "fel_key_max", &fel_key_max, 1); if(ret) { printf("fel key max not found\n"); return 0; } ret = script_parser_fetch("fel_key", "fel_key_min", &fel_key_min, 1); if(ret) { printf("fel key min not found\n"); return 0; } if((key_value <= fel_key_max) && (key_value >= fel_key_min)) { printf("fel key detected\n"); return 1; } printf("fel key value %d is not in the range from %d to %d\n", key_value, fel_key_min, fel_key_max); //old_usb_plug_status = usb_probe_vbus_type(); //add by guoyingyang while(sunxi_key_read() > 0) //press key and not loosen { time_tick++; new_power_status = axp_probe_power_source(); __msdelay(KEY_DELAY_EACH_TIME); if(new_power_status != old_power_status) { power_plug_count++; old_power_status = new_power_status; } if(power_plug_count == 3) { change_to_debug_mode(); break; } if(time_tick > KEY_MAX_COUNT_GO_ON) { printf("time out\n"); break; } } return 0; } else if(fel_key_mode == 1) { int count; int value_old, value_new, value_cnt; int new_key, new_key_flag; time_tick = 0; count = 0; value_cnt = 0; new_key = 0; new_key_flag = 0; ret = sunxi_key_read(); //读取按键信息 if(ret < 0) //没有按键按下 { printf("no key found\n"); return 0; } else { value_old = ret; } gd->key_pressd_value = ret; while(1) { time_tick ++; ret = axp_probe_key(); //获取power按键信息 new_power_status = axp_probe_power_source(); //detect vbus status printf("new_power_status = %d \n",new_power_status); if(ret > 0) //检测到POWER按键按下 { count ++; } if(new_power_status != old_power_status) { debug("=======flag change========\n"); power_plug_count ++; old_power_status = new_power_status; } __msdelay(KEY_DELAY_EACH_TIME); ret = sunxi_key_read(); //读取按键信息 if(ret < 0) //没有按键按下 { printf("key not pressed anymore\n"); if(count == 1) { if(new_key >= 2) { printf("1\n"); printf("force to debug mode\n"); return -1; } } return 0; } else { value_new = ret; if(value_old == value_new) { value_cnt ++; if(new_key_flag == 1) { new_key ++; new_key_flag ++; } else if(!new_key_flag) { new_key_flag ++; } } else { new_key_flag = 0; value_old = value_new; } } if(count == 3) { printf("you can unclench the key to update now\n"); return -1; } if((!count) && (power_plug_count == 3)) { change_to_debug_mode(); return 0; } if((!count) && (time_tick >= KEY_MAX_COUNT_GO_ON)) { printf("timeout, but no power key found\n"); return 0; } } } else { int user_key_value; user_key_value = sunxi_key_read(); //读取按键信息 if(user_key_value < 0) //没有按键按下 { printf("no user_key found\n"); } else { gd->key_pressd_value = user_key_value; } return 0; } }
static int board_probe_power_level(void) { int power_status; int power_start; //清除power按键 axp_probe_key(); //获取电源状态 power_status = axp_get_power_vol_level(); debug("power status = %d\n", power_status); if(power_status == BATTERY_RATIO_TOO_LOW_WITHOUT_DCIN) { tick_printf("battery power is low without no dc or ac, should be set off\n"); sunxi_bmp_display("bat\\low_pwr.bmp"); __msdelay(3000); if(!efex_test) return -1; else return 0; } power_start = 0; //power_start的含义 //0: 不允许插火牛直接开机,必须通过判断:满足以下条件可以直接开机:长按power按键,前次是系统状态,如果电池电量过低,则不允许开机 //1: 任意状态下,允许插火牛直接开机,同时要求电池电量足够高 //2: 不允许插火牛直接开机,必须通过判断:满足以下条件可以直接开机:长按power按键,前次是系统状态,不要求电池电量 //3: 任意状态下,允许插火牛直接开机,不要求电池电量 script_parser_fetch(PMU_SCRIPT_NAME, "power_start", &power_start, 1); debug("power start cause = %d\n", power_start); if(power_start == 3) { return 0; } if(power_status == BATTERY_RATIO_TOO_LOW_WITH_DCIN_VOL_TOO_LOW)//低电量低电压,带外部电源状态 { if(!(power_start & 0x02)) //根据配置,低电状态下不允许开机, power_start==0 | power_start==1 { tick_printf("battery low power and vol with dc or ac, should charge longer\n"); sunxi_bmp_display("bat\\bempty.bmp"); __msdelay(3000); return -1; } //低电池低电量,此时配置为2,进入检测,按键则进入系统,插入火牛则待机 return 1; } if(power_status == BATTERY_RATIO_TOO_LOW_WITH_DCIN)//低电量高电压,带外部电源状态 { //如果配置为0,进入检测,按键则显示低电图标然后关机,插入火牛则待机 //如果配置为1,进入检测,按键则显示低电图标然后关机,插入火牛则待机 //如果配置为2,进入检测,按键则进入系统,插入火牛则待机 if(!(power_start & 0x02)) //根据配置,低电状态下不允许开机, power_start==0 | power_start==1 { tick_printf("battery low power with dc or ac\n"); return 2; } //低电池低电量,此时配置为2,进入检测,按键则进入系统,插入火牛则待机 return 1; } //电池电压电流都足够 if(power_start == 0x01) //如果第0bit的值为1,则进入系统 { return 0; } return 1; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : standby_mode: 0, 普通模式,需要检测电源状态 * * 1, 测试模式,强制进入standby模式,不论电源状态 * * return : * * note : probe power and other condition * * * ************************************************************************************************************ */ void board_status_probe(int standby_mode) { int ret; int start_condition = 0; int bat_exist; //清除power按键 axp_probe_key(); //启动条件判断,第一阶段,检测电源电压状态 if(!standby_mode) { ret = board_probe_power_level(); //负数:关机;0:进入系统;正数:检测 debug("stage1 resule %d\n", ret); if(ret < 0) { do_shutdown(NULL, 0, 1, NULL); } else if(!ret) { return ; } else if(ret == 2) //按键则显示低电图标然后关机,插入火牛则待机 { start_condition = 1; } //启动条件判断,第二阶段,检测开机原因 ret = board_probe_poweron_cause(); //负数,0:进入系统;正数:待机或者直接关机 debug("stage2 resule %d\n", ret); if(ret <= 0) { if(!start_condition) { return ; } else { tick_printf("battery low power with dc or ac, should charge longer\n"); sunxi_bmp_display("bat\\bempty.bmp"); __msdelay(3000); do_shutdown(NULL, 0, 1, NULL); } } else if(ret == AXP_VBUS_DCIN_NOT_EXIST) //当前一次为boot standby状态,但是启动时检查无外部电源,直接关机 { do_shutdown(NULL, 0, 1, NULL); } } #ifdef FORCE_BOOT_STANDBY bat_exist = 1; #else if(standby_mode) { bat_exist = 1; } else { bat_exist = board_probe_battery_exist(); if(bat_exist <= 0) { tick_printf("no battery exist\n"); return; } } #endif //启动条件判断,第三阶段,检测电池存在 //负数:关机;0:进入系统;正数:待机 ret = board_probe_bat_status(standby_mode); debug("stage3 resule %d\n", ret); if(ret < 0) { do_shutdown(NULL, 0, 1, NULL); } else if(!ret) { return ; } #ifndef CONFIG_NO_BOOT_STANDBY //启动条件判断,第四阶段,进入boot待机 //负数:关机,其它:进入系统 ret = board_standby_status(ret); debug("stage4 resule %d\n", ret); if(ret < 0) { do_shutdown(NULL, 0, 1, NULL); } #endif return ; }
int check_update_key(void) { int ret; int fel_key_max; int fel_key_mode = 0; gd->key_pressd_value = 0; if(uboot_spare_head.boot_data.work_mode != WORK_MODE_BOOT) { return 0; } sunxi_key_init(); ret = script_parser_fetch("fel_key", "fel_key_max", &fel_key_max, 1); if(ret) { printf("fel key old mode\n"); fel_key_mode = 1; } else { printf("fel key new mode\n"); } printf("run key detect\n"); sunxi_key_read(); __msdelay(10); if(!fel_key_mode) { int key_value; int fel_key_max, fel_key_min; key_value = sunxi_key_read(); //读取按键信息 if(key_value < 0) //没有按键按下 { printf("no key found\n"); return 0; } gd->key_pressd_value = key_value; ret = script_parser_fetch("fel_key", "fel_key_max", &fel_key_max, 1); if(ret) { printf("fel key max not found\n"); return 0; } ret = script_parser_fetch("fel_key", "fel_key_min", &fel_key_min, 1); if(ret) { printf("fel key min not found\n"); return 0; } if((key_value <= fel_key_max) && (key_value >= fel_key_min)) { printf("fel key detected\n"); return 1; } printf("fel key value %d is not in the range from %d to %d\n", key_value, fel_key_min, fel_key_max); return 0; } else { int count, time_tick; int value_old, value_new, value_cnt; int new_key, new_key_flag; time_tick = 0; count = 0; value_cnt = 0; new_key = 0; new_key_flag = 0; ret = sunxi_key_read(); //读取按键信息 if(ret < 0) //没有按键按下 { printf("no key found\n"); return 0; } else { value_old = ret; } gd->key_pressd_value = ret; while(1) { time_tick ++; ret = axp_probe_key(); //获取power按键信息 if(ret > 0) //检测到POWER按键按下 { count ++; } __msdelay(KEY_DELAY_EACH_TIME); ret = sunxi_key_read(); //读取按键信息 if(ret < 0) //没有按键按下 { printf("key not pressed anymore\n"); if(count == 1) { if(new_key >= 2) { printf("1\n"); printf("force to debug mode\n"); return -2; } } return 0; } else { value_new = ret; if(value_old == value_new) { value_cnt ++; if(new_key_flag == 1) { new_key ++; new_key_flag ++; } else if(!new_key_flag) { new_key_flag ++; } } else { new_key_flag = 0; value_old = value_new; } } if(count == 3) { printf("you can unclench the key to update now\n"); return -1; } if((!count) && (time_tick >= KEY_MAX_COUNT_GO_ON)) { printf("timeout, but no power key found\n"); return 0; } } } }