示例#1
0
static inline void axp_read_adc(struct axp_charger *charger,
  struct axp_adc_res *adc)
{
	uint8_t tmp[8];
#ifdef CONFIG_AW_AXP19
	axp_reads(charger->master,AXP_VACH_RES,8,tmp);
	adc->vac_res = ((uint16_t) tmp[0] << 8 )| tmp[1];
	adc->iac_res = ((uint16_t) tmp[2] << 8 )| tmp[3];
	adc->vusb_res = ((uint16_t) tmp[4] << 8 )| tmp[5];
	adc->iusb_res = ((uint16_t) tmp[6] << 8 )| tmp[7];
#else
	adc->vac_res = 0;
	adc->iac_res = 0;
	adc->vusb_res = 0;
	adc->iusb_res = 0;
	axp_reads(charger->master,AXP_OCVBATH_RES,2,tmp);
	adc->ocvbat_res = ((uint16_t) tmp[0] << 8 )| tmp[1];
	axp_reads(charger->master,AXP_VTS_RES,2,tmp);
	adc->ts_res = ((uint16_t) tmp[0] << 8 )| tmp[1];
#endif

	axp_reads(charger->master,AXP_VBATH_RES,6,tmp);
	adc->vbat_res = ((uint16_t) tmp[0] << 8 )| tmp[1];
	adc->ichar_res = ((uint16_t) tmp[2] << 8 )| tmp[3];
	adc->idischar_res = ((uint16_t) tmp[4] << 8 )| tmp[5];
}
static inline void axp_read_adc(struct axp_charger *charger,
	struct axp_adc_res *adc)
{
   uint8_t tmp[8];

