static int usb_charging_detect_call_back(char bc_mode) { #ifdef CONFIG_PLATFORM_HAS_PMU struct aml_pmu_driver *driver = aml_pmu_get_driver(); #endif switch(bc_mode){ case BC_MODE_DCP: case BC_MODE_CDP: //Pull up chargging current > 500mA #ifdef CONFIG_PLATFORM_HAS_PMU if (driver && driver->pmu_set_usb_current_limit) { driver->pmu_set_usb_current_limit(0); // do not limit usb current } #endif break; case BC_MODE_UNKNOWN: case BC_MODE_SDP: default: //Limit chargging current <= 500mA //Or detet dec-charger #ifdef CONFIG_PLATFORM_HAS_PMU if (driver && driver->pmu_set_usb_current_limit) { driver->pmu_set_usb_current_limit(500); } #endif break; } return 0; }
static int do_set_usbcur_limit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { int usbcur_limit = simple_strtol(argv[1], NULL, 10); if (argc < 2) return cmd_usage(cmdtp); #ifdef CONFIG_PLATFORM_HAS_PMU struct aml_pmu_driver *pmu_driver; pmu_driver = aml_pmu_get_driver(); if (pmu_driver && pmu_driver->pmu_set_usb_current_limit) { pmu_driver->pmu_set_usb_current_limit(usbcur_limit); printf("set usbcur_limit: %smA\n", argv[1]); if (argc == 2 ) { setenv("usbcur_limit", argv[1]); } } else { printf("ERROR!! No pmu_set_usb_current_limit hooks!\n"); } #else pmu_set_usbcur_limit(usbcur_limit); printf("set usbcur_limit: %smA\n", argv[1]); if (argc == 2 ) { setenv("usbcur_limit", argv[1]); } #endif return 0; }
static void board_pmu_init(void) { struct aml_pmu_driver *driver = aml_pmu_get_driver(); if (driver && driver->pmu_init) { driver->pmu_init(); } #ifdef CONFIG_AW_AXP20 // todo add your platform needed init code here #ifdef CONFIG_AML_AXP202 uint8_t tmp; uint8_t reg_val; uint8_t axp_ts_current=0x3; //TS pin output current: 00:20uA£»01:40uA;10:60uA;11:80uA #endif #ifdef CONFIG_AML_AXP202 #define LTF_CHARGE_REG 0x38 #define HTF_CHARGE_REG 0x39 //#define LTF_DISCHARGE_REG 0x3c //#define HTF_DISCHARGE_REG 0x3d #define TS_CURRENT_REG 0x84 axp_read(TS_CURRENT_REG, ®_val); tmp = axp_ts_current << 4; reg_val &= ~(3<<4); //reg_val &= 0xcf; reg_val |= tmp; reg_val &= ~(3<<0); reg_val |= 0x1; //TS pin:charge output current axp_write(TS_CURRENT_REG,reg_val); //set TS pin output current axp_write(LTF_CHARGE_REG,0xDB); //set battery low temperature threshold,T=0 axp_write(HTF_CHARGE_REG,0x48); //set battery high temperature threshold,T=70 #endif #endif }
static int do_set_chgcur (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #if 0 /* rsy blocked */ int current = simple_strtol(argv[1], NULL, 10); #endif #ifdef CONFIG_PLATFORM_HAS_PMU struct aml_pmu_driver *pmu_driver; pmu_driver = aml_pmu_get_driver(); if (pmu_driver && pmu_driver->pmu_set_charge_current) { pmu_driver->pmu_set_charge_current(current); setenv("charging_current", argv[1]); } else { printf("ERROR!! No pmu_set_charge_current hooks!\n"); } #else #if 0 /* rsy blocked */ set_charging_current(current); printf("Charging current: %smA\n", argv[1]); setenv("charging_current", argv[1]); #endif #endif return 0; }
static void board_pmu_init(void) { struct aml_pmu_driver *driver = aml_pmu_get_driver(); if (driver && driver->pmu_init) { driver->pmu_init(); } }
static int usb_charging_detect_call_back(char bc_mode) { #ifdef CONFIG_PLATFORM_HAS_PMU struct aml_pmu_driver *driver = aml_pmu_get_driver(); struct battery_parameter *battery; #endif switch(bc_mode){ case BC_MODE_DCP: case BC_MODE_CDP: //Pull up chargging current > 500mA #ifdef CONFIG_PLATFORM_HAS_PMU /* * Policy: * for charger and PC + charger, don't limit usb current */ if (driver && driver->pmu_set_usb_current_limit) { driver->pmu_set_usb_current_limit(900); // Max allowed in 1212 #ifdef CONFIG_VBUS_DC_SHORT_CONNECT aml_pmu_set_dcin(1); // enable DC_IN when detect charger #endif } #endif break; case BC_MODE_UNKNOWN: case BC_MODE_SDP: default: //Limit chargging current <= 500mA //Or detet dec-charger #ifdef CONFIG_PLATFORM_HAS_PMU /* * for PC: * If pmu_usbcur_limit is 1 in dts, then set usb current by * value pmu_usbcur set in dts. If pmu_usbcur_limit is 0, then don't * limit usb current. If not find battery parameters, set usb current * to 500mA as default */ battery = get_battery_para(); if (driver && battery && driver->pmu_set_usb_current_limit) { if (battery->pmu_usbcur_limit) { driver->pmu_set_usb_current_limit(battery->pmu_usbcur); } else { driver->pmu_set_usb_current_limit(900); } } else { driver->pmu_set_usb_current_limit(500); } #ifdef CONFIG_VBUS_DC_SHORT_CONNECT aml_pmu_set_dcin(0); // don't open dcin when connect to PC #endif #endif break; } return 0; }
static int do_battery_test(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct aml_pmu_driver *pmu_driver; pmu_driver = aml_pmu_get_driver(); if (pmu_driver && pmu_driver->pmu_do_battery_calibrate) { pmu_driver->pmu_do_battery_calibrate(); } else { printf("ERROR!! No pmu_do_battery_calibrate hooks!\n"); } return 0; }
static void board_pmu_init(void) { struct aml_pmu_driver *driver = aml_pmu_get_driver(); if (driver && driver->pmu_reg_write) { printf("%s, increase DCIN_OV_ADJ\n", __func__); driver->pmu_reg_write(0x0030, 0x18); } if (driver && driver->pmu_init) { driver->pmu_init(); } }
static int usb_charging_detect_call_back(char bc_mode) { #ifdef CONFIG_PLATFORM_HAS_PMU struct aml_pmu_driver *driver = aml_pmu_get_driver(); struct battery_parameter *battery; #endif switch(bc_mode){ case BC_MODE_DCP: case BC_MODE_CDP: //Pull up chargging current > 500mA #ifdef CONFIG_PLATFORM_HAS_PMU /* * Policy: * for charger and PC + charger, don't limit usb current */ if (driver && driver->pmu_set_usb_current_limit) { driver->pmu_set_usb_current_limit(-1); // -1 means do not limit usb current } #endif break; case BC_MODE_SDP: //Limit chargging current <= 500mA //Or detet dec-charger #ifdef CONFIG_PLATFORM_HAS_PMU /* * for PC: * If pmu_usbcur_limit is 1 in dts, then set usb current by * value pmu_usbcur set in dts. If pmu_usbcur_limit is 0, then don't * limit usb current. If not find battery parameters, set usb current * to 500mA as default */ battery = get_battery_para(); if (driver && driver->pmu_usb_bc_process) { driver->pmu_usb_bc_process(bc_mode); } if (driver && battery && driver->pmu_set_usb_current_limit) { if (battery->pmu_usbcur_limit) { driver->pmu_set_usb_current_limit(battery->pmu_usbcur); } else { driver->pmu_set_usb_current_limit(-1); } } else { driver->pmu_set_usb_current_limit(500); } #endif break; case BC_MODE_UNKNOWN: default: break; } return 0; }
int do_get_rebootmode (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { uint32_t reboot_mode_val; #ifdef CONFIG_RESET_TO_SYSTEM struct aml_pmu_driver *pmu_driver = NULL; int reboot_flag; #endif reboot_mode_val = reboot_mode; debug("reboot_mode(0x%x)=0x%x\n", &reboot_mode, reboot_mode); #ifdef CONFIG_RESET_TO_SYSTEM pmu_driver = aml_pmu_get_driver(); if (pmu_driver && pmu_driver->pmu_reset_flag_operation) { reboot_flag = pmu_driver->pmu_reset_flag_operation(RESET_FLAG_GET); printf("reboot flag = %d\n", reboot_flag); if (reboot_flag) { printf("abnormal reboot, direct boot to Kernel now\n"); run_command("run prepare; bmp display ${poweron_offset}; run bootcmd;", 0); } } #endif switch(reboot_mode_val) { case AMLOGIC_NORMAL_BOOT: { setenv("reboot_mode","normal"); break; } case AMLOGIC_FACTORY_RESET_REBOOT: { setenv("reboot_mode","factory_reset"); break; } case AMLOGIC_UPDATE_REBOOT: { setenv("reboot_mode","update"); break; } case MESON_USB_BURNER_REBOOT: { setenv("reboot_mode","usb_burning"); break; } default: { setenv("reboot_mode","charging"); break; } } return 0; }
static inline int do_ac_online (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #ifdef CONFIG_PLATFORM_HAS_PMU struct aml_pmu_driver *pmu_driver; pmu_driver = aml_pmu_get_driver(); if (pmu_driver && pmu_driver->pmu_get_extern_power_status) { return !pmu_driver->pmu_get_extern_power_status(); } else { printf("ERROR!! No pmu_get_battery_capacity hooks!\n"); return 0; } #else return !is_ac_online(); #endif }
static int do_poweroff (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #ifdef CONFIG_PLATFORM_HAS_PMU struct aml_pmu_driver *pmu_driver; pmu_driver = aml_pmu_get_driver(); if (pmu_driver && pmu_driver->pmu_power_off) { pmu_driver->pmu_power_off(); } else { printf("ERROR!! NO power off hooks!\n"); } #else power_off(); #endif return 0; }
static int do_pmu_reg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct aml_pmu_driver *pmu_driver; int rw = 0;//, i; int addr; unsigned char val; if (argc < 1 || argc > 4) { return cmd_usage(cmdtp); } pmu_driver = aml_pmu_get_driver(); if (!strcmp(argv[1], "r")) { rw = 0; } else if (!strcmp(argv[1], "w")) { rw = 1; } else if (!strcmp(argv[1], "d")) { if (pmu_driver && pmu_driver->pmu_dump_register) { pmu_driver->pmu_dump_register(DUMP_ALL); return 0; } } else { return cmd_usage(cmdtp); } addr = simple_strtoul(argv[2], NULL, 16); if (rw == 1) { val = simple_strtoul(argv[3], NULL, 16); } if (pmu_driver && pmu_driver->pmu_reg_read && rw == 0) { if (pmu_driver->pmu_reg_read(addr, &val)) { printf("read addr 0x%03x failed\n", addr); return -1; } printf("REG[0x%02x] = 0x%02x\n", addr, val); } else if (pmu_driver && pmu_driver->pmu_reg_write && rw == 1) { if (pmu_driver->pmu_reg_write(addr, val)) { printf("write addr 0x%03x failed\n", addr); return -1; } printf("REG[0x%02x] set to 0x%02x\n", addr, val); } else { printf("ERROR!! No hooks!\n"); } return 0; }
static int do_get_batcap (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { char percent_str[16]; int percent = 0; #ifdef CONFIG_PLATFORM_HAS_PMU struct aml_pmu_driver *pmu_driver; pmu_driver = aml_pmu_get_driver(); if (pmu_driver && pmu_driver->pmu_get_battery_capacity) { percent = pmu_driver->pmu_get_battery_capacity(); } else { printf("ERROR!! No pmu_get_battery_capacity hooks!\n"); } #else percent = get_charging_percent(); #endif printf("Battery CAP: %d%%\n", percent); sprintf(percent_str, "%d", percent); setenv("battery_cap", percent_str); return 0; }
static int bl_extern_set_level(unsigned int level) { #ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU struct aml_pmu_driver *pmu_driver; unsigned char temp; #endif int ret = 0; if (bl_ext_config == NULL) { printk("no %s driver\n", BL_EXTERN_NAME); return -1; } get_bl_ext_level(bl_ext_config); level = bl_ext_config->dim_min - ((level - bl_ext_config->level_min) * (bl_ext_config->dim_min - bl_ext_config->dim_max)) / (bl_ext_config->level_max - bl_ext_config->level_min); level &= 0x1f; #ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU pmu_driver = aml_pmu_get_driver(); if (pmu_driver == NULL) { printk("no pmu driver\n"); return -1; } else { if ((pmu_driver->pmu_reg_write) && (pmu_driver->pmu_reg_read)) { ret = pmu_driver->pmu_reg_read(0x005f, &temp); temp &= ~(0x3f << 2); temp |= (level << 2); ret = pmu_driver->pmu_reg_write(0x005f, temp); } else { printk("no pmu_reg_read/write\n"); return -1; } } #endif return ret; }
static int bl_extern_power_on(void) { #ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU struct aml_pmu_driver *pmu_driver; unsigned char temp; #endif int ret = 0; #ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU pmu_driver = aml_pmu_get_driver(); if (pmu_driver == NULL) { printk("no pmu driver\n"); return -1; } else { if ((pmu_driver->pmu_reg_write) && (pmu_driver->pmu_reg_read)) { ret = pmu_driver->pmu_reg_read(0x005e, &temp); temp |= (1 << 7); ret = pmu_driver->pmu_reg_write(0x005e, temp);//DCEXT_IREF_ADJLV2_EN } else { printk("no pmu_reg_read/write\n"); return -1; } } #endif if (bl_ext_config->gpio_used > 0) { if (bl_ext_config->gpio_on==2) bl_extern_gpio_direction_input(bl_ext_config->gpio); else bl_extern_gpio_direction_output(bl_ext_config->gpio, bl_ext_config->gpio_on); } printk("%s\n", __FUNCTION__); return ret; }
printk("%s\n", __FUNCTION__); return ret; } //***********************************************// static ssize_t bl_extern_debug(struct class *class, struct class_attribute *attr, const char *buf, size_t count) { #ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU struct aml_pmu_driver *pmu_driver; unsigned char temp; unsigned int t[2]; #endif int ret = 0; #ifdef CONFIG_AMLOGIC_BOARD_HAS_PMU pmu_driver = aml_pmu_get_driver(); if (pmu_driver == NULL) { printk("no pmu driver\n"); return -EINVAL; } switch (buf[0]) { case 'r': //read ret = sscanf(buf, "r %x", &t[0]); if ((pmu_driver->pmu_reg_write) && (pmu_driver->pmu_reg_read)) { ret = pmu_driver->pmu_reg_read(t[0], &temp); printk("read pmu reg: 0x%x=0x%x\n", t[0], temp); } break; case 'w': //write ret = sscanf(buf, "w %x %x", &t[0], &t[1]);
int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { ulong iflag; ulong load_end = 0; int ret = 0; boot_os_fn *boot_fn; AML_LOG_INIT("cmd_bootm"); AML_LOG_TE("cmd_bootm"); #ifdef TEST_UBOOT_BOOT_SPEND_TIME bootm_start_time = get_utimer(0); #endif #ifdef CONFIG_NEEDS_MANUAL_RELOC static int relocated = 0; /* relocate boot function table */ if (!relocated) { int i; for (i = 0; i < ARRAY_SIZE(boot_os); i++) if (boot_os[i] != NULL) boot_os[i] += gd->reloc_off; relocated = 1; } #endif AML_LOG_TE("cmd_bootm"); #ifdef CONFIG_RESET_TO_SYSTEM struct aml_pmu_driver *pmu_driver = NULL; pmu_driver = aml_pmu_get_driver(); if (pmu_driver && pmu_driver->pmu_reset_flag_operation) { pmu_driver->pmu_reset_flag_operation(RESET_FLAG_SET); } #endif AML_LOG_TE("cmd_bootm"); #ifdef CONFIG_M6_SECU_BOOT #ifdef CONFIG_MESON_TRUSTZONE extern int meson_trustzone_boot_check(unsigned char *addr); ret = meson_trustzone_boot_check((unsigned char*)load_addr); #else extern int aml_decrypt_kernel_image(void* kernel_image_address); ret = aml_decrypt_kernel_image((void*)load_addr); #endif if(ret != 0) { printf("Error! Illegal kernel image, please check!\n"); return ret; } #endif //CONFIG_M6_SECU_BOOT AML_LOG_TE("cmd_bootm"); #ifdef CONFIG_AML_SECU_BOOT_V2 #ifdef CONFIG_MESON_TRUSTZONE extern int meson_trustzone_boot_check(unsigned char *addr); if(!g_nIMGReadFlag) ret = meson_trustzone_boot_check(aml_get_kernel_crypto_addr(argc < 2 ? NULL : argv[1])); #else extern int aml_sec_boot_check(unsigned char *pSRC); if(!g_nIMGReadFlag) ret = aml_sec_boot_check(aml_get_kernel_crypto_addr(argc < 2 ? NULL : argv[1])); #endif if(0 != ret) return ret; #endif //CONFIG_AML_SECU_BOOT_V2 AML_LOG_TE("cmd_bootm"); #ifdef CONFIG_AML_GATE_INIT extern void gate_init(void); gate_init(); #endif /* determine if we have a sub command */ if (argc > 1) { char *endp; simple_strtoul(argv[1], &endp, 16); /* endp pointing to NULL means that argv[1] was just a * valid number, pass it along to the normal bootm processing * * If endp is ':' or '#' assume a FIT identifier so pass * along for normal processing. * * Right now we assume the first arg should never be '-' */ if ((*endp != 0) && (*endp != ':') && (*endp != '#')) return do_bootm_subcommand(cmdtp, flag, argc, argv); } AML_LOG_TE("cmd_bootm"); if (bootm_start(cmdtp, flag, argc, argv)) return 1; AML_LOG_TE("cmd_bootm"); /* * We have reached the point of no return: we are going to * overwrite all exception vector code, so we cannot easily * recover from any failures any more... */ iflag = disable_interrupts(); #if defined(CONFIG_CMD_USB) /* * turn off USB to prevent the host controller from writing to the * SDRAM while Linux is booting. This could happen (at least for OHCI * controller), because the HCCA (Host Controller Communication Area) * lies within the SDRAM and the host controller writes continously to * this area (as busmaster!). The HccaFrameNumber is for example * updated every 1 ms within the HCCA structure in SDRAM! For more * details see the OpenHCI specification. */ usb_stop(); #endif AML_LOG_TE("cmd_bootm"); ret = bootm_load_os(images.os, &load_end, 1); AML_LOG_TE("cmd_bootm"); if (ret < 0) { if (ret == BOOTM_ERR_RESET) do_reset (cmdtp, flag, argc, argv); if (ret == BOOTM_ERR_OVERLAP) { if (images.legacy_hdr_valid) { if (image_get_type (&images.legacy_hdr_os_copy) == IH_TYPE_MULTI) puts ("WARNING: legacy format multi component " "image overwritten\n"); } else { puts ("ERROR: new format image overwritten - " "must RESET the board to recover\n"); show_boot_progress (-113); do_reset (cmdtp, flag, argc, argv); } } if (ret == BOOTM_ERR_UNIMPLEMENTED) { if (iflag) enable_interrupts(); show_boot_progress (-7); return 1; } } AML_LOG_TE("cmd_bootm"); lmb_reserve(&images.lmb, images.os.load, (load_end - images.os.load)); AML_LOG_TE("cmd_bootm"); if (images.os.type == IH_TYPE_STANDALONE) { if (iflag) enable_interrupts(); /* This may return when 'autostart' is 'no' */ bootm_start_standalone(iflag, argc, argv); return 0; } show_boot_progress (8); #if defined(CONFIG_SILENT_CONSOLE) && \ (defined(CONFIG_SILENT_CONSOLE_LINUX_QUIET) || defined(CONFIG_DEPRECATED_SILENT_LINUX_CONSOLE)) if (images.os.os == IH_OS_LINUX) fixup_silent_linux(); #endif AML_LOG_TE("cmd_bootm"); #ifdef CONFIG_AUTO_SET_BOOTARGS_MEM mem_size_arg_process(); #endif boot_fn = boot_os[images.os.os]; if (boot_fn == NULL) { if (iflag) enable_interrupts(); printf ("ERROR: booting os '%s' (%d) is not supported\n", genimg_get_os_name(images.os.os), images.os.os); show_boot_progress (-8); return 1; } AML_LOG_TE("cmd_bootm"); arch_preboot_os(); #ifdef TEST_UBOOT_BOOT_SPEND_TIME { int boot_kernel_start; boot_kernel_start = get_utimer(0); printf("bootm start to prepare boot kernel time:%dus\n",boot_kernel_start-bootm_start_time); printf("from main_loop start to kernel decompress finished time:%dus\n",boot_kernel_start-main_loop_start); } #endif ulong temp_img_addr; AML_LOG_TE("cmd_bootm"); /* use fprintf to always show this print even if console is silenced with GD_FLG_SILENT */ fprintf(stderr, "uboot time: %d us.\n", get_utimer(0)); boot_fn(0, argc, argv, &images); show_boot_progress (-9); #ifdef DEBUG puts ("\n## Control returned to monitor - resetting...\n"); #endif do_reset (cmdtp, flag, argc, argv); return 1; }