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;
Esempio n. 3
0
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;
}
Esempio n. 4
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);
}