/*
 *di->cin_limit:      set usb input limit current(100,150,500,800,900,1500)
 *di->enable_iterm:   Enable charge current termination
 *ENABLE_STAT_PIN: Enable STAT pin output to show charge status
 * di->enable_ce=0 : Charger enabled
 */
static void bq2416x_config_control_reg(struct bq2416x_device_info *di)
{
	u8 Iin_limit;

	if (di->cin_limit <= 100)
		Iin_limit = 0;
	else if (di->cin_limit > 100 && di->cin_limit <= 150)
		Iin_limit = 1;
	else if (di->cin_limit > 150 && di->cin_limit <= 500)
		Iin_limit = 2;
	else if (di->cin_limit > 500 && di->cin_limit <= 800)
		Iin_limit = 3;
	else if (di->cin_limit > 800 && di->cin_limit <= 900)
		Iin_limit = 4;	
	else if (di->cin_limit > 900 && di->cin_limit <= 1500)
		Iin_limit = 5;
	else
		Iin_limit = 6;

	di->control_reg = ((Iin_limit << INPUT_CURRENT_LIMIT_SHIFT)
				| (di->enable_iterm << ENABLE_ITERM_SHIFT) | ENABLE_STAT_PIN 
				|( di->enable_ce << 1) |di->hz_mode);
	bq2416x_write_byte(di, di->control_reg, REG_CONTROL_REGISTER);
	return;
}
/*
 *config TMR_RST function to reset the watchdog
 * 
 */
static void bq2416x_config_usb_supply_sel_reg(struct bq2416x_device_info *di) 
{
	//di->usb_supply_sel_reg = (TIMER_RST | ENABLE_USB_SUPPLY_SEL);
	di->usb_supply_sel_reg = (TIMER_RST);
	bq2416x_write_byte(di, di->usb_supply_sel_reg, REG_STATUS_CONTROL);
	return;
}
/*
 * set Battery charger current(550 ~1500mA) and Termination current(50~350mA)
 *
 */
static void bq2416x_config_current_reg(struct bq2416x_device_info *di)
{
	unsigned int currentmA = 0;
	unsigned int term_currentmA = 0;
	u8 Vichrg = 0;
	u8 shift = 0;
	u8 Viterm = 0;

	currentmA = di->currentmA;
	term_currentmA = di->term_currentmA;

	if (currentmA < ICHG_MIN_550)
		currentmA = ICHG_MIN_550;
  
	if ((di->bqchip_version & BQ24161)) {
		shift = BQ2416x_CURRENT_SHIFT;
		if (currentmA > ICHG_1500)
			currentmA = ICHG_1500;
	}

	if (term_currentmA < ITERM_MIN_50)
		term_currentmA = ITERM_MIN_50;

	if (term_currentmA > ITERM_MAX_400)
		term_currentmA = ITERM_MAX_400;

	Vichrg = (currentmA - ICHG_MIN_550)/ICHG_STEP_75;

	Viterm = (term_currentmA - ITERM_MIN_50)/ITERM_STEP_50;

	di->current_reg05 = (Vichrg << shift | Viterm);
	bq2416x_write_byte(di, di->current_reg05, REG_BATTERY_CURRENT_REG05);
	
	return;
}
/*
 *di->cin_limit:      set usb input limit current(100,150,500,800,900,1500)
 *di->enable_iterm:   Enable charge current termination
 *ENABLE_STAT_PIN: Enable STAT pin output to show charge status
 * di->enable_ce=0 : Charger enabled
 */
