static void smb347_set_charging_state(struct smb_charger_callbacks *ptr, int cable_status) { struct smb347_chg_data *chg = container_of(ptr, struct smb347_chg_data, callbacks); if (cable_status) { /* Init smb347 charger */ smb347_charger_init(chg); switch (cable_status) { case CABLE_TYPE_AC: /* Input current limit : DCIN 1800mA, USBIN HC 1800mA */ smb347_i2c_write(chg->client, SMB347_INPUT_CURRENTLIMIT, 0x66); /* CommandB : High-current mode */ smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x03); pr_info("%s : 1.8A charging enable\n", __func__); break; case CABLE_TYPE_USB: /* CommandB : USB5 */ smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x02); pr_info("%s : LOW(USB5) charging enable\n", __func__); break; default: /* CommandB : USB1 */ smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x00); pr_info("%s : LOW(USB1) charging enable\n", __func__); break; } } }
void smb347_set_charging_current(int set_current) { struct smb347_chg_data *chg = smb347_chg; if (set_current > 450) { /* CommandB : High-current mode */ smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x03); udelay(10); } else { /* CommandB : USB5 */ smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x02); udelay(10); } pr_debug("%s: Set charging current as %dmA.\n", __func__, set_current); }
static void smb347_i2c_write_array(struct i2c_client *client, u8 *buf, int size) { int i; for (i = 0; i < size; i += 3) smb347_i2c_write(client, (u8) (*(buf + i)), (buf + i) + 1); }
static void smb347_set_charging_state(int enable, int charging_mode) { struct smb347_chg_data *chg = smb347_chg; pr_info("%s : enable(%d), charging_mode(%d)\n", __func__, enable, charging_mode); if (enable) { /* Only for P4C rev0.2, Check vbus for opeartion charger */ if (!smb347_check_powersource(chg)) return; /* Init smb347 charger */ smb347_charger_init(chg); switch (charging_mode) { case CABLE_TYPE_TA: /* Input current limit : DCIN 1800mA, USBIN HC 1800mA */ smb347_i2c_write(chg->client, SMB347_INPUT_CURRENTLIMIT, 0x66); /* CommandB : High-current mode */ smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x03); pr_info("%s : 1.8A charging enable\n", __func__); break; case CABLE_TYPE_DESKDOCK: /* Input current limit : DCIN 1500mA, USBIN HC 1500mA */ smb347_i2c_write(chg->client, SMB347_INPUT_CURRENTLIMIT, 0x55); /* CommandB : High-current mode */ smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x03); pr_info("%s : 1.5A charging enable\n", __func__); break; case CABLE_TYPE_USB: /* CommandB : USB5 */ smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x02); pr_info("%s : LOW(USB5) charging enable\n", __func__); break; default: /* CommandB : USB1 */ smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x00); pr_info("%s : LOW(USB1) charging enable\n", __func__); break; } smb347_enable_charging(chg); } else { smb347_disable_charging(chg); } smb347_test_read(); }
static void smb347_allow_volatile_writes(struct i2c_client *client) { int val, reg; u8 data; reg = SMB347_COMMAND_A; val = smb347_i2c_read(client, reg, &data); if ((val >= 0) && !(data & 0x80)) { dev_dbg(&client->dev, "%s : reg(0x%02x): 0x%02x", __func__, reg, data); data |= (0x1 << 7); if (smb347_i2c_write(client, reg, &data) < 0) dev_err(&client->dev, "%s : error!\n", __func__); val = smb347_i2c_read(client, reg, &data); if (val >= 0) { data = (u8) data; dev_dbg(&client->dev, " => 0x%02x\n", data); } } }
static void smb347_set_command(struct i2c_client *client, int reg, int datum) { int val; u8 data = 0; val = smb347_i2c_read(client, reg, &data); if (val >= 0) { dev_dbg(&client->dev, "%s : reg(0x%02x): 0x%02x", __func__, reg, data); if (data != datum) { data = datum; if (smb347_i2c_write(client, reg, &data) < 0) dev_err(&client->dev, "%s : error!\n", __func__); val = smb347_i2c_read(client, reg, &data); if (val >= 0) dev_dbg(&client->dev, " => 0x%02x\n", data); } } }
ssize_t sec_hal_chg_store_attrs(struct device *dev, const ptrdiff_t offset, const char *buf, size_t count) { struct power_supply *psy = dev_get_drvdata(dev); struct sec_charger_info *chg = container_of(psy, struct sec_charger_info, psy_chg); int ret = 0; int x = 0; u8 data = 0; switch (offset) { case CHG_REG: if (sscanf(buf, "%x\n", &x) == 1) { chg->reg_addr = x; smb347_i2c_read(chg->client, chg->reg_addr, &data); chg->reg_data = data; dev_dbg(dev, "%s: (read) addr = 0x%x, data = 0x%x\n", __func__, chg->reg_addr, chg->reg_data); ret = count; } break; case CHG_DATA: if (sscanf(buf, "%x\n", &x) == 1) { data = (u8)x; dev_dbg(dev, "%s: (write) addr = 0x%x, data = 0x%x\n", __func__, chg->reg_addr, data); smb347_i2c_write(chg->client, chg->reg_addr, &data); ret = count; } break; default: ret = -EINVAL; break; } return ret; }
static void smb347_charger_init(struct smb347_chg_data *chg) { /* Allow volatile writes to CONFIG registers */ smb347_i2c_write(chg->client, SMB347_COMMAND_A, 0x80); /* Command B : USB1 mode, USB mode */ smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x00); /* Charge curr : Fast-chg 2200mA */ /* Pre-charge curr 250mA, Term curr 250mA */ smb347_i2c_write(chg->client, SMB347_CHARGE_CURRENT, 0xDD); /* Pin enable control : Charger enable control EN Pin - Active Low */ /* : USB5/1/HC or USB9/1.5/HC Control - Register Control */ /* : USB5/1/HC Input state - Tri-state Input */ smb347_i2c_write(chg->client, SMB347_PIN_ENABLE_CONTROL, 0x60); /* Input current limit : DCIN 1800mA, USBIN HC 1800mA */ smb347_i2c_write(chg->client, SMB347_INPUT_CURRENTLIMIT, 0x66); /* Various func. : USBIN primary input, VCHG func. enable */ smb347_i2c_write(chg->client, SMB347_VARIOUS_FUNCTIONS, 0x87); /* Float voltage : 4.2V */ smb347_i2c_write(chg->client, SMB347_FLOAT_VOLTAGE, 0x63); /* Charge control : Auto recharge disable, APSD disable */ smb347_i2c_write(chg->client, SMB347_CHARGE_CONTROL, 0x80); /* STAT, Timer control : STAT active low, Complete time out 1527min. */ smb347_i2c_write(chg->client, SMB347_STAT_TIMERS_CONTROL, 0x1A); /* Therm control : Therm monitor disable */ smb347_i2c_write(chg->client, SMB347_THERM_CONTROL_A, 0x7F); /* USB selection : USB2.0(100mA/500mA), INOK polarity */ /* Active low */ smb347_i2c_write(chg->client, SMB347_SYSOK_USB30_SELECTION, 0x08); /* Other control */ smb347_i2c_write(chg->client, SMB347_OTHER_CONTROL_A, 0x1D); /* OTG tlim therm control */ smb347_i2c_write(chg->client, SMB347_OTG_TLIM_THERM_CONTROL, 0x3F); /* Limit cell temperature */ smb347_i2c_write(chg->client, SMB347_LIMIT_CELL_TEMPERATURE_MONITOR, 0x01); /* Fault interrupt : Clear */ smb347_i2c_write(chg->client, SMB347_FAULT_INTERRUPT, 0x00); /* STATUS ingerrupt : Clear */ smb347_i2c_write(chg->client, SMB347_STATUS_INTERRUPT, 0x00); msleep(50); }
static void smb347_charger_init(struct smb347_chg_data *chg) { pr_info("%s\n", __func__); /* Only for P4C rev0.2, Check vbus for opeartion charger */ if (!smb347_check_powersource(chg)) return; /* Set GPIO_TA_EN as HIGH, charging disable */ smb347_disable_charging(chg); mdelay(100); /* Allow volatile writes to CONFIG registers */ smb347_i2c_write(chg->client, SMB347_COMMAND_A, 0x80); /* Command B : USB1 mode, USB mode */ smb347_i2c_write(chg->client, SMB347_COMMAND_B, 0x00); /* Charge curr : Fast-chg 2200mA */ /* Pre-charge curr 250mA, Term curr 250mA */ smb347_i2c_write(chg->client, SMB347_CHARGE_CURRENT, 0xDD); /* Pin enable control : Charger enable control EN Pin - Active Low */ /* : USB5/1/HC or USB9/1.5/HC Control - Register Control */ /* : USB5/1/HC Input state - Tri-state Input */ smb347_i2c_write(chg->client, SMB347_PIN_ENABLE_CONTROL, 0x60); /* Input current limit : DCIN 1800mA, USBIN HC 1800mA */ smb347_i2c_write(chg->client, SMB347_INPUT_CURRENTLIMIT, 0x66); /* Various func. : USBIN primary input, VCHG func. enable */ smb347_i2c_write(chg->client, SMB347_VARIOUS_FUNCTIONS, 0xA7); /* Float voltage : 4.2V */ smb347_i2c_write(chg->client, SMB347_FLOAT_VOLTAGE, 0x63); /* Charge control : Auto recharge disable, APSD disable */ smb347_i2c_write(chg->client, SMB347_CHARGE_CONTROL, 0x80); /* STAT, Timer control : STAT active low, Complete time out 1527min. */ smb347_i2c_write(chg->client, SMB347_STAT_TIMERS_CONTROL, 0x1A); /* Therm control : Therm monitor disable */ smb347_i2c_write(chg->client, SMB347_THERM_CONTROL_A, 0xBF); /* USB selection : USB2.0(100mA/500mA), INOK polarity */ if ((system_rev >= 2) && (system_rev <= 5)) { /* Active high */ smb347_i2c_write(chg->client, SMB347_SYSOK_USB30_SELECTION, 0x09); } else { /* Active low */ smb347_i2c_write(chg->client, SMB347_SYSOK_USB30_SELECTION, 0x08); } /* Other control */ smb347_i2c_write(chg->client, SMB347_OTHER_CONTROL_A, 0x0D); /* OTG tlim therm control */ smb347_i2c_write(chg->client, SMB347_OTG_TLIM_THERM_CONTROL, 0x3F); /* Limit cell temperature */ smb347_i2c_write(chg->client, SMB347_LIMIT_CELL_TEMPERATURE_MONITOR, 0x01); /* Fault interrupt : Clear */ smb347_i2c_write(chg->client, SMB347_FAULT_INTERRUPT, 0x00); /* STATUS ingerrupt : Clear */ smb347_i2c_write(chg->client, SMB347_STATUS_INTERRUPT, 0x00); }