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 int axp_get_rdc(struct axp_charger *charger) { uint8_t val[2]; unsigned int i,temp,pre_temp; int averPreVol = 0, averPreCur = 0,averNextVol = 0,averNextCur = 0; axp_reads(charger->master,AXP19_DATA_BUFFER2,2,val); pre_temp = (((val[0] & 0x07) << 8 ) + val[1]); if(!charger->bat_det){ return pre_temp; } if( charger->ext_valid){ for(i = 0; i< AXP19_RDC_COUNT; i++){ axp_charger_update(charger); averPreVol += charger->vbat; averPreCur += charger->ibat; msleep(200); } averPreVol /= AXP19_RDC_COUNT; averPreCur /= AXP19_RDC_COUNT; axp_clr_bits(charger->master,AXP20_CHARGE_CONTROL1,0x80); msleep(3000); for(i = 0; i< AXP19_RDC_COUNT; i++){ axp_charger_update(charger); averNextVol += charger->vbat; averNextCur += charger->ibat; msleep(200); } averNextVol /= AXP19_RDC_COUNT; averNextCur /= AXP19_RDC_COUNT; axp_set_bits(charger->master,AXP20_CHARGE_CONTROL1,0x80); if(ABS(averPreCur - averNextCur) > 200){ temp = 1000 * ABS(averPreVol - averNextVol) / ABS(averPreCur - averNextCur); if((temp < 5) || (temp > 5000)){ return pre_temp; } else { temp += pre_temp; temp >>= 1; axp_write(charger->master,AXP19_DATA_BUFFER2,((temp & 0xFF00) | 0x800) >> 8); axp_write(charger->master,AXP19_DATA_BUFFER3,temp & 0x00FF); return temp; } } else { return pre_temp;
static int axp81x_resume(struct platform_device *dev) { struct axp_charger *charger = platform_get_drvdata(dev); int pre_rest_vol; uint8_t val,tmp; axp_enable_irq(charger); pre_rest_vol = charger->rest_vol; axp_read(charger->master, AXP81X_CAP,&val); charger->rest_vol = val & 0x7f; if(charger->rest_vol - pre_rest_vol){ printk("battery vol change: %d->%d \n", pre_rest_vol, charger->rest_vol); pre_rest_vol = charger->rest_vol; axp_write(charger->master,AXP81X_DATA_BUFFER1,charger->rest_vol | 0x80); } #if defined (CONFIG_AXP_CHGCHANGE) if(axp81x_config.pmu_runtime_chgcur == 0) axp_clr_bits(charger->master,AXP81X_CHARGE_CONTROL1,0x80); else axp_set_bits(charger->master,AXP81X_CHARGE_CONTROL1,0x80); printk("pmu_runtime_chgcur = %d\n", axp81x_config.pmu_runtime_chgcur); if(axp81x_config.pmu_runtime_chgcur >= 300000 && axp81x_config.pmu_runtime_chgcur <= 2550000){ tmp = (axp81x_config.pmu_runtime_chgcur -200001)/150000; charger->chgcur = tmp *150000 + 300000; axp_update(charger->master, AXP81X_CHARGE_CONTROL1, tmp,0x0F); }else if(axp81x_config.pmu_runtime_chgcur < 300000){ axp_clr_bits(axp_charger->master, AXP81X_CHARGE_CONTROL1,0x0F); }else{ axp_set_bits(axp_charger->master, AXP81X_CHARGE_CONTROL1,0x0F); } #endif charger->disvbat = 0; charger->disibat = 0; axp_charger_update_state(charger); axp_charger_update(charger, &axp81x_config); power_supply_changed(&charger->batt); power_supply_changed(&charger->ac); power_supply_changed(&charger->usb); schedule_delayed_work(&charger->work, charger->interval); return 0; }
static void axp_charging_monitor(struct work_struct *work) { struct axp_charger *charger; uint8_t val,temp_val[4]; int pre_rest_vol,pre_bat_curr_dir; unsigned long power_sply = 0; charger = container_of(work, struct axp_charger, work.work); pre_rest_vol = charger->rest_vol; pre_bat_curr_dir = charger->bat_current_direction; axp_charger_update_state(charger); axp_charger_update(charger, &axp81x_config); axp_read(charger->master, AXP81X_CAP,&val); spin_lock(&charger->charger_lock); charger->rest_vol = (int) (val & 0x7F); spin_unlock(&charger->charger_lock); if (axp_debug & DEBUG_SPLY) { DBG_PSY_MSG(DEBUG_SPLY, "charger->ic_temp = %d\n",charger->ic_temp); DBG_PSY_MSG(DEBUG_SPLY, "charger->bat_temp = %d\n",charger->bat_temp); DBG_PSY_MSG(DEBUG_SPLY, "charger->vbat = %d\n",charger->vbat); DBG_PSY_MSG(DEBUG_SPLY, "charger->ibat = %d\n",charger->ibat); DBG_PSY_MSG(DEBUG_SPLY, "charger->ocv = %d\n",charger->ocv); DBG_PSY_MSG(DEBUG_SPLY, "charger->disvbat = %d\n",charger->disvbat); DBG_PSY_MSG(DEBUG_SPLY, "charger->disibat = %d\n",charger->disibat); power_sply = charger->disvbat * charger->disibat; if (0 != power_sply) power_sply = power_sply/1000; DBG_PSY_MSG(DEBUG_SPLY, "power_sply = %ld mW\n",power_sply); DBG_PSY_MSG(DEBUG_SPLY, "charger->rest_vol = %d\n",charger->rest_vol); axp_reads(charger->master,0xba,2,temp_val); DBG_PSY_MSG(DEBUG_SPLY, "Axp Rdc = %d\n",(((temp_val[0] & 0x1f) <<8) + temp_val[1])*10742/10000); axp_reads(charger->master,0xe0,2,temp_val); DBG_PSY_MSG(DEBUG_SPLY, "Axp batt_max_cap = %d\n",(((temp_val[0] & 0x7f) <<8) + temp_val[1])*1456/1000); axp_reads(charger->master,0xe2,2,temp_val); DBG_PSY_MSG(DEBUG_SPLY, "Axp coulumb_counter = %d\n",(((temp_val[0] & 0x7f) <<8) + temp_val[1])*1456/1000); axp_read(charger->master,0xb8,temp_val); DBG_PSY_MSG(DEBUG_SPLY, "Axp REG_B8 = %x\n",temp_val[0]); axp_reads(charger->master,0xe4,2,temp_val); DBG_PSY_MSG(DEBUG_SPLY, "Axp OCV_percentage = %d\n",(temp_val[0] & 0x7f)); DBG_PSY_MSG(DEBUG_SPLY, "Axp Coulumb_percentage = %d\n",(temp_val[1] & 0x7f)); DBG_PSY_MSG(DEBUG_SPLY, "charger->is_on = %d\n",charger->is_on); DBG_PSY_MSG(DEBUG_SPLY, "charger->bat_current_direction = %d\n",charger->bat_current_direction); DBG_PSY_MSG(DEBUG_SPLY, "charger->charge_on = %d\n",charger->charge_on); DBG_PSY_MSG(DEBUG_SPLY, "charger->ext_valid = %d\n",charger->ext_valid); DBG_PSY_MSG(DEBUG_SPLY, "pmu_runtime_chgcur = %d\n",axp81x_config.pmu_runtime_chgcur); DBG_PSY_MSG(DEBUG_SPLY, "pmu_earlysuspend_chgcur = %d\n",axp81x_config.pmu_earlysuspend_chgcur); DBG_PSY_MSG(DEBUG_SPLY, "pmu_suspend_chgcur = %d\n",axp81x_config.pmu_suspend_chgcur); DBG_PSY_MSG(DEBUG_SPLY, "pmu_shutdown_chgcur = %d\n\n\n",axp81x_config.pmu_shutdown_chgcur); } /* if battery volume changed, inform uevent */ if((charger->rest_vol - pre_rest_vol) || (charger->bat_current_direction != pre_bat_curr_dir)){ axp_reads(charger->master,0xe2,2,temp_val); axp_reads(charger->master,0xe4,2,(temp_val+2)); DBG_PSY_MSG(DEBUG_SPLY, "battery vol change: %d->%d \n", pre_rest_vol, charger->rest_vol); DBG_PSY_MSG(DEBUG_SPLY, "for test %d %d %d %d %d %d\n",charger->vbat,charger->ocv,charger->ibat, (temp_val[2] & 0x7f),(temp_val[3] & 0x7f),(((temp_val[0] & 0x7f) <<8) + temp_val[1])*1456/1000); pre_rest_vol = charger->rest_vol; power_supply_changed(&charger->batt); } /* reschedule for the next time */ schedule_delayed_work(&charger->work, charger->interval); }