static void bq2416x_config_control_reg(struct bq2416x_device_info *di)
{
	u8 Iin_limit;

	if (di->cin_limit <= IINLIM_100)
		Iin_limit = 0;
	else if (di->cin_limit > IINLIM_100 && di->cin_limit <= IINLIM_150)
		Iin_limit = 1;
	else if (di->cin_limit > IINLIM_150 && di->cin_limit <= IINLIM_500)
		Iin_limit = 2;
	else if (di->cin_limit > IINLIM_500 && di->cin_limit <= IINLIM_800)
		Iin_limit = 3;
	else if (di->cin_limit > IINLIM_800 && di->cin_limit <= IINLIM_900)
		Iin_limit = 4;	
	else if (di->cin_limit > IINLIM_900 && di->cin_limit <= IINLIM_1500)
		Iin_limit = 5;
	else
		Iin_limit = 6;

	di->control_reg02 = ((Iin_limit << BQ2416x_INPUT_CURRENT_LIMIT_SHIFT)
				| (di->enable_iterm << BQ2416x_EN_ITERM_SHIFT) | (ENABLE_STAT) 
				|( di->enable_ce << BQ2416x_EN_CE_SHIFT) |di->hz_mode);
	bq2416x_write_byte(di, di->control_reg02, REG_CONTROL_REGISTER_REG02);
	return;
}
Exemplo n.º 5
0
static void
bq2416x_charger_update_status(struct bq2416x_device_info *di)
{
	u8 read_reg[8] = {0};

	timer_fault = 0;
	bq2416x_read_block(di, &read_reg[0], 0, 8); 

	if ((read_reg[0] & 0x70) == 0x50)   
		dev_dbg(di->dev, "CHARGE DONE\n");

	if ((read_reg[0] & 0x7) == 0x4) 
		timer_fault = 1;
     
	if (read_reg[0] & 0x7) {
		di->cfg_params = 1;
		dev_err(di->dev, "CHARGER STATUS = %x\n", read_reg[0]);
	}

    if ((read_reg[1] & 0x6) == 0x2) {
        di->hz_mode = 1;
        bq2416x_config_control_reg(di);
        bq2416x_write_byte(di, di->voltage_reg, REG_BATTERY_VOLTAGE);
        dev_err(di->dev, "battery ovp = %x,%x\n", read_reg[1],read_reg[3]);
        msleep(700);
        di->hz_mode = 0;
        bq2416x_config_control_reg(di);
    }

	if (is_bq27510_battery_exist(g_battery_measure_by_bq27510_device)){
		bq2416x__charge_status(di);
	}

	if ((timer_fault == 1) || (di->cfg_params == 1)) {
		bq2416x_write_byte(di, di->control_reg, REG_CONTROL_REGISTER);
		bq2416x_write_byte(di, di->voltage_reg, REG_BATTERY_VOLTAGE);
		bq2416x_write_byte(di, di->current_reg, REG_BATTERY_CURRENT);
		bq2416x_write_byte(di, di->dppm_reg, REG_DPPM_VOLTAGE);
		bq2416x_config_safety_reg(di); 
		di->cfg_params = 0;
	}

	/* reset 32 second timer */
	bq2416x_config_status_reg(di);

	return;
}
/*
 * enable TMR_PIN and set Safety Timer Time Limit = 9h
 *
 */
static void bq2416x_config_safety_reg(struct bq2416x_device_info *di)
{

	di->safety_timer_reg07 =  TMR_EN | di->safety_timer | di->enable_low_chg; 

	bq2416x_write_byte(di, di->safety_timer_reg07, REG_SAFETY_TIMER_REG07);
	return;
}
/*
 * enable TMR_PIN and set Safety Timer Time Limit = 6h
 *
 */
static void bq2416x_config_safety_reg(struct bq2416x_device_info *di)
{
	di->tmr_ts_reg = (ENABLE_TMR_PIN |TMR_X_6)  | di->enable_low_chg; //safety time = 6h and ENABLE_LOW_CHG

	//di->tmr_ts_reg = (ENABLE_TMR_PIN); //safety time = 27 min
	bq2416x_write_byte(di, di->tmr_ts_reg, REG_SAFETY_TIMER);
	return;
}
Exemplo n.º 8
0
/*di->enable_ce = 0,charger enable and display charging status
  di->enable_ce = 1 or USB supply fault,charger disable and display not charging status*/
