예제 #1
0
static void opchg_external_power_changed(struct power_supply *psy)
{
    struct opchg_charger *chip = container_of(psy, struct opchg_charger, batt_psy);
    union power_supply_propval prop = {0,};
    int rc, current_limit = 0, online = 0;
    
    if (chip->bms_psy_name) {
        chip->bms_psy = power_supply_get_by_name((char *)chip->bms_psy_name);
    }
    
    rc = chip->usb_psy->get_property(chip->usb_psy, POWER_SUPPLY_PROP_ONLINE, &prop);
    if (rc) {
        dev_err(chip->dev, "Couldn't read USB online property, rc=%d\n", rc);
    }
	else {
        online = prop.intval;
    }
    
    rc = chip->usb_psy->get_property(chip->usb_psy, POWER_SUPPLY_PROP_CURRENT_MAX, &prop);
    if (rc) {
        dev_err(chip->dev, "Couldn't read USB current_max property, rc=%d\n", rc);
    }
	else {
        current_limit = prop.intval / 1000;
    }
    
    if(current_limit > chip->limit_current_max_ma) {
        current_limit = chip->limit_current_max_ma;
    }

	//lfc add for charger_ovp
	chip->charger_vol = opchg_get_prop_charger_voltage_now(chip);
	opchg_get_charger_ov_status(chip);
	if(chip->charger_ov_status == true){
		dev_err(chip->dev,"%s charger-ovp,return \n",__func__);
		return ;
	}

    opchg_set_enable_volatile_writes(chip);
	opchg_config_input_chg_current(chip, INPUT_CURRENT_LCD, chip->limit_current_max_ma);
	opchg_config_input_chg_current(chip, INPUT_CURRENT_CAMERA, chip->limit_current_max_ma);
    opchg_config_input_chg_current(chip, INPUT_CURRENT_BY_POWER, current_limit);

    	opchg_set_input_chg_current(chip, chip->max_input_current[INPUT_CURRENT_MIN], false);

	if ((chip->multiple_test == 1) && (current_limit >= 500)) {
		opchg_config_suspend_enable(chip, FACTORY_ENABLE, 1);
	}
	
    opchg_config_over_time(chip, current_limit);//opchg_set_complete_charge_timeout(chip);
	dev_dbg(chip->dev, "%s set charger input current=%d,online = %d, current_limit = %d\n", __func__,chip->max_input_current[INPUT_CURRENT_MIN], online, current_limit);

    opchg_check_status(chip);
	opchg_set_status(chip, false);
	if(chip->charging_opchg_temp_statu == OPCHG_CHG_TEMP_NORMAL)
		opchg_set_fast_chg_current(chip, chip->max_fast_current[FAST_CURRENT_MIN]);
	
    power_supply_changed(&chip->batt_psy);
}
int smb358_hw_init(struct opchg_charger *chip)
{
    int rc;
    u8 reg = 0, mask = 0;
    
	/*
	 * If the charger is pre-configured for autonomous operation,
	 * do not apply additonal settings
	 */
    if (chip->chg_autonomous_mode) {
        dev_dbg(chip->dev, "Charger configured for autonomous mode\n");
        return 0;
    }
    
    rc = opchg_read_reg(chip, CHG_REVISION_REG, &reg);
    if (rc) {
        dev_err(chip->dev, "Couldn't read CHG_REVISION_REG rc=%d\n", rc);
        return rc;
    }
    
    rc = smb358_set_enable_volatile_writes(chip);
    if (rc) {
        dev_err(chip->dev, "Couldn't configure volatile writes rc=%d\n", rc);
        return rc;
	}
	
    /* setup defaults for CHG_CNTRL_REG */
    reg = CHG_CTRL_BATT_MISSING_DET_THERM_IO;
    mask = CHG_CTRL_BATT_MISSING_DET_MASK;
    rc = opchg_masked_write(chip, CHG_CTRL_REG, mask, reg);
    if (rc) {
        dev_err(chip->dev, "Couldn't set CHG_CTRL_REG rc=%d\n", rc);
        return rc;
    }
    
    /* setup defaults for PIN_CTRL_REG */
    reg = CHG_PIN_CTRL_USBCS_REG_BIT | CHG_PIN_CTRL_CHG_EN_LOW_REG_BIT |
                            CHG_PIN_CTRL_APSD_IRQ_BIT | CHG_PIN_CTRL_CHG_ERR_IRQ_BIT;
    mask = CHG_PIN_CTRL_CHG_EN_MASK | CHG_PIN_CTRL_USBCS_REG_MASK |
                            CHG_PIN_CTRL_APSD_IRQ_MASK | CHG_PIN_CTRL_CHG_ERR_IRQ_MASK;
    rc = opchg_masked_write(chip, CHG_PIN_EN_CTRL_REG, mask, reg);
    if (rc) {
        dev_err(chip->dev, "Couldn't set CHG_PIN_EN_CTRL_REG rc=%d\n", rc);
        return rc;
    }
    
    /* setup USB suspend and APSD  */
    rc = opchg_masked_write(chip, VARIOUS_FUNC_REG,
                            VARIOUS_FUNC_USB_SUSP_MASK, VARIOUS_FUNC_USB_SUSP_EN_REG_BIT);
    if (rc) {
        dev_err(chip->dev, "Couldn't set VARIOUS_FUNC_REG rc=%d\n", rc);
        return rc;
    }
    
    if (!chip->disable_apsd) {
        reg = CHG_CTRL_APSD_EN_BIT;
    }
	else {
        reg = 0;
    }
    rc = opchg_masked_write(chip, CHG_CTRL_REG, CHG_CTRL_APSD_EN_MASK, reg);
    if (rc) {
        dev_err(chip->dev, "Couldn't set CHG_CTRL_REG rc=%d\n", rc);
        return rc;
    }
    
    /* Fault and Status IRQ configuration */
    reg = FAULT_INT_HOT_COLD_HARD_BIT | FAULT_INT_HOT_COLD_SOFT_BIT | FAULT_INT_INPUT_UV_BIT
                            | FAULT_INT_AICL_COMPLETE_BIT | FAULT_INT_INPUT_OV_BIT;
    rc = opchg_write_reg(chip, FAULT_INT_REG, reg);
    if (rc) {
        dev_err(chip->dev, "Couldn't set FAULT_INT_REG rc=%d\n", rc);
        return rc;
    }
    
    reg = STATUS_INT_CHG_TIMEOUT_BIT | STATUS_INT_OTG_DETECT_BIT | STATUS_INT_BATT_OV_BIT
                            | STATUS_INT_CHGING_BIT | STATUS_INT_CHG_INHI_BIT
                            | STATUS_INT_INOK_BIT | STATUS_INT_LOW_BATT_BIT
                            | STATUS_INT_MISSING_BATT_BIT;
    rc = opchg_write_reg(chip, STATUS_INT_REG, reg);
    if (rc) {
        dev_err(chip->dev, "Couldn't set STATUS_INT_REG rc=%d\n", rc);
        return rc;
    }
    
    /* setup THERM Monitor */
    rc = opchg_masked_write(chip, THERM_A_CTRL_REG,
                            THERM_A_THERM_MONITOR_EN_MASK, THERM_A_THERM_MONITOR_EN_MASK);
    if (rc) {
        dev_err(chip->dev, "Couldn't set THERM_A_CTRL_REG rc=%d\n", rc);
        return rc;
    }
    
    /* setup switching frequency */
    rc = opchg_masked_write(chip, THERM_A_CTRL_REG,
                            THERM_A_SWITCHING_FREQ_MASK, THERM_A_SWITCHING_FREQ_1_5MHZ);
    if (rc) {
        dev_err(chip->dev, "Couldn't set THERM_A_CTRL_REG rc=%d\n", rc);
        return rc;
    }
    
    /* setup otg current limit */
    rc = opchg_masked_write(chip, OTG_TLIM_THERM_REG, OTG_CURRENT_LIMIT_MASK, OTG_CURRENT_LIMIT_BIT);
    if (rc) {
        dev_err(chip->dev, "Couldn't set OTG_TLIM_THERM_REG rc=%d\n", rc);
        return rc;
    }
	
    /* set the fast charge current limit */
	opchg_set_fast_chg_current(chip, chip->max_fast_current[FAST_CURRENT_MIN]);
	
	/* set the float voltage */
	opchg_set_float_voltage(chip, chip->min_term_voltage[TERM_VOL_MIN]);
	
    #if 0
    /* set low_battery voltage threshold */
    reg = 0x0f;//3.58V
    rc = opchg_masked_write(chip, LOW_BATT_THRESHOLD_REG, CHG_LOW_BATT_THRESHOLD_MASK, reg);
    if (rc) {
        dev_err(chip->dev, "Couldn't set LOW_BATT_THRESHOLD_REG rc=%d\n", rc);
        return rc;
    }
    #endif
	
    /* set pre-charging current */
    reg = CHG_PRE_450MA;
    rc = opchg_masked_write(chip, CHG_CURRENT_CTRL_REG, CHG_PRE_MASK, reg);
    if (rc) {
        dev_err(chip->dev, "Couldn't set CHG_CURRENT_CTRL_REG rc=%d\n", rc);
        return rc;
    }
    
 	/* set iterm */
	rc = smb358_set_term_current(chip);
	if (rc)
		dev_err(chip->dev, "Couldn't set term current rc=%d\n", rc);
    
 	/* set recharge */
	rc = smb358_set_recharge_and_inhibit(chip);
	if (rc)
		dev_err(chip->dev, "Couldn't set recharge para rc=%d\n", rc);
    
    rc = opchg_masked_write(chip, INPUT_CURRENT_LIMIT_REG, VFLT_MASK, reg);
    if (rc) {
        dev_err(chip->dev, "Couldn't set inhibit threshold rc = %d\n", rc);
        return rc;
    }
    
    /* enable/disable stat output */
    rc = opchg_masked_write(chip, CMD_A_REG, CMD_A_STAT_DISABLE_MASK, CMD_A_STAT_DISABLE_BIT);
    if (rc) {
        dev_err(chip->dev, "Unable to %s stat pin. rc=%d\n",
                            CMD_A_STAT_DISABLE_BIT ? "disable" : "enable", rc);
    }
    
    /* enable/disable charging */
    //opchg_config_charging_disable(chip, USER_DISABLE, !!chip->disabled_status);
    /* enable/disable charging */
	if (chip->charging_disabled) {
		rc = smb358_charging_disable(chip, USER, 1);
		if (rc)
			dev_err(chip->dev, "Couldn't '%s' charging rc = %d\n",
								chip->charging_disabled ? "disable" : "enable", rc);
	} else {
			/*
			* Enable charging explictly,
			* because not sure the default behavior.
			*/
			rc = smb358_set_charging_disable(chip, 0);
			if (rc)
				dev_err(chip->dev, "Couldn't enable charging\n");
	}
	
    /* enable/disable fast charging setting */
    rc = opchg_masked_write(chip, CMD_A_REG, CMD_A_FAST_CHARGING_SET_MASK, CMD_A_FAST_CHARGING_SET_BIT);
    if (rc) {
        dev_err(chip->dev, "Unable to %s fast charging set. rc=%d\n",
                            CMD_A_FAST_CHARGING_SET_BIT ? "disable" : "enable", rc);
    }

	/*
	* Workaround for recharge frequent issue: When battery is
	* greater than 4.2v, and charging is disabled, charger
	* stops switching. In such a case, system load is provided
	* by battery rather than input, even though input is still
	* there. Make reg09[0:3] to be a non-zero value which can
	* keep the switcher active
	*/
	rc = opchg_masked_write(chip, OTHER_CTRL_REG, CHG_LOW_BATT_THRESHOLD_MASK,
											SMB358_BATT_GOOD_THRE_2P5);
	if (rc)
		dev_err(chip->dev, "Couldn't write OTHER_CTRL_REG, rc = %d\n",rc);
	
    return rc;
}