static int axp_get_rdc(struct axp_charger *charger) { uint8_t val[3]; unsigned int i,temp,pre_temp; int averPreVol = 0, averPreCur = 0,averNextVol = 0,averNextCur = 0; //axp_reads(charger->master,AXP18_DATA_BUFFER1,2,val); axp_read(charger->master,AXP18_DATA_BUFFER1,val); axp_read(charger->master,AXP18_DATA_BUFFER2,val+1); pre_temp = (((val[0] & 0x7F) << 8 ) + val[1]); printk("%d:pre_temp = %d\n",__LINE__,pre_temp); if( charger->is_on){ for(i = 0; i< AXP18_RDC_COUNT; i++){ axp_charger_update(charger); averPreVol += charger->vbat; averPreCur += charger->ibat; msleep(50); } averPreVol /= AXP18_RDC_COUNT; averPreCur /= AXP18_RDC_COUNT; axp_clr_bits(charger->master,AXP18_CHARGE_CONTROL2,0x80); msleep(500); for(i = 0; i< AXP18_RDC_COUNT; i++){ axp_charger_update(charger); averNextVol += charger->vbat; averNextCur += charger->ibat; msleep(50); } averNextVol /= AXP18_RDC_COUNT; averNextVol /= AXP18_RDC_COUNT; axp_set_bits(charger->master,AXP18_CHARGE_CONTROL2,0x80); msleep(500); if(ABS(averPreCur - averNextCur) > 200){ temp = 1000 * ABS(averPreVol - averNextVol) / ABS(averPreCur); if((temp < 5) || (temp > 5000)){ return pre_temp; } else { temp += pre_temp; temp >>= 1; val[0] = ((temp & 0xFF00) | 0x8000) >> 8; val[1] = AXP18_DATA_BUFFER2; val[2] = temp & 0x00FF; axp_writes(charger->master,AXP18_DATA_BUFFER1,3,val ); return temp; } } else return pre_temp;
static void axp_set_charge(struct axp_charger *charger) { uint8_t val=0x00; uint8_t tmp=0x00; uint8_t var[3]; if(charger->chgvol < 4150) val &= ~(3 << 5); else if (charger->chgvol<4200){ val &= ~(3 << 5); val |= 1 << 5; } else if (charger->chgvol<4360){ val &= ~(3 << 5); val |= 1 << 6; } else val |= 3 << 5; if(charger->chgcur< 100) charger->chgcur =100; val |= (charger->chgcur - 100) / 100 ; if(charger ->chgend == 10){ val &= ~(1 << 4); } else { val |= 1 << 4; } val &= 0x7F; val |= charger->chgen << 7; if(charger->chgpretime < 30) charger->chgpretime = 30; if(charger->chgcsttime < 420) charger->chgcsttime = 420; if(charger->chgextcur < 300) charger->chgextcur = 300; tmp = ((charger->chgpretime - 30) / 10) << 6 \ | (charger->chgcsttime - 420) / 60 | \ (charger->chgexten << 2) | ((charger->chgextcur - 300) / 100 << 3); var[0] = val; var[1] = AXP19_CHARGE_CONTROL2; var[2] = tmp; axp_writes(charger->master, AXP19_CHARGE_CONTROL1,3, var); }
int axp81x_init(struct axp_charger *charger) { int ret = 0, var = 0; uint8_t val = 0; uint8_t ocv_cap[63]; int Cur_CoulombCounter,rdc; ret = axp_battery_first_init(charger); if (ret) goto err_charger_init; /* usb /ac voltage limit */ if(axp81x_config.pmu_usbvol){ axp81x_usb_ac_vol_limit(charger, CHARGE_AC, axp81x_config.pmu_usbvol); } if(axp81x_config.pmu_usbvol_pc){ axp81x_usb_ac_vol_limit(charger, CHARGE_USB_20, axp81x_config.pmu_usbvol_pc); } /* ac current limit */ if(axp81x_config.pmu_usbcur){ axp81x_usb_ac_current_limit(charger, CHARGE_AC, axp81x_config.pmu_usbcur); } else { #ifdef BPI-M3 axp81x_usb_ac_current_limit(charger, CHARGE_AC, 2500); #else axp81x_usb_ac_current_limit(charger, CHARGE_AC, 4000); #endif } #ifdef BPI-M3 #else printk("BPI-M3: set PMIC AC 4000mA\n"); axp81x_usb_ac_current_limit(charger, CHARGE_AC, 4000); #endif axp81x_chg_current_limit(axp81x_config.pmu_runtime_chgcur); /* set lowe power warning/shutdown level */ axp_write(charger->master, AXP81X_WARNING_LEVEL,((axp81x_config.pmu_battery_warning_level1-5) << 4)+axp81x_config.pmu_battery_warning_level2); ocv_cap[0] = axp81x_config.pmu_bat_para1; ocv_cap[1] = 0xC1; ocv_cap[2] = axp81x_config.pmu_bat_para2; ocv_cap[3] = 0xC2; ocv_cap[4] = axp81x_config.pmu_bat_para3; ocv_cap[5] = 0xC3; ocv_cap[6] = axp81x_config.pmu_bat_para4; ocv_cap[7] = 0xC4; ocv_cap[8] = axp81x_config.pmu_bat_para5; ocv_cap[9] = 0xC5; ocv_cap[10] = axp81x_config.pmu_bat_para6; ocv_cap[11] = 0xC6; ocv_cap[12] = axp81x_config.pmu_bat_para7; ocv_cap[13] = 0xC7; ocv_cap[14] = axp81x_config.pmu_bat_para8; ocv_cap[15] = 0xC8; ocv_cap[16] = axp81x_config.pmu_bat_para9; ocv_cap[17] = 0xC9; ocv_cap[18] = axp81x_config.pmu_bat_para10; ocv_cap[19] = 0xCA; ocv_cap[20] = axp81x_config.pmu_bat_para11; ocv_cap[21] = 0xCB; ocv_cap[22] = axp81x_config.pmu_bat_para12; ocv_cap[23] = 0xCC; ocv_cap[24] = axp81x_config.pmu_bat_para13; ocv_cap[25] = 0xCD; ocv_cap[26] = axp81x_config.pmu_bat_para14; ocv_cap[27] = 0xCE; ocv_cap[28] = axp81x_config.pmu_bat_para15; ocv_cap[29] = 0xCF; ocv_cap[30] = axp81x_config.pmu_bat_para16; ocv_cap[31] = 0xD0; ocv_cap[32] = axp81x_config.pmu_bat_para17; ocv_cap[33] = 0xD1; ocv_cap[34] = axp81x_config.pmu_bat_para18; ocv_cap[35] = 0xD2; ocv_cap[36] = axp81x_config.pmu_bat_para19; ocv_cap[37] = 0xD3; ocv_cap[38] = axp81x_config.pmu_bat_para20; ocv_cap[39] = 0xD4; ocv_cap[40] = axp81x_config.pmu_bat_para21; ocv_cap[41] = 0xD5; ocv_cap[42] = axp81x_config.pmu_bat_para22; ocv_cap[43] = 0xD6; ocv_cap[44] = axp81x_config.pmu_bat_para23; ocv_cap[45] = 0xD7; ocv_cap[46] = axp81x_config.pmu_bat_para24; ocv_cap[47] = 0xD8; ocv_cap[48] = axp81x_config.pmu_bat_para25; ocv_cap[49] = 0xD9; ocv_cap[50] = axp81x_config.pmu_bat_para26; ocv_cap[51] = 0xDA; ocv_cap[52] = axp81x_config.pmu_bat_para27; ocv_cap[53] = 0xDB; ocv_cap[54] = axp81x_config.pmu_bat_para28; ocv_cap[55] = 0xDC; ocv_cap[56] = axp81x_config.pmu_bat_para29; ocv_cap[57] = 0xDD; ocv_cap[58] = axp81x_config.pmu_bat_para30; ocv_cap[59] = 0xDE; ocv_cap[60] = axp81x_config.pmu_bat_para31; ocv_cap[61] = 0xDF; ocv_cap[62] = axp81x_config.pmu_bat_para32; axp_writes(charger->master, 0xC0,63,ocv_cap); /* pok open time set */ if(axp81x_config.pmu_pekon_time < 1000) val = 0x00; else if(axp81x_config.pmu_pekon_time < 2000){ val = 0x40; }else if(axp81x_config.pmu_pekon_time < 3000){ val = 0x80; }else { val = 0xc0; } axp_update(charger->master, AXP81X_POK_SET, val, 0xc0); var = axp81x_config.pmu_peklong_time; /* pok long time set*/ if(axp81x_config.pmu_peklong_time < 1000) var = 1000; if(axp81x_config.pmu_peklong_time > 2500) var = 2500; val = (((var - 1000) / 500) << 4); axp_update(charger->master, AXP81X_POK_SET, val, 0x30); /* pek offlevel poweroff en set*/ if(axp81x_config.pmu_pekoff_en) var = 1; else var = 0; val = (var << 3); axp_update(charger->master, AXP81X_POK_SET, val, 0x8); /*Init offlevel restart or not */ if(axp81x_config.pmu_pekoff_func) axp_set_bits(charger->master,AXP81X_POK_SET,0x04); //restart else axp_clr_bits(charger->master,AXP81X_POK_SET,0x04); //not restart if(10 > axp81x_config.pmu_pekoff_delay_time) val = 0x00; else if(20 > axp81x_config.pmu_pekoff_delay_time) val = 0x01; else if(30 > axp81x_config.pmu_pekoff_delay_time) val = 0x02; else if(40 > axp81x_config.pmu_pekoff_delay_time) val = 0x03; else if(50 > axp81x_config.pmu_pekoff_delay_time) val = 0x04; else if(60 > axp81x_config.pmu_pekoff_delay_time) val = 0x05; else if(70 > axp81x_config.pmu_pekoff_delay_time) val = 0x06; else val = 0x07; axp_write(charger->master,AXP81X_POK_DELAY_SET,val); /* pek delay set */ if (axp81x_config.pmu_pwrok_time < 32) val = ((axp81x_config.pmu_pwrok_time / 8) - 1); else val = ((axp81x_config.pmu_pwrok_time / 32) + 1); axp_update(charger->master, AXP81X_OFF_CTL, val, 0x3); //axp_read(charger->master,AXP81X_DCDC_MONITOR,&val); //if(axp81x_config.pmu_pwrok_shutdown_en) // val |= 0x40; //axp_write(charger->master,AXP81X_DCDC_MONITOR,val); if(axp81x_config.pmu_reset_shutdown_en) axp_set_bits(charger->master,AXP81X_HOTOVER_CTL,0x01); //restart shutdown ldo/dcdc /* pek offlevel time set */ if(axp81x_config.pmu_pekoff_time < 4000) var = 4000; if(axp81x_config.pmu_pekoff_time > 10000) var =10000; var = (axp81x_config.pmu_pekoff_time - 4000) / 2000 ; val = var ; axp_update(charger->master, AXP81X_POK_SET, val, 0x3); /*Init 16's Reset PMU en */ if(axp81x_config.pmu_reset) axp_set_bits(charger->master,0x8F,0x08); //enable else axp_clr_bits(charger->master,0x8F,0x08); //disable /*Init IRQ wakeup en*/ if(axp81x_config.pmu_IRQ_wakeup) axp_set_bits(charger->master,0x8F,0x80); //enable else axp_clr_bits(charger->master,0x8F,0x80); //disable /*Init N_VBUSEN status*/ if(axp81x_config.pmu_vbusen_func) axp_set_bits(charger->master,0x8F,0x10); //output else axp_clr_bits(charger->master,0x8F,0x10); //input /*Init InShort status*/ if(axp81x_config.pmu_inshort) axp_set_bits(charger->master,0x8F,0x60); //InShort else axp_clr_bits(charger->master,0x8F,0x60); //auto detect /*Init CHGLED function*/ if(axp81x_config.pmu_chgled_func) axp_set_bits(charger->master,0x32,0x08); //control by charger else axp_clr_bits(charger->master,0x32,0x08); //drive MOTO /*set CHGLED Indication Type*/ if(axp81x_config.pmu_chgled_type) axp_set_bits(charger->master,0x34,0x10); //Type B else axp_clr_bits(charger->master,0x34,0x10); //Type A /*Init PMU Over Temperature protection*/ if(axp81x_config.pmu_hot_shutdowm) axp_set_bits(charger->master,0x8f,0x04); //enable else axp_clr_bits(charger->master,0x8f,0x04); //disable /*Init battery capacity correct function*/ if(axp81x_config.pmu_batt_cap_correct) axp_set_bits(charger->master,0xb8,0x20); //enable else axp_clr_bits(charger->master,0xb8,0x20); //disable /* Init battery regulator enable or not when charge finish*/ if(axp81x_config.pmu_bat_regu_en) axp_set_bits(charger->master,0x34,0x20); //enable else axp_clr_bits(charger->master,0x34,0x20); //disable if(!axp81x_config.pmu_batdeten) axp_clr_bits(charger->master,AXP81X_PDBC,0x40); else axp_set_bits(charger->master,AXP81X_PDBC,0x40); /* RDC initial */ axp_read(charger->master, AXP81X_RDC0,&val); if((axp81x_config.pmu_battery_rdc) && (!(val & 0x40))){ rdc = (axp81x_config.pmu_battery_rdc * 10000 + 5371) / 10742; axp_write(charger->master, AXP81X_RDC0, ((rdc >> 8) & 0x1F)|0x80); axp_write(charger->master,AXP81X_RDC1,rdc & 0x00FF); }
int axp202_writes(int addr, unsigned char *buf, int count) { return axp_writes(addr, count, buf); }