static void
bq2416x__charge_status(struct bq2416x_device_info *di)
{
	long int events=BQ2416x_START_CHARGING;
	u8 read_reg[8] = {0};
    int battery_capacity = 0;

	bq2416x_read_block(di, &read_reg[0], 0, 2);

	if((read_reg[1] & BQ2416x_FAULT_VBUS_VUVLO) == BQ2416x_FAULT_VBUS_OVP){
		dev_err(di->dev, " POWER_SUPPLY_OVERVOLTAGE = %x\n",read_reg[1]);
		events = POWER_SUPPLY_OVERVOLTAGE;
		blocking_notifier_call_chain(&notifier_list, events, NULL);
		return;
	}

	if ((read_reg[0] & BQ2416x_VUSB_FAULT) == BQ2416x_CHARGING_FROM_USB){
				events = BQ2416x_START_CHARGING;
	}
	else if((di->enable_ce == DISABLE_CE)
		|| ((read_reg[0] & POWER_SUPPLY_STATE_FAULT) == POWER_SUPPLY_STATE_FAULT)){
		dev_err(di->dev, " BQ2416x_NOT_CHARGING \n");
		events = BQ2416x_NOT_CHARGING;
	}

	else if((read_reg[0] & BQ2416x_VUSB_FAULT) == BQ2416x_CHARGE_DONE){
        battery_capacity = bq27510_battery_capacity(g_battery_measure_by_bq27510_device);
        if((!is_bq27510_battery_full(g_battery_measure_by_bq27510_device))||(battery_capacity !=100)){
            dev_info(di->dev, "charge_done_battery_capacity=%d\n",battery_capacity);
            di->hz_mode = 1; /*enable bq2416x charger high impedance mode*/
            bq2416x_write_byte(di, di->control_reg | di->hz_mode, REG_CONTROL_REGISTER);
            di->hz_mode = 0; /*disable bq2416x charger high impedance mode*/
            msleep(700);
            bq2416x_config_control_reg(di);
            events = BQ2416x_START_CHARGING;
        } else{
            events = BQ2416x_CHARGE_DONE;
       }
     }
	else{
	     events=BQ2416x_START_CHARGING;
		dev_dbg(di->dev, "BQ2416x_START_CHARGING !\n");
	}
	if(di->charger_source == POWER_SUPPLY_TYPE_BATTERY){
		return;
	}
	blocking_notifier_call_chain(&notifier_list, events, NULL);
}
/*
 * set USB input dppm voltage between 4.2V and 4.76V 
 *
 */
static void bq2416x_config_dppm_voltage_reg(struct bq2416x_device_info *di,
	                             unsigned int dppm_voltagemV) 
{
      u8 Vmreg;

	if (dppm_voltagemV < VINDPM_MIN_4200)
		dppm_voltagemV = VINDPM_MIN_4200;
	else if (dppm_voltagemV > VINDPM_MAX_4760)
		dppm_voltagemV = VINDPM_MAX_4760;
	
	Vmreg = (dppm_voltagemV - VINDPM_MIN_4200)/VINDPM_STEP_80;
	
	di->dppm_reg06 =(Vmreg << BQ2416x_USB_INPUT_DPPM_SHIFT);
	bq2416x_write_byte(di, di->dppm_reg06, REG_DPPM_VOLTAGE_REG06);
	return;
}
void bq2416x_open_inner_fet(struct bq2416x_device_info *di)
{
    	u8 en_nobatop = 0;
		
		bq2416x_read_byte(di, &en_nobatop, REG_BATTERY_AND_SUPPLY_STATUS);
       if(g_battery_measure_by_bq27510_device &&
          is_bq27510_battery_exist(g_battery_measure_by_bq27510_device) ){
        	di->enable_iterm = ENABLE_ITERM;
        	en_nobatop = en_nobatop & (~EN_NOBATOP);
        }else {
        	di->enable_iterm = DISABLE_ITERM;
        	en_nobatop = en_nobatop | EN_NOBATOP;
        }
	bq2416x_config_control_reg(di);
	bq2416x_write_byte(di, en_nobatop, REG_BATTERY_AND_SUPPLY_STATUS);
}
/*
 * set Battery Regulation Voltage between 3.5V and 4.44V
 *
 */
