int power_source_init(void) { int pll1; int dcdc2_vol; if(script_parser_fetch("target", "dcdc2_vol", &dcdc2_vol, 1)) { dcdc2_vol = 1400; } if(axp_probe() > 0) { if(!axp_probe_power_supply_condition()) { if(!axp_set_supply_status(0, PMU_SUPPLY_DCDC2, dcdc2_vol, -1)) { tick_printf("PMU: dcdc2 %d\n", dcdc2_vol); pll1 = sunxi_clock_set_corepll(uboot_spare_head.boot_data.run_clock, dcdc2_vol); tick_printf("PMU: pll1 %d Mhz\n", pll1); } else { printf("axp_set_dcdc2 fail\n"); } } else { printf("axp_probe_power_supply_condition error\n"); } } else { printf("axp_probe error\n"); } axp_set_charge_vol_limit(); axp_set_all_limit(); axp_set_hardware_poweron_vol(); axp_set_power_supply_output(); return 0; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ static void __limited_fastboot(void) { char response[64]; memset(response, 0, 64); tick_printf("secure mode,fastboot limited used\n"); strcpy(response,"FAIL:secure mode,fastboot limited used"); __sunxi_fastboot_send_status(response, strlen(response)); return; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ static void probe_usb_overtime(void *p) { struct timer_list *timer_t; timer_t = (struct timer_list *)p; sunxi_usb_burn_from_boot_overtime = 1; tick_printf("timer occur\n"); del_timer(timer_t); return; }
static int init_func_pmubus(void) { tick_printf("pmbus: "); #if defined(CONFIG_SUNXI_I2C) i2c_init(CONFIG_SYS_I2C_SPEED,CONFIG_SYS_I2C_SLAVE); #elif defined(CONFIG_SUNXI_P2WI) p2wi_init(); #else sunxi_rsb_init(0); #endif puts("ready\n"); return (0); }
int board_display_framebuffer_change(void *buffer) { #if defined(CONFIG_VIDEO_SUNXI_V3) || defined(CONFIG_VIDEO_SUNXI_V2) return 0; #else uint arg[4]; __disp_fb_t disp_fb; __disp_layer_info_t *layer_para = (__disp_layer_info_t *)gd->layer_para; arg[0] = screen_id; arg[1] = gd->layer_hd; arg[2] = (uint)&disp_fb; arg[3] = 0; if(disp_ioctl(NULL, DISP_CMD_LAYER_GET_FB, (void*)arg)) { tick_printf("sunxi display error :get framebuffer failed\n"); return -1; } disp_fb.addr[0] = (uint)buffer; arg[0] = screen_id; arg[1] = gd->layer_hd; arg[2] = (uint)&disp_fb; arg[3] = 0; //debug("try to set framebuffer %x\n", (uint)buffer); if(disp_ioctl(NULL, DISP_CMD_LAYER_SET_FB, (void*)arg)) { tick_printf("sunxi display error :set framebuffer failed\n"); return -1; } layer_para->fb.addr[0] = (uint)buffer; return 0; #endif }
/* ************************************************************************************************************ * * function * * 函数名称: * * 参数列表: * * 返回值 : * * 说明 : * * ************************************************************************************************************ */ void power_limit_detect_enter(void) { unsigned char power_int_enable[8]; power_int_enable[0] = 0x4C; //dc in/out, usb in/out power_int_enable[1] = 0; power_int_enable[2] = 3; power_int_enable[4] = 0; power_int_enable[5] = 0; tick_printf("power limit detect enter\n"); axp_int_enable(power_int_enable); irq_install_handler(AW_IRQ_NMI, power_int_irq, 0); irq_enable(AW_IRQ_NMI); }
static int display_banner(void) { tick_printf("\n\n%s\n\n", version_string); debug("U-Boot code: %08lX -> %08lX BSS: -> %08lX\n", _TEXT_BASE, _bss_start_ofs + _TEXT_BASE, _bss_end_ofs + _TEXT_BASE); #ifdef CONFIG_MODEM_SUPPORT debug("Modem Support enabled\n"); #endif #ifdef CONFIG_USE_IRQ debug("IRQ Stack: %08lx\n", IRQ_STACK_START); debug("FIQ Stack: %08lx\n", FIQ_STACK_START); #endif return (0); }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ int board_display_layer_release(void) { __u32 arg[4]; if(gd->layer_hd == 0) { tick_printf("sunxi display error : display layer is NULL\n"); return -1; } arg[0] = 0; arg[1] = gd->layer_hd; return disp_ioctl(NULL, DISP_CMD_LAYER_RELEASE, (void*)arg); }
int board_display_layer_request(void) { __u32 arg[4]; arg[0] = 0; arg[1] = DISP_LAYER_WORK_MODE_NORMAL; gd->layer_hd = disp_ioctl(NULL, DISP_CMD_LAYER_REQUEST, (void*)arg); if(gd->layer_hd == 0) { tick_printf("sunxi display error : display request layer failed\n"); return -1; } return 0; }
/* ************************************************************************************************************ * * function * * 函数名称: * * 参数列表: * * 返回值 : * * 说明 : * * ************************************************************************************************************ */ static void power_int_irq(void *p_arg) { #ifdef DEBUG int i; #endif unsigned char power_int_status[8]; int dc_exist, bat_exist; axp_int_query(power_int_status); #ifdef DEBUG for(i=0;i<5;i++) { tick_printf("int status %d %x\n", i, power_int_status[i]); } #endif if(power_int_status[0] & 0x48) //外部电源插入 { axp_power_get_dcin_battery_exist(&dc_exist, &bat_exist); if(dc_exist) { tick_printf("power insert\n"); boot_standby_action &= ~0x10; boot_standby_action |= 0x04; } } if(power_int_status[0] & 0x8) //usb 插入中断,启动usb检测 { tick_printf("usb in\n"); boot_standby_action |= 8; usb_detect_enter(); } if(power_int_status[0] & 0x4) { tick_printf("usb out\n"); boot_standby_action &= ~0x04; boot_standby_action |= 0x10; usb_detect_exit(); } if(power_int_status[2] & 0x2) //短按键 { tick_printf("short key\n"); boot_standby_action |= 2; } if(power_int_status[2] & 0x1) //长按键 { tick_printf("long key\n"); boot_standby_action |= 1; } return; }
static int init_func_pmubus(void) { tick_printf("pmbus: "); #if defined(CONFIG_SUNXI_I2C) i2c_init(0, CONFIG_SYS_I2C_SPEED,CONFIG_SYS_I2C_SLAVE); //twi0 #if (defined(CONFIG_ARCH_HOMELET) && defined(CONFIG_ARCH_SUN9IW1P1)) i2c_init(1, CONFIG_SYS_I2C_SPEED,CONFIG_SYS_I2C_SLAVE); //twi1 for cvbs #endif #endif #if defined(CONFIG_SUNXI_P2WI) p2wi_init(); #endif #if defined(CONFIG_SUNXI_RSB) sunxi_rsb_init(0); #endif puts("ready\n"); return (0); }
/* ************************************************************************************************************ * * function * * 函数名称: * * 参数列表: * * 返回值 : * * 说明 : * * ************************************************************************************************************ */ int axp22_probe(void) { u8 pmu_type; if(axp_i2c_read(AXP22_ADDR, BOOT_POWER22_VERSION, &pmu_type)) { printf("axp read error\n"); return -1; } pmu_type &= 0x0f; if(pmu_type & 0x06) { /* pmu type AXP221 */ tick_printf("PMU: AXP221\n"); return 0; } return -1; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ int board_display_layer_release(void) { #if defined(CONFIG_VIDEO_SUNXI_V1) __u32 arg[4]; if(gd->layer_hd == 0) { tick_printf("sunxi display error : display layer is NULL\n"); return -1; } arg[0] = screen_id; arg[1] = gd->layer_hd; return disp_ioctl(NULL, DISP_CMD_LAYER_RELEASE, (void*)arg); #elif defined(CONFIG_VIDEO_SUNXI_V2) return 0; #else return 0; #endif }
int sunxi_board_shutdown(void) { printf("set next system normal\n"); axp_set_next_poweron_status(0x0); #ifdef CONFIG_SUNXI_DISPLAY board_display_set_exit_mode(0); drv_disp_exit(); #endif sunxi_flash_exit(1); sunxi_sprite_exit(1); disable_interrupts(); interrupt_exit(); tick_printf("power off\n"); axp_set_hardware_poweroff_vol(); axp_set_power_off(); return 0; }
/* ************************************************************************************************************ * * function * * 函数名称: * * 参数列表: * * 返回值 : * * 说明 : * * ************************************************************************************************************ */ int axp809_probe(void) { u8 pmu_type; axp_i2c_config(SUNXI_AXP_809, AXP809_ADDR); if(axp_i2c_read(AXP809_ADDR, BOOT_POWER809_VERSION, &pmu_type)) { printf("axp read error\n"); return -1; } pmu_type &= 0xCF; if(pmu_type == 0x42) { /* pmu type AXP809 */ tick_printf("PMU: AXP809\n"); return 0; } return -1; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ int sunxi_board_shutdown(void) { #if defined(CONFIG_SUNXI_RTC) printf("rtc disable\n"); rtc_disable(); #endif printf("set next system normal\n"); axp_set_next_poweron_status(0x0); board_display_set_exit_mode(0); drv_disp_exit(); sunxi_flash_exit(1); //强制关闭FLASH sunxi_sprite_exit(1); disable_interrupts(); interrupt_exit(); tick_printf("power off\n"); axp_set_hardware_poweroff_vol(); axp_set_power_off(); return 0; }
/* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ static int sunxi_fastboot_state_loop(void *buffer) { int ret; sunxi_ubuf_t *sunxi_ubuf = (sunxi_ubuf_t *)buffer; char response[68]; switch(sunxi_usb_fastboot_status) { case SUNXI_USB_FASTBOOT_IDLE: if(sunxi_ubuf->rx_ready_for_data == 1) { sunxi_usb_fastboot_status = SUNXI_USB_FASTBOOT_SETUP; } break; case SUNXI_USB_FASTBOOT_SETUP: tick_printf("SUNXI_USB_FASTBOOT_SETUP\n"); tick_printf("fastboot command = %s\n", sunxi_ubuf->rx_req_buffer); sunxi_usb_fastboot_status = SUNXI_USB_FASTBOOT_IDLE; sunxi_ubuf->rx_ready_for_data = 0; if(memcmp(sunxi_ubuf->rx_req_buffer, "reboot-bootloader", strlen("reboot-bootloader")) == 0) { tick_printf("reboot-bootloader\n"); __fastboot_reboot(PMU_PRE_FASTBOOT_MODE); } else if(memcmp(sunxi_ubuf->rx_req_buffer, "reboot", 6) == 0) { tick_printf("reboot\n"); __fastboot_reboot(0); } else if(memcmp(sunxi_ubuf->rx_req_buffer, "erase:", 6) == 0) { tick_printf("erase\n"); __erase_part((char *)(sunxi_ubuf->rx_req_buffer + 6)); } else if(memcmp(sunxi_ubuf->rx_req_buffer, "flash:", 6) == 0) { tick_printf("flash\n"); __flash_to_part((char *)(sunxi_ubuf->rx_req_buffer + 6)); } else if(memcmp(sunxi_ubuf->rx_req_buffer, "download:", 9) == 0) { tick_printf("download\n"); ret = __try_to_download((char *)(sunxi_ubuf->rx_req_buffer + 9), response); if(ret >= 0) { fastboot_data_flag = 1; sunxi_ubuf->rx_req_buffer = (uchar *)trans_data.base_recv_buffer; sunxi_usb_fastboot_status = SUNXI_USB_FASTBOOT_RECEIVE_DATA; } __sunxi_fastboot_send_status(response, strlen(response)); } else if(memcmp(sunxi_ubuf->rx_req_buffer, "boot", 4) == 0) { tick_printf("boot\n"); __boot(); } else if(memcmp(sunxi_ubuf->rx_req_buffer, "getvar:", 7) == 0) { tick_printf("getvar\n"); __get_var((char *)(sunxi_ubuf->rx_req_buffer + 7)); } else if(memcmp(sunxi_ubuf->rx_req_buffer, "oem", 3) == 0) { tick_printf("oem operations\n"); __oem_operation((char *)(sunxi_ubuf->rx_req_buffer + 4)); } else if(memcmp(sunxi_ubuf->rx_req_buffer, "continue", 8) == 0) { tick_printf("continue\n"); __continue(); } else { tick_printf("not supported fastboot cmd\n"); __unsupported_cmd(); } break; case SUNXI_USB_FASTBOOT_SEND_DATA: tick_printf("SUNXI_USB_FASTBOOT_SEND_DATA\n"); break; case SUNXI_USB_FASTBOOT_RECEIVE_DATA: //tick_printf("SUNXI_USB_FASTBOOT_RECEIVE_DATA\n"); if((fastboot_data_flag == 1) && ((char *)sunxi_ubuf->rx_req_buffer == all_download_bytes + trans_data.base_recv_buffer)) //传输完毕 { tick_printf("fastboot transfer finish\n"); fastboot_data_flag = 0; sunxi_usb_fastboot_status = SUNXI_USB_FASTBOOT_IDLE; sunxi_ubuf->rx_req_buffer = sunxi_ubuf->rx_base_buffer; sprintf(response,"OKAY"); __sunxi_fastboot_send_status(response, strlen(response)); } break; default: break; } return 0; }
int power_source_init(void) { int pll_cpux; int cpu_vol; int dcdc_vol; int axp_exist = 0; //PMU_SUPPLY_DCDC2 is for cpua if(script_parser_fetch("power_sply", "dcdc2_vol", &dcdc_vol, 1)) { cpu_vol = 900; } else { cpu_vol = dcdc_vol%10000; } axp_exist = axp_probe(); if(axp_exist) { axp_probe_factory_mode(); if(!axp_probe_power_supply_condition()) { //PMU_SUPPLY_DCDC2 is for cpua if(!axp_set_supply_status(0, PMU_SUPPLY_DCDC2, cpu_vol, -1)) { tick_printf("PMU: dcdc2 %d\n", cpu_vol); sunxi_clock_set_corepll(uboot_spare_head.boot_data.run_clock); } else { printf("axp_set_dcdc2 fail\n"); } } else { printf("axp_probe_power_supply_condition error\n"); } } else { printf("axp_probe error\n"); } pll_cpux = sunxi_clock_get_corepll(); tick_printf("PMU: cpux %d Mhz,AXI=%d Mhz\n", pll_cpux,sunxi_clock_get_axi()); printf("PLL6=%d Mhz,AHB=%d Mhz, APB1=%d Mhz \n", sunxi_clock_get_pll6(), sunxi_clock_get_ahb(), sunxi_clock_get_apb()); if(axp_exist) { axp_set_charge_vol_limit(); axp_set_all_limit(); axp_set_hardware_poweron_vol(); axp_set_power_supply_output(); power_config_gpio_bias(); power_limit_init(); } return 0; }
int display_inner(void) { tick_printf("version: %s\n", uboot_spare_head.boot_head.version); return 0; }
int board_display_device_open(void) { #if (defined CONFIG_ARCH_SUN8IW5P1) int ret = 0; __u32 output_type = 0; unsigned long arg[4] = {0}; output_type = DISP_OUTPUT_TYPE_LCD; if(output_type == DISP_OUTPUT_TYPE_LCD) { debug("lcd open\n"); arg[0] = screen_id; arg[1] = 0; arg[2] = 0; ret = disp_ioctl(NULL, DISP_CMD_LCD_ENABLE, (void*)arg); debug("lcd open,ret=%d\n",ret); } else if(output_type == DISP_OUTPUT_TYPE_HDMI) { } #else int value = 1; int ret = 0; __u32 output_type = 0; __u32 output_mode = 0; __u32 auto_hpd = 0; __u32 err_count = 0; unsigned long arg[4] = {0}; int i; debug("De_OpenDevice\n"); //channel if(script_parser_fetch("boot_disp", "output_disp", &value, 1) < 0) { tick_printf("fetch script data boot_disp.output_disp fail\n"); err_count ++; value = 0; } else { tick_printf("boot_disp.output_disp=%d\n", value); screen_id = value; } //screen0_output_type if(script_parser_fetch("boot_disp", "output_type", &value, 1) < 0) { tick_printf("fetch script data boot_disp.output_type fail\n"); err_count ++; value = 0; } else { tick_printf("boot_disp.output_type=%d\n", value); } if(value == 0) { output_type = DISP_OUTPUT_TYPE_NONE; } else if(value == 1) { output_type = DISP_OUTPUT_TYPE_LCD; } else if(value == 2) { output_type = DISP_OUTPUT_TYPE_TV; } else if(value == 3) { output_type = DISP_OUTPUT_TYPE_HDMI; } else if(value == 4) { output_type = DISP_OUTPUT_TYPE_VGA; } else { tick_printf("invalid screen0_output_type %d\n", value); return -1; } //screen0_output_mode if(script_parser_fetch("boot_disp", "output_mode", &value, 1) < 0) { tick_printf("fetch script data boot_disp.output_mode fail\n"); err_count ++; value = 0; } else { tick_printf("boot_disp.output_mode=%d\n", value); } if(output_type == DISP_OUTPUT_TYPE_TV || output_type == DISP_OUTPUT_TYPE_HDMI) { output_mode = value; } else if(output_type == DISP_OUTPUT_TYPE_VGA) { output_mode = value; } //auto hot plug detect if(script_parser_fetch("boot_disp", "auto_hpd", &value, 1) < 0) { tick_printf("fetch script data boot_disp.auto_hpd fail\n"); err_count ++; value = 0; }else { auto_hpd = value; tick_printf("boot_disp.auto_hpd=%d\n", value); } if(err_count == 4)//no boot_disp config { if(script_parser_fetch("lcd0_para", "lcd_used", &value, 1) < 0) { tick_printf("fetch script data lcd0_para.lcd_used fail\n"); value = 0; }else { tick_printf("lcd0_para.lcd_used=%d\n", value); } if(value == 1) //lcd available { output_type = DISP_OUTPUT_TYPE_LCD; } else { arg[0] = screen_id; arg[1] = 0; arg[2] = 0; ret = 0; for(i=0; (i<3)&&(ret==0); i++) { #if defined(CONFIG_VIDEO_SUNXI_V1) || defined(CONFIG_VIDEO_SUNXI_V2) ret = disp_ioctl(NULL, DISP_CMD_HDMI_GET_HPD_STATUS, (void*)arg); #endif } if(ret == 1) { output_type = DISP_OUTPUT_TYPE_HDMI; //output_mode = (output_mode == -1)? DISP_TV_MOD_720P_50HZ:output_mode; output_mode = DISP_TV_MOD_720P_50HZ; } } } else//has boot_disp config { if(output_type == DISP_OUTPUT_TYPE_LCD) { } else if(auto_hpd == 1) { arg[0] = screen_id; arg[1] = 0; for(i=0; (i<3)&&(ret==0); i++) { #if defined(CONFIG_VIDEO_SUNXI_V1) || defined(CONFIG_VIDEO_SUNXI_V2) ret=disp_ioctl(NULL, DISP_CMD_HDMI_GET_HPD_STATUS, (void*)arg); debug("hdmi pending%d\n",i); // disp_delay_ms(200); #endif } if (ret == 1) { output_type = DISP_OUTPUT_TYPE_HDMI; output_mode = (output_mode == -1)? DISP_TV_MOD_720P_50HZ:output_mode; //output_mode = DISP_TV_MOD_1080P_60HZ; debug("------DISP_OUTPUT_TYPE_HDMI-----\n"); } else { #if defined(CONFIG_VIDEO_SUNXI_V1) ret = 0; arg[0] = screen_id; arg[1] = 0; for(i=0; (i<6)&&(ret==0); i++) { debug("%d\n",i); ret = disp_ioctl(NULL, DISP_CMD_TV_GET_INTERFACE, (void*)arg); disp_delay_ms(200); } debug("tv detect, ret = %d\n", ret); if((ret & DISP_TV_CVBS) == DISP_TV_CVBS) { output_type = DISP_OUTPUT_TYPE_TV; output_mode = DISP_TV_MOD_PAL; debug("------DISP_TV_CVBS-----\n"); }else if((ret & DISP_TV_YPBPR) == DISP_TV_YPBPR) { output_type = DISP_OUTPUT_TYPE_VGA; output_mode = DISP_VGA_H1024_V768; debug("------DISP_TV_YPBPR-----\n"); }else { output_type = DISP_OUTPUT_TYPE_NONE; debug("------DISP_OUTPUT_TYPE_NONE-----\n"); } #endif } } } #if !defined(CONFIG_VIDEO_SUNXI_V3) if(output_type == DISP_OUTPUT_TYPE_LCD) { printf("lcd open\n"); arg[0] = screen_id; arg[1] = 0; arg[2] = 0; #if !(defined CONFIG_ARCH_SUN9IW1P1) && !(defined CONFIG_ARCH_SUN8IW8P1)&& !(defined CONFIG_ARCH_SUN8IW7P1) ret = disp_ioctl(NULL, DISP_CMD_LCD_ON, (void*)arg); #else ret = disp_ioctl(NULL, DISP_CMD_LCD_ENABLE, (void*)arg); #endif debug("lcd open,ret=%d\n",ret); } else if(output_type == DISP_OUTPUT_TYPE_HDMI) { printf("hdmi open\n"); arg[0] = screen_id; arg[1] = output_mode; arg[2] = 0; #if !(defined CONFIG_ARCH_SUN9IW1P1) && !(defined CONFIG_ARCH_SUN8IW8P1)&& !(defined CONFIG_ARCH_SUN8IW7P1) disp_ioctl(NULL, DISP_CMD_HDMI_SET_MODE, (void *)arg); ret = disp_ioctl(NULL, DISP_CMD_HDMI_ON, (void *)arg); #else disp_ioctl(NULL, DISP_CMD_HDMI_SET_MODE, (void *)arg); ret = disp_ioctl(NULL, DISP_CMD_HDMI_ENABLE, (void *)arg); #endif } #if defined(CONFIG_VIDEO_SUNXI_V1) else if(output_type == DISP_OUTPUT_TYPE_TV) { printf("tv open\n"); //udelay(1000*1000*10); arg[0] = screen_id; arg[1] = output_mode; arg[2] = 0; disp_ioctl(NULL, DISP_CMD_TV_SET_MODE, (void *)arg); ret = disp_ioctl(NULL, DISP_CMD_TV_ON, (void *)arg); } else if(output_type == DISP_OUTPUT_TYPE_VGA) { printf("vga open\n"); //udelay(1000*200); arg[0] = screen_id; arg[1] = output_mode; arg[2] = 0; disp_ioctl(NULL, DISP_CMD_VGA_SET_MODE, (void *)arg); ret = disp_ioctl(NULL, DISP_CMD_VGA_ON, (void *)arg); } #endif // !(defined CONFIG_ARCH_SUN9IW1P1) #else /* CONFIG_VIDEO_SUNXI_V3 */ arg[0] = screen_id; arg[1] = output_type; arg[2] = output_mode; disp_ioctl(NULL, DISP_DEVICE_SWITCH, (void *)arg); #endif // !CONFIG_VIDEO_SUNXI_V3 #endif // CONFIG_ARCH_SUN8IW5P1 return ret; }
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 : * * return : * * note : * * ************************************************************************************************************ */ int board_display_framebuffer_set(int width, int height, int bitcount, void *buffer) { #if defined(CONFIG_VIDEO_SUNXI_V3) disp_layer_config *layer_para; uint screen_width, screen_height; uint arg[4]; if(!gd->layer_para) { layer_para = (disp_layer_config *)malloc(sizeof(disp_layer_config)); if(!layer_para) { tick_printf("sunxi display error: unable to malloc memory for layer\n"); return -1; } } else { layer_para = (disp_layer_config *)gd->layer_para; } arg[0] = screen_id; screen_width = disp_ioctl(NULL, DISP_GET_SCN_WIDTH, (void*)arg); screen_height = disp_ioctl(NULL, DISP_GET_SCN_HEIGHT, (void*)arg); tick_printf("screen_id =%d, screen_width =%d, screen_height =%d\n", screen_id, screen_width, screen_height); memset((void *)layer_para, 0, sizeof(disp_layer_config)); layer_para->info.fb.addr[0] = (uint)buffer; tick_printf("frame buffer address %x\n", (uint)buffer); layer_para->channel = 1; layer_para->layer_id = 0; layer_para->info.fb.format = (bitcount == 24)? DISP_FORMAT_RGB_888:DISP_FORMAT_ARGB_8888; layer_para->info.fb.size[0].width = width; layer_para->info.fb.size[0].height = height; layer_para->info.fb.crop.x = 0; layer_para->info.fb.crop.y = 0; layer_para->info.fb.crop.width = ((unsigned long long)width) << 32; layer_para->info.fb.crop.height = ((unsigned long long)height) << 32; layer_para->info.fb.flags = DISP_BF_NORMAL; layer_para->info.fb.scan = DISP_SCAN_PROGRESSIVE; debug("bitcount = %d\n", bitcount); layer_para->info.mode = LAYER_MODE_BUFFER; layer_para->info.alpha_mode = 1; layer_para->info.alpha_value = 0xff; layer_para->info.screen_win.x = (screen_width - width) / 2; layer_para->info.screen_win.y = (screen_height - height) / 2; layer_para->info.screen_win.width = width; layer_para->info.screen_win.height = height; layer_para->info.b_trd_out = 0; layer_para->info.out_trd_mode = 0; #elif defined(CONFIG_VIDEO_SUNXI_V2) disp_layer_info *layer_para; uint screen_width, screen_height; uint arg[4]; if(!gd->layer_para) { layer_para = (disp_layer_info *)malloc(sizeof(disp_layer_info)); if(!layer_para) { tick_printf("sunxi display error: unable to malloc memory for layer\n"); return -1; } } else { layer_para = (disp_layer_info *)gd->layer_para; } arg[0] = screen_id; screen_width = disp_ioctl(NULL, DISP_CMD_GET_SCN_WIDTH, (void*)arg); screen_height = disp_ioctl(NULL, DISP_CMD_GET_SCN_HEIGHT, (void*)arg); printf("screen_id =%d, screen_width =%d, screen_height =%d\n", screen_id, screen_width, screen_height); memset((void *)layer_para, 0, sizeof(disp_layer_info)); layer_para->fb.addr[0] = (uint)buffer; debug("frame buffer address %x\n", (uint)buffer); layer_para->fb.format = (bitcount == 24)? DISP_FORMAT_RGB_888:DISP_FORMAT_ARGB_8888; layer_para->fb.size.width = width; layer_para->fb.size.height = height; debug("bitcount = %d\n", bitcount); layer_para->fb.b_trd_src = 0; layer_para->fb.trd_mode = 0; layer_para->ck_enable = 0; layer_para->mode = DISP_LAYER_WORK_MODE_NORMAL; layer_para->alpha_mode = 1; layer_para->alpha_value = 0xff; layer_para->pipe = 0; layer_para->screen_win.x = (screen_width - width) / 2; layer_para->screen_win.y = (screen_height - height) / 2; layer_para->screen_win.width = width; layer_para->screen_win.height = height; layer_para->b_trd_out = 0; layer_para->out_trd_mode = 0; #else __disp_layer_info_t *layer_para; uint screen_width, screen_height; uint arg[4]; if(!gd->layer_para) { layer_para = (__disp_layer_info_t *)malloc(sizeof(__disp_layer_info_t)); if(!layer_para) { tick_printf("sunxi display error: unable to malloc memory for layer\n"); return -1; } } else { layer_para = (__disp_layer_info_t *)gd->layer_para; } arg[0] = screen_id; screen_width = disp_ioctl(NULL, DISP_CMD_SCN_GET_WIDTH, (void*)arg); screen_height = disp_ioctl(NULL, DISP_CMD_SCN_GET_HEIGHT, (void*)arg); debug("screen_width =%d, screen_height =%d\n", screen_width, screen_height); memset((void *)layer_para, 0, sizeof(__disp_layer_info_t)); layer_para->fb.addr[0] = (uint)buffer; debug("frame buffer address %x\n", (uint)buffer); layer_para->fb.size.width = width; layer_para->fb.size.height = height; layer_para->fb.mode = DISP_MOD_INTERLEAVED; layer_para->fb.format = (bitcount == 24)? DISP_FORMAT_RGB888:DISP_FORMAT_ARGB8888; debug("bitcount = %d\n", bitcount); layer_para->fb.br_swap = 0; layer_para->fb.seq = DISP_SEQ_ARGB; layer_para->fb.b_trd_src = 0; layer_para->fb.trd_mode = 0; layer_para->ck_enable = 0; layer_para->mode = DISP_LAYER_WORK_MODE_NORMAL; layer_para->alpha_en = 1; layer_para->alpha_val = 0xff; layer_para->pipe = 0; layer_para->src_win.x = 0; layer_para->src_win.y = 0; layer_para->src_win.width = width; layer_para->src_win.height = height; layer_para->scn_win.x = (screen_width - width) / 2; layer_para->scn_win.y = (screen_height - height) / 2; layer_para->scn_win.width = width; layer_para->scn_win.height = height; layer_para->b_trd_out = 0; layer_para->out_trd_mode = 0; #endif gd->layer_para = (uint)layer_para; return 0; }
int sunxi_pwm_config(int pwm, int duty_ns, int period_ns) { #if ((defined CONFIG_ARCH_SUN8IW1P1) || (defined CONFIG_ARCH_SUN9IW1P1)) uint pre_scal[7] = {1, 2, 4, 8, 16, 32, 64}; uint freq; uint pre_scal_id = 0; uint entire_cycles = 256; uint active_cycles = 192; uint entire_cycles_max = 65536; uint temp; uint calc; if(period_ns < 10667) freq = 93747; else if(period_ns > 174762666) { freq = 6; calc = period_ns / duty_ns; duty_ns = 174762666 / calc; period_ns = 174762666; } else freq = 1000000000 / period_ns; entire_cycles = 24000000 / freq /pre_scal[pre_scal_id]; while(entire_cycles > entire_cycles_max) { pre_scal_id++; if(pre_scal_id > 6) break; entire_cycles = 24000000 / freq / pre_scal[pre_scal_id]; } if(period_ns < 5*100*1000) active_cycles = (duty_ns * entire_cycles + (period_ns/2)) /period_ns; else if(period_ns >= 5*100*1000 && period_ns < 6553500) active_cycles = ((duty_ns / 100) * entire_cycles + (period_ns /2 / 100)) / (period_ns/100); else active_cycles = ((duty_ns / 10000) * entire_cycles + (period_ns /2 / 10000)) / (period_ns/10000); temp = sunxi_pwm_read_reg(pwm * 0x10); temp = (temp & 0xfffffff0) | pre_scal_id; sunxi_pwm_write_reg(pwm * 0x10, temp); sunxi_pwm_write_reg(pwm * 0x10 + 0x04, ((entire_cycles - 1)<< 16) | active_cycles); pwm_debug("PWM _TEST: duty_ns=%d, period_ns=%d, freq=%d, per_scal=%d, period_reg=0x%x\n", duty_ns, period_ns, freq, pre_scal_id, temp); #elif ((defined CONFIG_ARCH_SUN8IW3P1) || (defined CONFIG_ARCH_SUN7IW1P1)) tick_printf("+++++++++++++++++++test10+++++++++++++++++++++\n"); uint pre_scal[11][2] = {{15, 1}, {0, 120}, {1, 180}, {2, 240}, {3, 360}, {4, 480}, {8, 12000}, {9, 24000}, {10, 36000}, {11, 48000}, {12, 72000}}; uint freq; uint pre_scal_id = 0; uint entire_cycles = 256; uint active_cycles = 192; uint entire_cycles_max = 65536; uint temp; if(period_ns < 10667) freq = 93747; else if(period_ns > 1000000000) freq = 1; else freq = 1000000000 / period_ns; entire_cycles = 24000000 / freq / pre_scal[pre_scal_id][1]; while(entire_cycles > entire_cycles_max) { pre_scal_id++; if(pre_scal_id > 10) break; entire_cycles = 24000000 / freq / pre_scal[pre_scal_id][1]; } if(period_ns < 5*100*1000) active_cycles = (duty_ns * entire_cycles + (period_ns/2)) /period_ns; else if(period_ns >= 5*100*1000 && period_ns < 6553500) active_cycles = ((duty_ns / 100) * entire_cycles + (period_ns /2 / 100)) / (period_ns/100); else active_cycles = ((duty_ns / 10000) * entire_cycles + (period_ns /2 / 10000)) / (period_ns/10000); temp = sunxi_pwm_read_reg(0); if(pwm == 0) temp = (temp & 0xfffffff0) |pre_scal[pre_scal_id][0]; else temp = (temp & 0xfff87fff) |pre_scal[pre_scal_id][0]; sunxi_pwm_write_reg(0, temp); sunxi_pwm_write_reg((pwm + 1) * 0x04, ((entire_cycles - 1)<< 16) | active_cycles); pwm_debug("PWM _TEST: duty_ns=%d, period_ns=%d, freq=%d, per_scal=%d, period_reg=0x%x\n", duty_ns, period_ns, freq, pre_scal_id, temp); #endif return 0; }
/* ************************************************************************************************************ * * function * * 函数名称: * * 参数列表: * * 返回值 : * * 说明 : * * ************************************************************************************************************ */ int axp_probe(void) { int ret = 0; int pmu_main_id = (int)-1; int pmu_slave_id = (int)-1; memset(sunxi_axp_dev, 0, SUNXI_AXP_DEV_MAX * 4); if(axp_fetch_pmu_id(&pmu_main_id, &pmu_slave_id) != (-1)) //must has one pmu { gd->power_main_id = pmu_main_id; gd->power_slave_id = pmu_slave_id; if(axp_probe_type(pmu_main_id, pmu_slave_id) > 0) { ret++; } } else { #if defined(CONFIG_SUNXI_AXP22) if(axp22_probe()) { printf("probe axp22x failed\n"); } else { /* pmu type AXP22X */ tick_printf("PMU: AXP22x found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_22X] = &sunxi_axp_22; #if (CONFIG_SUNXI_AXP_MAIN == PMU_TYPE_22X) sunxi_axp_dev[0] = &sunxi_axp_22; #endif #endif #if defined(CONFIG_SUNXI_AXP20) if(axp20_probe()) { printf("probe axp20x failed\n"); } else { /* pmu type AXP22X */ tick_printf("PMU: AXP20x found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_20X] = &sunxi_axp_20; #if (CONFIG_SUNXI_AXP_MAIN == PMU_TYPE_20X) sunxi_axp_dev[0] = &sunxi_axp_20; #endif #endif #if defined(CONFIG_SUNXI_AXP15) if(axp15_probe()) { printf("probe axp15 failed\n"); } else { /* pmu type AXP15X */ tick_printf("PMU: AXP15x found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_15X] = &sunxi_axp_15; #if (CONFIG_SUNXI_AXP_MAIN == PMU_TYPE_15X) sunxi_axp_dev[0] = &sunxi_axp_15; #endif #endif #if defined(CONFIG_SUNXI_AXP809) if(axp809_probe()) { printf("probe axp809 failed\n"); } else { /* pmu type AXP809 */ tick_printf("PMU: AXP809 found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_809] = &sunxi_axp_809; #if (CONFIG_SUNXI_AXP_MAIN == PMU_TYPE_809) sunxi_axp_dev[0] = &sunxi_axp_809; #endif #endif #if defined(CONFIG_SUNXI_AXP806) if(axp806_probe()) { printf("probe axp806 failed\n"); } else { /* pmu type AXP806 */ tick_printf("PMU: AXP806 found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_806] = &sunxi_axp_806; #if (CONFIG_SUNXI_AXP_MAIN == PMU_TYPE_806) sunxi_axp_dev[0] = &sunxi_axp_806; #endif #endif #if defined(CONFIG_SUNXI_AXP81X) if(axp81_probe()) { printf("probe axp81X failed\n"); } else { /* pmu type AXP81X */ tick_printf("PMU: AXP81X found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_81X] = &sunxi_axp_81; #if (CONFIG_SUNXI_AXP_MAIN == PMU_TYPE_81X) sunxi_axp_dev[0] = &sunxi_axp_81; #endif #endif } if(!ret) { sunxi_axp_dev[0] = &sunxi_axp_null; } return ret; }
int sunxi_flash_handle_init(void) { int workmode; int storage_type; int card_no; // long long flash_size; // uboot_spare_head.boot_data.storage_type = 0; // if(uboot_spare_head.boot_data.storage_type) // uboot_spare_head.boot_data.work_mode = WORK_MODE_CARD_PRODUCT;//WORK_MODE_CARD_PRODUCT; workmode = uboot_spare_head.boot_data.work_mode; #if 1 printf("workmode = %d\n", workmode); debug("storage type = %d\n", uboot_spare_head.boot_data.storage_type); #endif if(workmode == WORK_MODE_BOOT || workmode == WORK_MODE_SPRITE_RECOVERY) { int nand_used, sdc0_used, sdc2_used, sdc_detmode=3; storage_type = uboot_spare_head.boot_data.storage_type; debug("storage type = %d\n", storage_type); if((storage_type == 1) || (storage_type == 2)) { if(2 == storage_type) { nand_used = 0; sdc2_used = 1; script_parser_patch("nand0_para", "nand0_used", &nand_used, 1); script_parser_patch("nand1_para", "nand1_used", &nand_used, 1); script_parser_patch("mmc2_para", "sdc_used", &sdc2_used, 1); script_parser_patch("mmc2_para", "sdc_detmode", &sdc_detmode, 1); } else { //nand_used = 0; sdc0_used = 1; //sdc2_used = 0; //script_parser_patch("nand0_para", "nand0_used", &nand_used, 1); //script_parser_patch("nand1_para", "nand1_used", &nand_used, 1); script_parser_patch("mmc0_para", "sdc_used", &sdc0_used, 1); script_parser_patch("mmc0_para", "sdc_detmode", &sdc_detmode, 1); //script_parser_patch("mmc2_para", "sdc_used", &sdc2_used, 1); } card_no = (storage_type == 1)?0:2; printf("MMC: %d\n", card_no); board_mmc_set_num(card_no); debug("set card number\n"); board_mmc_pre_init(card_no); debug("begin to find mmc\n"); mmc_boot = find_mmc_device(card_no); if(!mmc_boot){ printf("fail to find one useful mmc card\n"); return -1; } debug("try to init mmc\n"); if (mmc_init(mmc_boot)) { puts("MMC init failed\n"); return -1; } debug("mmc %d init ok\n", card_no); sunxi_flash_read_pt = sunxi_flash_mmc_read; sunxi_flash_write_pt = sunxi_flash_mmc_write; sunxi_flash_size_pt = sunxi_flash_mmc_size; sunxi_flash_exit_pt = sunxi_flash_mmc_exit; sunxi_flash_phyread_pt = sunxi_flash_mmc_phyread; sunxi_flash_phywrite_pt = sunxi_flash_mmc_phywrite; sunxi_sprite_phyread_pt = sunxi_flash_mmc_phyread; sunxi_sprite_phywrite_pt = sunxi_flash_mmc_phywrite; } else { nand_used = 1; sdc2_used = 0; script_parser_patch("nand0_para", "nand0_used", &nand_used, 1); script_parser_patch("nand1_para", "nand1_used", &nand_used, 1); script_parser_patch("mmc2_para", "sdc_used", &sdc2_used, 1); tick_printf("NAND: "); if (workmode == WORK_MODE_BOOT) { if(nand_uboot_init(1)) { tick_printf("nand init fail\n"); return -1; } } else if (workmode == WORK_MODE_SPRITE_RECOVERY) { if(nand_uboot_init(2)) { tick_printf("nand init fail\n"); return -1; } } //flash_size = nand_uboot_get_flash_size(); //flash_size <<= 9; //print_size(flash_size, "\n"); sunxi_flash_read_pt = sunxi_flash_nand_read; sunxi_flash_write_pt = sunxi_flash_nand_write; sunxi_flash_size_pt = sunxi_flash_nand_size; sunxi_flash_exit_pt = sunxi_flash_nand_exit; sunxi_flash_flush_pt = sunxi_flash_nand_flush; } sunxi_sprite_read_pt = sunxi_flash_read_pt; sunxi_sprite_write_pt = sunxi_flash_write_pt; sunxi_flash_init_uboot(0); script_parser_patch("target", "storage_type", &storage_type, 1); tick_printf("sunxi flash init ok\n"); #if defined(CONFIG_ARCH_SUN8IW1P1) if((storage_type == 0) || (storage_type == 2)) //如果是A31非卡0启动,则需要跳转检测卡0 { sunxi_card_probe_mmc0_boot(); } #endif if((storage_type == 0) ||(storage_type == 2)) { int sprite_next_work = 0; script_parser_fetch("card_boot","next_work",&sprite_next_work,1); if(sprite_next_work == SUNXI_UPDATA_NEXT_ACTION_SPRITE_TEST) sunxi_card_fill_boot0_magic(); } } else if((workmode & WORK_MODE_PRODUCT) || (workmode == 0x30)) /* 量产模式 */ { if(!nand_uboot_probe()) { printf("nand found\n"); sunxi_sprite_init_pt = sunxi_flash_nand_init; sunxi_sprite_exit_pt = sunxi_flash_nand_exit; sunxi_sprite_read_pt = sunxi_flash_nand_read; sunxi_sprite_write_pt = sunxi_flash_nand_write; sunxi_sprite_erase_pt = sunxi_flash_nand_erase; sunxi_sprite_size_pt = sunxi_flash_nand_size; sunxi_sprite_flush_pt = sunxi_flash_nand_flush; sunxi_sprite_force_erase_pt = sunxi_flash_nand_force_erase; debug("sunxi sprite has installed nand function\n"); uboot_spare_head.boot_data.storage_type = 0; if(workmode == 0x30) { if(sunxi_sprite_init(1)) { tick_printf("nand init fail\n"); return -1; } } } #ifdef CONFIG_SUNXI_SPINOR else if(!try_spi_nor(0)) //burn nor { printf("try nor successed \n"); sunxi_sprite_init_pt = sunxi_flash_spinor_init; sunxi_sprite_exit_pt = sunxi_flash_spinor_exit; sunxi_sprite_read_pt = sunxi_flash_spinor_read; sunxi_sprite_write_pt = sunxi_sprite_spinor_write; sunxi_sprite_erase_pt = sunxi_flash_spinor_erase; sunxi_sprite_size_pt = sunxi_flash_spinor_size; sunxi_sprite_flush_pt = sunxi_flash_spinor_flush; sunxi_sprite_datafinish_pt = sunxi_flash_spinor_datafinish; printf("sunxi sprite has installed spi function\n"); uboot_spare_head.boot_data.storage_type = 3; } #endif else /* burn sdcard 2 */ { printf("try nand fail\n"); board_mmc_pre_init(2); mmc_sprite = find_mmc_device(2); if(!mmc_sprite){ printf("fail to find one useful mmc card\n"); return -1; } if (mmc_init(mmc_sprite)) { puts("MMC init failed\n"); return -1; } sunxi_sprite_init_pt = sunxi_sprite_mmc_init; sunxi_sprite_exit_pt = sunxi_sprite_mmc_exit; sunxi_sprite_read_pt = sunxi_sprite_mmc_read; sunxi_sprite_write_pt = sunxi_sprite_mmc_write; sunxi_sprite_erase_pt = sunxi_sprite_mmc_erase; sunxi_sprite_size_pt = sunxi_sprite_mmc_size; sunxi_sprite_phyread_pt = sunxi_sprite_mmc_phyread; sunxi_sprite_phywrite_pt = sunxi_sprite_mmc_phywrite; sunxi_sprite_force_erase_pt = sunxi_sprite_mmc_force_erase; debug("sunxi sprite has installed sdcard2 function\n"); uboot_spare_head.boot_data.storage_type = 2; } if((workmode == WORK_MODE_CARD_PRODUCT) || (workmode == 0x30)) //sdcard burn mode { board_mmc_pre_init(0); mmc_boot = find_mmc_device(0); if(!mmc_boot) { printf("fail to find one useful mmc card\n"); return -1; } if (mmc_init(mmc_boot)) { puts("MMC sprite init failed\n"); return -1; } else { puts("mmc init ok\n"); } sunxi_flash_init_pt = sunxi_flash_mmc_init; sunxi_flash_read_pt = sunxi_flash_mmc_read; sunxi_flash_write_pt = sunxi_flash_mmc_write; sunxi_flash_size_pt = sunxi_flash_mmc_size; sunxi_flash_phyread_pt = sunxi_flash_mmc_phyread; sunxi_flash_phywrite_pt = sunxi_flash_mmc_phywrite; sunxi_flash_exit_pt = sunxi_flash_mmc_exit; } sunxi_flash_init_uboot(0); } else if(workmode & WORK_MODE_UPDATE) /* 升级模式 */ { } else /* undefined mode */ { } return 0; }
static int axp_probe_type(int main_pmu_id, int slave_pmu_id) { int ret = 0; printf("use pmu by pmu_id from sys_config.fex\n"); switch(main_pmu_id) { case PMU_TYPE_22X: #if defined(CONFIG_SUNXI_AXP22) if(axp22_probe()) { printf("probe axp22x failed\n"); } else { /* pmu type AXP22X */ tick_printf("PMU: AXP22x found\n"); ret ++; } sunxi_axp_dev[0] = &sunxi_axp_22; sunxi_axp_dev[PMU_TYPE_22X] = &sunxi_axp_22; #endif break; case PMU_TYPE_20X: #if defined(CONFIG_SUNXI_AXP20) if(axp20_probe()) { printf("probe axp20x failed\n"); } else { /* pmu type AXP22X */ tick_printf("PMU: AXP20x found\n"); ret ++; } sunxi_axp_dev[0] = &sunxi_axp_20; sunxi_axp_dev[PMU_TYPE_20X] = &sunxi_axp_20; #endif break; case PMU_TYPE_15X: #if defined(CONFIG_SUNXI_AXP15) if(axp15_probe()) { printf("probe axp15 failed\n"); } else { /* pmu type AXP15X */ tick_printf("PMU: AXP15x found\n"); ret ++; } sunxi_axp_dev[0] = &sunxi_axp_15; sunxi_axp_dev[PMU_TYPE_15X] = &sunxi_axp_15; #endif break; case PMU_TYPE_809: #if defined(CONFIG_SUNXI_AXP809) if(axp809_probe()) { printf("probe axp809 failed\n"); } else { /* pmu type AXP809 */ tick_printf("PMU: AXP809 found\n"); ret ++; } sunxi_axp_dev[0] = &sunxi_axp_809; sunxi_axp_dev[PMU_TYPE_809] = &sunxi_axp_809; #endif break; case PMU_TYPE_806: #if defined(CONFIG_SUNXI_AXP806) if(axp806_probe()) { printf("probe axp806 failed\n"); } else { /* pmu type AXP806 */ tick_printf("PMU: AXP806 found\n"); ret ++; } sunxi_axp_dev[0] = &sunxi_axp_806; sunxi_axp_dev[PMU_TYPE_806] = &sunxi_axp_806; #endif break; case PMU_TYPE_808: #if defined(CONFIG_SUNXI_AXP808) if(axp808_probe()) { printf("probe axp808 failed\n"); } else { /* pmu type AXP808 */ tick_printf("PMU: AXP808 found\n"); ret ++; } sunxi_axp_dev[0] = &sunxi_axp_808; sunxi_axp_dev[PMU_TYPE_808] = &sunxi_axp_808; #endif break; case PMU_TYPE_81X: #if defined(CONFIG_SUNXI_AXP81X) if(axp81_probe()) { printf("probe axp81x failed\n"); } else { /* pmu type AXP81x */ tick_printf("PMU: AXP81x found\n"); ret ++; } sunxi_axp_dev[0] = &sunxi_axp_81; sunxi_axp_dev[PMU_TYPE_81X] = &sunxi_axp_81; #endif break; default: tick_printf("main pmu id is valid\n"); break; } switch(slave_pmu_id) { case PMU_TYPE_22X: #if defined(CONFIG_SUNXI_AXP22) if(axp22_probe()) { printf("probe axp22x failed\n"); } else { /* pmu type AXP22X */ tick_printf("PMU: AXP22x found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_22X] = &sunxi_axp_22; #endif break; case PMU_TYPE_20X: #if defined(CONFIG_SUNXI_AXP20) if(axp20_probe()) { printf("probe axp20x failed\n"); } else { /* pmu type AXP22X */ tick_printf("PMU: AXP20x found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_20X] = &sunxi_axp_20; #endif break; case PMU_TYPE_15X: #if defined(CONFIG_SUNXI_AXP15) if(axp15_probe()) { printf("probe axp15 failed\n"); } else { /* pmu type AXP15X */ tick_printf("PMU: AXP15x found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_15X] = &sunxi_axp_15; #endif break; case PMU_TYPE_809: #if defined(CONFIG_SUNXI_AXP809) if(axp809_probe()) { printf("probe axp809 failed\n"); } else { /* pmu type AXP809 */ tick_printf("PMU: AXP809 found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_809] = &sunxi_axp_809; #endif break; case PMU_TYPE_806: #if defined(CONFIG_SUNXI_AXP806) if(axp806_probe()) { printf("probe axp806 failed\n"); } else { /* pmu type AXP806 */ tick_printf("PMU: AXP806 found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_806] = &sunxi_axp_806; #endif break; case PMU_TYPE_808: #if defined(CONFIG_SUNXI_AXP808) if(axp808_probe()) { printf("probe axp808 failed\n"); } else { /* pmu type AXP808 */ tick_printf("PMU: AXP808 found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_808] = &sunxi_axp_808; #endif break; case PMU_TYPE_81X: #if defined(CONFIG_SUNXI_AXP81X) if(axp81_probe()) { printf("probe axp81x failed\n"); } else { /* pmu type AXP81x */ tick_printf("PMU: AXP81x found\n"); ret ++; } sunxi_axp_dev[PMU_TYPE_81X] = &sunxi_axp_81; #endif break; case POWER_TYPE_OZ: #if defined(CONFIG_SUNXI_POWEROZ) if(power_oz_probe()) { printf("probe oz failed\n"); } else { /* pmu type poewr oz */ tick_printf("power: oz found\n"); ret ++; } #endif break; case POWER_TYPE_RICH: #if defined(CONFIG_SUNXI_POWEROZ) if(power_rich_probe()) { printf("probe rich failed\n"); } else { /* pmu type poewr oz */ tick_printf("power: rich found\n"); ret ++; } #endif break; default: tick_printf("slave pmu id is valid\n"); break; } return ret; }
int power_source_init(void) { int pll1; int cpu_vol; int dcdc_vol; if(script_parser_fetch("power_sply", "dcdc2_vol", &dcdc_vol, 1)) { cpu_vol = 900; } else { cpu_vol = dcdc_vol%10000; } if(axp_probe() > 0) { axp_probe_factory_mode(); if(!axp_probe_power_supply_condition()) { //PMU_SUPPLY_DCDC2 is for cpua if(!axp_set_supply_status(0, PMU_SUPPLY_DCDC2, cpu_vol, -1)) { tick_printf("PMU: dcdc2 %d\n", cpu_vol); sunxi_clock_set_corepll(uboot_spare_head.boot_data.run_clock, 0); } else { printf("axp_set_dcdc2 fail\n"); } } else { printf("axp_probe_power_supply_condition error\n"); } } else { printf("axp_probe error\n"); } pll1 = sunxi_clock_get_corepll(); tick_printf("PMU: pll1 %d Mhz\n", pll1); printf("AXI0=%d Mhz,PLL_PERIPH =%d Mhz AHB1=%d Mhz, APB1=%d Mhz \n", sunxi_clock_get_axi(), sunxi_clock_get_pll6(), sunxi_clock_get_ahb(), sunxi_clock_get_apb1()); axp_set_charge_vol_limit(); axp_set_all_limit(); axp_set_hardware_poweron_vol(); axp_set_power_supply_output(); power_config_gpio_bias(); power_limit_init(); // AXP and RTC use the same interrupt line, so disable RTC INT in uboot disable_rtc_int(); return 0; }
int checkboard(void) { tick_printf("Board: SUN6I\n"); return 0; }
static int board_probe_bat_status(int standby_mode) { int dc_exist, bat_exist, counter; int bat_init = 0; int bat_cal = 1; int ret, chargemode = 0; //当前可以确定是火牛开机,但是是否开机还不确定,需要确认电池是否存在 //当电池不存在即开机,电池存在则关机 //新添加,根据环境变量,是启动当前的待机,或者android待机功能 ret = script_parser_fetch("charging_type", "charging_type", &chargemode, 1); if((!ret) && chargemode) { chargemode = 1; } counter = 4; do { dc_exist = 0; bat_exist = 0; axp_power_get_dcin_battery_exist(&dc_exist, &bat_exist); printf("bat_exist=%d\n", bat_exist); if(bat_exist == -1) { printf("bat is unknown\n"); if(!chargemode) { if(!bat_init) { if(battery_charge_cartoon_init(0) < 0) { tick_printf("init charge cartoon fail\n"); return -1; } bat_init = 1; } } __msdelay(500); } else { break; } } while(counter --); #ifdef FORCE_BOOT_STANDBY bat_exist = 1; #else if(standby_mode) { bat_exist = 1; } #endif if(bat_exist <= 0) { tick_printf("no battery exist\n"); if(chargemode) { return 0; } if(bat_init) { battery_charge_cartoon_exit(); } return 0; } if(chargemode) { printf("use android charge mode"); gd->chargemode = 1; return 0; } if(!bat_init) { bat_cal = axp_probe_rest_battery_capacity(); printf("bat not inited\n"); if(battery_charge_cartoon_init(bat_cal/(100/(SUNXI_BAT_BMP_MAX-1))) < 0) { tick_printf("init charge cartoon fail\n"); return -1; } } if((!bat_cal) && (standby_mode)) { bat_cal = 100; } return bat_cal; }
static int board_standby_status(int source_bat_cal) { int bat_cal, this_bat_cal; int i, j, status; int one_delay; int ret; boot_standby_action = 0; this_bat_cal = source_bat_cal; tick_printf("base bat_cal = %d\n", this_bat_cal); if(this_bat_cal > 95) { this_bat_cal = 100; } //启动中断检测 usb_detect_for_charge(BOOT_USB_DETECT_DELAY_TIME + 200); //启动axp检测 power_limit_detect_enter(); status = 1; goto __start_case_status__; /****************************************************************** * * standby 返回值说明 * * -1: 进入standby失败 * 1: 普通按键唤醒 * 2: 电源按键短按唤醒 * 3: 电源按键长按唤醒 * 4: 外部电源移除唤醒 * 5: 电池充电完成 * 6: 在唤醒状态下外部电源被移除 * 7: 在唤醒状态下充电完成 * ******************************************************************/ do { tick_printf("enter standby\n"); board_display_layer_close(); power_limit_detect_exit(); status = board_try_boot_standby(); tick_printf("exit standby by %d\n", status); bat_cal = axp_probe_rest_battery_capacity(); tick_printf("current bat_cal = %d\n", bat_cal); if(bat_cal > this_bat_cal) { this_bat_cal = bat_cal; } __start_case_status__: tick_printf("status = %d\n", status); switch(status) { case 2: //短按power按键导致唤醒 //启动中断检测 boot_standby_action = 0; power_limit_detect_enter(); board_display_layer_open(); case 1: //重新计算动画延时时间 if(this_bat_cal == 100) { one_delay = 1000; } else { one_delay = 1000/(10 - (this_bat_cal/10)); } //绘制动画 for(j=0;j<3;j++) { for(i=this_bat_cal/(100/(SUNXI_BAT_BMP_MAX-1));i<SUNXI_BAT_BMP_MAX;i++) { battery_charge_cartoon_rate(i); if(boot_standby_action & 0x08) //存在外部电源 { boot_standby_action &= ~0x08; j = 0; } else if(boot_standby_action & 0x02) //短按 { boot_standby_action &= ~2; j = 0; } else if(boot_standby_action & 0x01) //长按 { battery_charge_cartoon_exit(); power_limit_detect_exit(); return 0; } else if(boot_standby_action & 0x10) //拔掉外部电源,没有外部电源 { status = 10; boot_standby_action &= ~0x10; goto __start_case_status__; } __msdelay(one_delay); } } //停止动画,固定显示当前电量 battery_charge_cartoon_rate(this_bat_cal/(100/(SUNXI_BAT_BMP_MAX-1))); for(j=0;j<4;j++) { if(boot_standby_action & 0x08) //存在外部电源 { boot_standby_action &= ~0x08; j = 0; } else if(boot_standby_action & 0x10) //拔掉外部电源,没有外部电源 { status = 10; boot_standby_action &= ~0x10; goto __start_case_status__; } else if(boot_standby_action & 0x01) //长按 { battery_charge_cartoon_exit(); power_limit_detect_exit(); return 0; } __msdelay(250); } break; case 3: //长按电源按键之后,关闭电池图标,进入系统 battery_charge_cartoon_exit(); return 0; case 4: //当移除外部电源时候,重新显示当前电池图标后,3秒后关机 case 5: //当电池充电完成的时候,需要关机 //启动中断检测 boot_standby_action = 0; power_limit_detect_enter(); board_display_layer_open(); battery_charge_cartoon_rate(this_bat_cal/(100/(SUNXI_BAT_BMP_MAX-1))); case 6: case 7: if((status != 4) && (status != 5)) { board_display_layer_open(); battery_charge_cartoon_rate(this_bat_cal/(100/(SUNXI_BAT_BMP_MAX-1))); } case 10: battery_charge_cartoon_rate(this_bat_cal/(100/(SUNXI_BAT_BMP_MAX-1))); __msdelay(500); do { if(!(boot_standby_action & 0x04)) { ret = battery_charge_cartoon_degrade(5); } else { status = 1; battery_charge_cartoon_reset(); goto __start_case_status__; } } while(!ret); battery_charge_cartoon_exit(); power_limit_detect_exit(); return -1; case 8: //standby过程中检测到vbus存在变化 { usb_detect_for_charge(BOOT_USB_DETECT_DELAY_TIME + 200); } break; case 9: //standby过程中检测到vbus移除,同时存在普通dc { // power_set_usbpc(); } break; default: break; } } while(1); }