Ejemplo n.º 1
0
static int set_reg(void *data, u64 val)
{
    struct opchg_charger *chip = data;
    int rc;
    u8 temp;
    
    temp = (u8) val;
    rc = opchg_write_reg(chip, chip->peek_poke_address, temp);
    if (rc < 0) {
        dev_err(chip->dev, "Couldn't write 0x%02x to 0x%02x rc= %d\n", chip->peek_poke_address, temp, rc);
        return -EAGAIN;
    }
    
    return 0;
}
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;
}