static void bq2416x_config_voltage_reg(struct bq2416x_device_info *di)
{
	unsigned int voltagemV;
	u8 Voreg;

	voltagemV = di->voltagemV;
	if (voltagemV < 3500)
		voltagemV = 3500;
	else if (voltagemV > 4440)
		voltagemV = 4440;

	Voreg = (voltagemV - 3500)/20;
	di->voltage_reg = (Voreg << VOLTAGE_SHIFT);
	bq2416x_write_byte(di, di->voltage_reg, REG_BATTERY_VOLTAGE);
	return;
}
/*
 * set Battery Regulation Voltage between 3.5V and 4.44V
 *
 */
static void bq2416x_config_voltage_reg(struct bq2416x_device_info *di)
{
	unsigned int voltagemV;
	u8 Voreg;

	voltagemV = di->voltagemV;
	if (voltagemV < VCHARGE_MIN_3500)
		voltagemV = VCHARGE_MIN_3500;
	else if (voltagemV > VCHARGE_MAX_4440)
		voltagemV = VCHARGE_MAX_4440;

	Voreg = (voltagemV - VCHARGE_MIN_3500)/VCHARGE_STEP_20;

	di->voltage_reg03 = (Voreg << BQ2416x_VCHARGE_SHIFT);
	bq2416x_write_byte(di, di->voltage_reg03, REG_BATTERY_VOLTAGE_REG03);
	return;
}
/*
 * set USB input dppm voltage between 4.2V and 4.76V 
 *
 */
static void bq2416x_config_dppm_voltage_reg(struct bq2416x_device_info *di,
	                             unsigned int dppm_voltagemV) 
{
      u8 Vmreg;

	if (dppm_voltagemV < 4200)
		dppm_voltagemV = 4200;
	else if (dppm_voltagemV > 4760)
		dppm_voltagemV = 4760;
	
	Vmreg = (dppm_voltagemV - 4200)/80;
	
	di->dppm_reg =(Vmreg << USB_INPUT_DPPM_SHIFT);
	bq2416x_write_byte(di, di->dppm_reg,
					REG_DPPM_VOLTAGE);
	return;
}
static void bq2416x_open_inner_fet(struct bq2416x_device_info *di)
{
    u8 en_nobatop = 0;
		
    bq2416x_read_byte(di, &en_nobatop, REG_BATTERY_AND_SUPPLY_STATUS_REG01);

    if(di->battery_present){
        di->enable_iterm = ENABLE_ITERM;
        en_nobatop = en_nobatop & (~EN_NOBATOP);
    }else {
        di->enable_iterm = DISABLE_ITERM;
        en_nobatop = en_nobatop | EN_NOBATOP;
    }

    bq2416x_config_control_reg(di);
    bq2416x_write_byte(di, en_nobatop, REG_BATTERY_AND_SUPPLY_STATUS_REG01);
}
/*
 * set Battery charger current(550 ~1500mA) and Termination current(50~350mA)
 *
 */
static void bq2416x_config_current_reg(struct bq2416x_device_info *di)
{
	unsigned int currentmA = 0;
	unsigned int term_currentmA = 0;
	u8 Vichrg = 0;
	u8 shift = 0;
	u8 Viterm = 0;

	currentmA = di->currentmA;
	term_currentmA = di->term_currentmA;

	if (currentmA < 550)
		currentmA = 550;

//r00186667, 20110802 , removed begin
#if 0
	if ((di->bqchip_version & (BQ24153 | BQ24158))) {
		shift = BQ24153_CURRENT_SHIFT;
		if (currentmA > 1250)
			currentmA = 1250;
	}
#endif
//r00186667, 20110802 , removed end    

	if ((di->bqchip_version & BQ24161)) {
		shift = BQ2416x_CURRENT_SHIFT;
		if (currentmA > 2500)
			currentmA = 2500;
	}

	if (term_currentmA > 350)
		term_currentmA = 350;

	Vichrg = (currentmA - 550)/75;

	Viterm = (term_currentmA - 50)/50;

	di->current_reg = (Vichrg << shift | Viterm);
	bq2416x_write_byte(di, di->current_reg, REG_BATTERY_CURRENT);
	
	return;
}
/*
 *config TMR_RST function to reset the watchdog
 * 
 */
