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, ®); 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; }