int power_config_gpio_bias(void) { char gpio_bias[32], gpio_name[32]; char *gpio_name_const="pa_bias"; char port_index; char *axp=NULL, *supply=NULL, *vol=NULL; uint main_hd; uint bias_vol_set; int index, ret, i; uint port_bias_addr; uint vol_index, config_type; int pmu_vol; struct bias_set bias_vol_config[8] = { {1800, 0}, {2500, 6}, {2800, 9}, {3000, 0xa}, {3300, 0xd}, {0, 0} }; main_hd = script_parser_fetch_subkey_start("gpio_bias"); if(main_hd == 0) { printf("gpio_bias not exist\n"); return 0; } index = 0; while(1) { memset(gpio_bias, 0, 32); memset(gpio_name, 0, 32); ret = script_parser_fetch_subkey_next(main_hd, gpio_name, (int *)gpio_bias, &index); if(!ret) { lower(gpio_name); lower(gpio_bias); port_index = gpio_name[1]; gpio_name[1] = 'a'; if(strcmp(gpio_name_const, gpio_name)) { printf("invalid gpio bias name %s\n", gpio_name); continue; } gpio_name[1] = port_index; i=0; axp = gpio_bias; while( (gpio_bias[i]!=':') && (gpio_bias[i]!='\0') ) { i++; } gpio_bias[i++]='\0'; if(!strcmp(axp, "constant")) { config_type = 1; } else if(!strcmp(axp, "floating")) { printf("ignore %s bias config\n", gpio_name); continue; } else { config_type = 0; } if(config_type == 0) { supply = gpio_bias + i; while( (gpio_bias[i]!=':') && (gpio_bias[i]!='\0') ) { i++; } gpio_bias[i++]='\0'; } printf("supply=%s\n", supply); vol = gpio_bias + i; while( (gpio_bias[i]!=':') && (gpio_bias[i]!='\0') ) { i++; } bias_vol_set = simple_strtoul(vol, NULL, 10); for(i=0;i<5;i++) { if(bias_vol_config[i].vol == bias_vol_set) { break; } } if(i==5) { printf("invalid gpio bias set vol %d, at name %s\n", bias_vol_set, gpio_name); break; } vol_index = bias_vol_config[i].index; if((port_index >= 'a') && (port_index <= 'h')) { //获取寄存器地址 port_bias_addr = SUNXI_PIO_BASE + 0x300 + 0x4 * (port_index - 'a'); } else if(port_index == 'j') { //获取寄存器地址 port_bias_addr = SUNXI_PIO_BASE + 0x300 + 0x4 * (port_index - 'a'); } else if((port_index == 'l') || (port_index == 'm')) { //获取寄存器地址 port_bias_addr = SUNXI_RPIO_BASE + 0x300 + 0x4 * (port_index - 'l'); } else { printf("invalid gpio port at name %s\n", gpio_name); continue; } printf("axp=%s, supply=%s, vol=%d\n", axp, supply, bias_vol_set); if(config_type == 1) { smc_writel(vol_index, port_bias_addr); } else { pmu_vol = axp_probe_supply_status_byname(axp, supply); if(pmu_vol < 0) { printf("sunxi board read %s %s failed\n", axp, supply); continue; } if(pmu_vol > bias_vol_set) //pmu实际电压超过需要设置的电压 { //电压降低到需要电压 axp_set_supply_status_byname(axp, supply, bias_vol_set, 1); //设置寄存器 smc_writel(vol_index, port_bias_addr); } else if(pmu_vol < bias_vol_set) //pmu实际电压低于需要设置的电压 { //设置寄存器 smc_writel(vol_index, port_bias_addr); //把pmu电压调整到需要的电压 axp_set_supply_status_byname(axp, supply, bias_vol_set, 1); } else { //如果实际电压等于需要设置电压,直接设置即可 smc_writel(vol_index, port_bias_addr); } } printf("reg addr=0x%x, value=0x%x, pmu_vol=%d\n", port_bias_addr, smc_readl(port_bias_addr), bias_vol_set); } else { printf("config gpio bias voltage finish\n"); break; } } return 0; }
int axp_set_supply_status_byregulator(const char* id, int onoff) { char main_key[32]; char pmu_type[32]; char vol_type[32]; char sub_key_name[32]; char sub_key_value[256]; int main_hd = 0; unsigned int i = 0, j = 0, index = 0; int ldo_count = 0; int find_flag = 0; int ret = 0; #if (defined(CONFIG_ARCH_SUN8IW6) && defined(CONFIG_ARCH_HOMELET)) static int chipid = -2; //use static variable for read once if(chipid == -2) { //just read once chipid = plat_get_chip_id(); } //0x18:axp_818, 0x13:axp_813 0x03:axp_803 0x0: key not burn if(chipid == -1) //default, platform not implement function plat_get_chip_id { printf("axp chipid not care,use default regulator tree\n"); i = 1; } else if(chipid == 0x03) { printf("use extend regulator tree\n"); i = 2; } else { printf("use default regulator tree\n"); i = 1; } for(i = 1; i <= 1; i++) { #else for(i = 1; i <= 2; i++) { #endif sprintf(main_key,"pmu%d_regu", i); main_hd = script_parser_fetch(main_key,"regulator_count",&ldo_count, 1); if(main_hd != 0) { //printf("unable to get ldo_count from [%s] \n",main_key); break; } for(index = 1; index <= ldo_count; index++) { sprintf(sub_key_name, "regulator%d", index); main_hd = script_parser_fetch(main_key,sub_key_name,(int*)(sub_key_value), sizeof(sub_key_value)/sizeof(int)); if(main_hd != 0) { //printf("unable to get subkey %s from [%s]\n",sub_key_name, main_key); break; } if(find_regulator_str(sub_key_value, id)) { find_flag = 1; break; } } if(find_flag) break; } if(!find_flag) { printf("unable to find regulator %s from [pmu1_regu] or [pmu2_regu] \n",id); return -1; } //example : ldo6 = "axp81x_dcdc6 vdd-sys vdd-usb0-09 vdd-hdmi-09" memset(pmu_type, 0, sizeof(pmu_type)); memset(vol_type, 0, sizeof(vol_type)); //get pmu type for(j = 0,i =0; i < strlen(sub_key_value); i++) { if(sub_key_value[i] == '_') { i++; break; } pmu_type[j++] = sub_key_value[i]; } //get vol type j = 0; for(; i < strlen(sub_key_value); i++) { if(sub_key_value[i] == ' ') { break; } vol_type[j++]= sub_key_value[i]; } //para vol = 0 indcate not set vol,only open or close voltage switch ret = axp_set_supply_status_byname(pmu_type,vol_type,0, onoff); if(ret != 0) { printf("error: supply regelator %s=id, pmu_type=%s_%s onoff=%d fail\n", id,pmu_type,vol_type,onoff ); } return ret; } /* ************************************************************************************************************ * * function * * name : * * parmeters : * * return : * * note : * * ************************************************************************************************************ */ static int current_pmu = -1; int axp_probe_supply_pmu_name(char *axpname) { int i = 0; if(axpname == NULL) { return -1; } for(i=1;i<SUNXI_AXP_DEV_MAX;i++) { if((sunxi_axp_dev[i] != NULL) && (current_pmu < i)) { current_pmu = i; strcpy(axpname, sunxi_axp_dev[i]->pmu_name); return 0; } } return -1; }