   axp_reads(charger->master,AXP19_VACH_RES,8,tmp);
	 adc->vac_res = ((uint16_t) tmp[0] << 8 )| tmp[1];
	 adc->iac_res = ((uint16_t) tmp[2] << 8 )| tmp[3];
	 adc->vusb_res = ((uint16_t) tmp[4] << 8 )| tmp[5];
	 adc->iusb_res = ((uint16_t) tmp[6] << 8 )| tmp[7];
 	 axp_reads(charger->master,AXP19_VBATH_RES,6,tmp);
	 adc->vbat_res = ((uint16_t) tmp[0] << 8 )| tmp[1];
	 adc->ichar_res = ((uint16_t) tmp[2] << 8 )| tmp[3];
	 adc->idischar_res = ((uint16_t) tmp[4] << 8 )| tmp[5];
}
示例#3
0
文件: axp20-sply.c 项目: xtra72/s805
static inline void axp_read_adc(struct axp_adc_res *adc)
{
	uint8_t tmp[8];
	axp_reads(AXP20_VACH_RES,8,tmp);
	adc->vac_res = ((uint16_t) tmp[0] << 4 )| (tmp[1] & 0x0f);
	adc->iac_res = ((uint16_t) tmp[2] << 4 )| (tmp[3] & 0x0f);
	adc->vusb_res = ((uint16_t) tmp[4] << 4 )| (tmp[5] & 0x0f);
	adc->iusb_res = ((uint16_t) tmp[6] << 4 )| (tmp[7] & 0x0f);
	axp_reads(AXP20_VBATH_RES,6,tmp);
	adc->vbat_res = ((uint16_t) tmp[0] << 4 )| (tmp[1] & 0x0f);

	adc->ichar_res = ((uint16_t) tmp[2] << 4 )| (tmp[3] & 0x0f);

	adc->idischar_res = ((uint16_t) tmp[4] << 5 )| (tmp[5] & 0x1f);
}
示例#4
0
void axp_charger_update_state(struct axp_charger *charger)
{
	uint8_t val[2];
	uint16_t tmp;

	axp_reads(charger->master,AXP_CHARGE_STATUS,2,val);
	tmp = (val[1] << 8 )+ val[0];
	spin_lock(&charger->charger_lock);
	charger->is_on = (val[1] & AXP_IN_CHARGE) ? 1 : 0;
	charger->fault = val[1];
	charger->bat_det = (tmp & AXP_STATUS_BATEN)?1:0;
	charger->ac_det = (tmp & AXP_STATUS_ACEN)?1:0;
	charger->usb_det = (tmp & AXP_STATUS_USBEN)?1:0;
	charger->ext_valid = (tmp & (AXP_STATUS_USBVA |AXP_STATUS_ACVA))?1:0;
	charger->in_short = (tmp& AXP_STATUS_ACUSBSH)?1:0;
	if(!charger->in_short) {
		charger->ac_valid = (tmp & AXP_STATUS_ACVA)?1:0;
	}
	charger->bat_current_direction = (tmp & AXP_STATUS_BATCURDIR)?1:0;
	charger->in_short = (tmp& AXP_STATUS_ACUSBSH)?1:0;
	charger->batery_active = (tmp & AXP_STATUS_BATINACT)?1:0;
	charger->int_over_temp = (tmp & AXP_STATUS_ICTEMOV)?1:0;
	spin_unlock(&charger->charger_lock);
	axp_read(charger->master,AXP_CHARGE_CONTROL1,val);
	spin_lock(&charger->charger_lock);
	charger->charge_on = ((val[0] >> 7) & 0x01);
	spin_unlock(&charger->charger_lock);
}
示例#5
0
void axp_charger_update(struct axp_charger *charger, const struct axp_config_info *axp_config)
{
	uint16_t tmp;
	uint8_t val[2];
#ifdef CONFIG_AW_AXP19
#else
	int bat_temp_mv;
#endif

	charger->adc = &adc;
	axp_read_adc(charger, &adc);
	tmp = charger->adc->vbat_res;

	spin_lock(&charger->charger_lock);
	charger->vbat = axp_vbat_to_mV(tmp);
	spin_unlock(&charger->charger_lock);

	//tmp = charger->adc->ichar_res + charger->adc->idischar_res;
	spin_lock(&charger->charger_lock);
	charger->ibat = ABS(axp_icharge_to_mA(charger->adc->ichar_res)-axp_ibat_to_mA(charger->adc->idischar_res));
	tmp = 00;///qin
	charger->vac = axp_vdc_to_mV(tmp);
	tmp = 00;
	charger->iac = axp_iac_to_mA(tmp);
	tmp = 00;
	charger->vusb = axp_vdc_to_mV(tmp);
	tmp = 00;
	charger->iusb = axp_iusb_to_mA(tmp);
	spin_unlock(&charger->charger_lock);

	axp_reads(charger->master,AXP_INTTEMP,2,val);
	//DBG_PSY_MSG("TEMPERATURE:val1=0x%x,val2=0x%x\n",val[1],val[0]);
	tmp = (val[0] << 4 ) + (val[1] & 0x0F);

#ifdef CONFIG_AW_AXP19
	spin_lock(&charger->charger_lock);
	charger->ic_temp = (int) ((tmp - 1447)/10);
	charger->disvbat =  charger->vbat;
	charger->disibat =  axp_ibat_to_mA(charger->adc->idischar_res);
	spin_unlock(&charger->charger_lock);
#else
	spin_lock(&charger->charger_lock);
	charger->ic_temp = (int) tmp *1063/10000  - 2667/10;
	charger->disvbat =  charger->vbat;
	charger->disibat =  axp_ibat_to_mA(charger->adc->idischar_res);
	spin_unlock(&charger->charger_lock);

	tmp = charger->adc->ocvbat_res;
	spin_lock(&charger->charger_lock);
	charger->ocv = axp_ocvbat_to_mV(tmp);
	spin_unlock(&charger->charger_lock);
	
	tmp = charger->adc->ts_res;
	bat_temp_mv = axp_vts_to_mV(tmp);
	spin_lock(&charger->charger_lock);
	charger->bat_temp = axp_vts_to_temp(bat_temp_mv, axp_config);
	spin_unlock(&charger->charger_lock);
#endif
}
示例#6
0
文件: axp20-sply.c 项目: xtra72/s805
/* 得到开路电压 */
static int axp_get_ocv(void)
{
	int battery_ocv;
	uint8_t v[2];
	axp_reads(AXP_OCV_BUFFER0, 2, v);
	battery_ocv = ((v[0] << 4) + (v[1] & 0x0f)) * 11 /10;
	DBG_PSY_MSG("battery_ocv = %d\n", battery_ocv);
	return battery_ocv;
}
示例#7
0
文件: axp20-sply.c 项目: xtra72/s805
int axp_charger_get_charging_status(void)
{
	axp_reads(0x00, 2, (uint8_t *)&status_reg);
	if (status_reg & (1 << 2)) {
		return 1;
	} else {
		return 0;
	}
}
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;
示例#9
0
文件: axp20-sply.c 项目: xtra72/s805
int axp_update_calibrate(int charge)
{
    uint8_t val[2];
    struct axp_adc_res axp_adc;
    uint32_t tmp0, tmp1;

    coulomb = axp_get_coulomb(); 
    ocv = axp_get_ocv(); 
    axp_read_adc(&axp_adc);
    ibat = ABS(axp_ibat_to_mA(axp_adc.ichar_res)-axp_ibat_to_mA(axp_adc.idischar_res)); 
    tmp0 = axp_adc.vbat_res;
    vbat_i = (tmp0 * 1100) / 1000;

    axp_reads(0xBA, 2, val);
    tmp1 = ((val[0] & 0x1F) << 8) | val[1];
    rdc_r = (tmp1  * 10742) / 10000;
    if (charge) {
        return axp_calculate_rdc();
    }
    return 0;
}
static void axp_charger_update_state(struct axp_charger *charger)
{
	uint8_t val[2];
	uint16_t tmp;

	axp_reads(charger->master,AXP19_CHARGE_STATUS,2,val);
	tmp = (val[1] << 8 )+ val[0];
	//printk("tmp = 0x%x\n",tmp);
	charger->is_on = (val[1] & AXP19_IN_CHARGE) ? 1 : 0;
	charger->fault = val[1];
	charger->bat_det = (tmp & AXP19_STATUS_BATEN)?1:0;
	charger->ac_det = (tmp & AXP19_STATUS_ACEN)?1:0;
	charger->usb_det = (tmp & AXP19_STATUS_USBEN)?1:0;
	charger->usb_valid = (tmp & AXP19_STATUS_USBVA)?1:0;
	charger->ac_valid = (tmp & AXP19_STATUS_ACVA)?1:0;
	charger->ext_valid = charger->ac_valid | charger->usb_valid;
	charger->bat_current_direction = (tmp & AXP19_STATUS_BATCURDIR)?1:0;
	charger->in_short = (tmp& AXP19_STATUS_ACUSBSH)?1:0;
	charger->batery_active = (tmp & AXP19_STATUS_BATINACT)?1:0;
	charger->low_charge_current = (tmp & AXP19_STATUS_CHACURLOEXP)?1:0;
	charger->int_over_temp = (tmp & AXP19_STATUS_ICTEMOV)?1:0;
}
示例#11
0
文件: axp20-sply.c 项目: xtra72/s805
static int axp_get_coulomb(void)
{
	uint8_t  temp[8];
	uint64_t  rValue1,rValue2,rValue;
	uint32_t Cur_CoulombCounter_tmp,m;

	axp_reads(POWER20_BAT_CHGCOULOMB3,8, temp);
	rValue1 = ((temp[0] << 24) + (temp[1] << 16) + (temp[2] << 8) + temp[3]);
	rValue2 = ((temp[4] << 24) + (temp[5] << 16) + (temp[6] << 8) + temp[7]);

	DBG_PSY_MSG("%s->%d -     CHARGINGOULB:[0]=0x%x,[1]=0x%x,[2]=0x%x,[3]=0x%x\n",__FUNCTION__,__LINE__,temp[0],temp[1],temp[2],temp[3]);
	DBG_PSY_MSG("%s->%d - DISCHARGINGCLOUB:[4]=0x%x,[5]=0x%x,[6]=0x%x,[7]=0x%x\n",__FUNCTION__,__LINE__,temp[4],temp[5],temp[6],temp[7]);

	rValue = (ABS(rValue1 - rValue2)) * 4369;
	m = axp_get_freq() * 480;
	do_div(rValue,m);
	if(rValue1 >= rValue2)
		Cur_CoulombCounter_tmp = (int)rValue;
	else
		Cur_CoulombCounter_tmp = (int)(0 - rValue);
	
	DBG_PSY_MSG("Cur_CoulombCounter_tmp = %d\n",Cur_CoulombCounter_tmp);
	return Cur_CoulombCounter_tmp;	//unit mAh
}
示例#12
0
文件: axp20-sply.c 项目: xtra72/s805
int axp202_reads(int addr, unsigned char *buf, int count)
{
    return axp_reads(addr, count, buf);    
}
示例#13
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);
}