static void bq2416x_config_watchdog_reg(struct bq2416x_device_info *di) 
{
    di->status_reg00 = (TMR_RST) | di->supply_sel; 
	bq2416x_write_byte(di, di->status_reg00, REG_STATUS_CONTROL_REG00);
	return;
}
/*
 *Enable STAT pin output to show charge status
 * 
 */
static void bq2416x_config_status_reg(struct bq2416x_device_info *di)
{
	bq2416x_config_usb_supply_sel_reg(di);
	bq2416x_write_byte(di, di->control_reg, REG_CONTROL_REGISTER);
	return;
}
static void
bq2416x_charger_update_status(struct bq2416x_device_info *di)
{
	u8 read_reg[8] = {0};
    long int events=BQ2416x_START_CHARGING;
    static int battery_capacity = 0;

	di->timer_fault = 0;
	bq2416x_read_block(di, &read_reg[0], 0, 8); 

	if((read_reg[1] & BQ2416x_FAULT_VBUS_VUVLO) == BQ2416x_FAULT_VBUS_OVP){
		dev_err(di->dev, "bq2416x charger over voltage = %x\n",read_reg[1]);
		events = POWER_SUPPLY_OVERVOLTAGE;
		blocking_notifier_call_chain(&notifier_list, events, NULL);
	}
   
	if ((read_reg[0] & BQ2416x_CHARGE_FAULT) == BQ2416x_STATUS_CHARGE_DONE){   
		dev_dbg(di->dev, "CHARGE DONE\n");
        battery_capacity = bq27510_battery_capacity(g_battery_measure_by_bq27510_device);
        if (((!is_bq27510_battery_full(g_battery_measure_by_bq27510_device))||(battery_capacity!=100))&& (di->battery_present)){
            dev_info(di->dev, "charge_done_battery_capacity=%d\n",battery_capacity);
            di->hz_mode = EN_HIZ;
			bq2416x_write_byte(di, di->control_reg02 | di->hz_mode, REG_CONTROL_REGISTER_REG02);
            msleep(500);
			di->hz_mode = DIS_HIZ;
            bq2416x_config_control_reg(di);
			events = BQ2416x_START_CHARGING;           
        }else{
            events = BQ2416x_CHARGE_DONE;
        }
        blocking_notifier_call_chain(&notifier_list, events, NULL);
    }

	if ((read_reg[0] & BQ2416x_FAULT_BATTERY) == BQ2416x_FAULT_WATCHDOG_TIMER){ 
		di->timer_fault = 1;
     }

	if ((read_reg[0] & BQ2416x_FAULT_BATTERY) == BQ2416x_FAULT_SAFETY_TIMER) 
		di->timer_fault = 1;
     
	if (read_reg[0] & BQ2416x_FAULT_BATTERY) {
		di->cfg_params = 1;
		dev_err(di->dev, "CHARGER STATUS %x\n", read_reg[0]);
	}

	if ((read_reg[1] & 0x6) == BQ2416x_FAULT_BAT_OVP) {
        gpio_set_value(ENABLE_BQ2416x_CHARGER, 1);
		dev_err(di->dev, "battery ovp = %x,%x\n", read_reg[1],read_reg[3]);
        msleep(1000);
        gpio_set_value(ENABLE_BQ2416x_CHARGER, 0);
	}

	if ((di->timer_fault == 1) || (di->cfg_params == 1)) {
		bq2416x_write_byte(di, di->control_reg02, REG_CONTROL_REGISTER_REG02);
		bq2416x_write_byte(di, di->voltage_reg03, REG_BATTERY_VOLTAGE_REG03);
		bq2416x_write_byte(di, di->current_reg05, REG_BATTERY_CURRENT_REG05);
		bq2416x_write_byte(di, di->dppm_reg06, REG_DPPM_VOLTAGE_REG06);
		bq2416x_config_safety_reg(di); 
		di->cfg_params = 0;
	}

	/* reset 32 second timer */
	bq2416x_config_status_reg(di);

	return;
}
/*
 *Enable STAT pin output to show charge status
 * 
 */
static void bq2416x_config_status_reg(struct bq2416x_device_info *di)
{
	bq2416x_config_watchdog_reg(di);
	bq2416x_write_byte(di, di->control_reg02, REG_CONTROL_REGISTER_REG02);
	return;
}