charger: smb345: add hot limit temperature to stop charging
Bug: 11476629
Change-Id: I5c7039e2a371b404f9f4e86e7b28542921138608
Signed-off-by: Hank_Lee <Hank_Lee@asus.com>
diff --git a/drivers/power/bq27541_battery.c b/drivers/power/bq27541_battery.c
index cde5011..217e53a 100755
--- a/drivers/power/bq27541_battery.c
+++ b/drivers/power/bq27541_battery.c
@@ -89,6 +89,7 @@
enum power_supply_property psp, union power_supply_propval *val);
extern unsigned get_usb_cable_status(void);
extern int smb347_charger_enable(bool enable);
+extern int smb347_config_thermal_charging(int temp);
module_param(battery_current, uint, 0644);
module_param(battery_remaining_capacity, uint, 0644);
@@ -148,6 +149,7 @@
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_TEMP,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
};
void check_cabe_type(void)
@@ -344,6 +346,26 @@
.attrs = battery_smbus_attributes,
};
+static int bq27541_battery_current(void)
+{
+ int ret;
+ int curr = 0;
+
+ ret = bq27541_read_i2c(bq27541_data[REG_CURRENT].addr, &curr, 0);
+ if (ret) {
+ BAT_ERR("error reading current ret = %x\n", ret);
+ return 0;
+ }
+
+ curr = (s16)curr;
+
+ if (curr >= bq27541_data[REG_CURRENT].min_value &&
+ curr <= bq27541_data[REG_CURRENT].max_value) {
+ return curr;
+ } else
+ return 0;
+}
+
static void battery_status_poll(struct work_struct *work)
{
struct bq27541_device_info *batt_dev = container_of(work, struct bq27541_device_info, status_poll_work.work);
@@ -353,6 +375,10 @@
power_supply_changed(&bq27541_supply[Charger_Type_Battery]);
+ if (!bq27541_device->temp_err)
+ if (ac_on || usb_on)
+ smb347_config_thermal_charging(bq27541_device->old_temperature/10);
+
/* Schedule next polling */
queue_delayed_work(battery_work_queue, &batt_dev->status_poll_work, bat_check_interval*HZ);
}
@@ -599,6 +625,11 @@
bq27541_device->old_temperature = val->intval = ret;
BAT_NOTICE("temperature= %u (0.1¢XC)\n", val->intval);
}
+ if (psp == POWER_SUPPLY_PROP_CURRENT_NOW) {
+ val->intval = bq27541_device->bat_current
+ = bq27541_battery_current();
+ BAT_NOTICE("current = %d mA\n", val->intval);
+ }
return 0;
}
diff --git a/drivers/power/smb347-charger.c b/drivers/power/smb347-charger.c
index 03f5263..1c5d136 100755
--- a/drivers/power/smb347-charger.c
+++ b/drivers/power/smb347-charger.c
@@ -108,6 +108,8 @@
#define DELAY_FOR_CURR_LIMIT_RECONF (60)
#define ADAPTER_PROTECT_DELAY (4*HZ)
#define GPIO_AC_OK TEGRA_GPIO_PV1
+#define ENABLE_PIN_CTRL_MASK 0x60
+#define BAT_Hot_Limit 45
/* Functions declaration */
static int smb347_configure_charger(struct i2c_client *client, int value);
@@ -1060,42 +1062,37 @@
static ssize_t smb347_reg_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct i2c_client *client = charger->client;
- uint8_t config_reg[14], cmd_reg[1], status_reg[10];
- int i, ret = 0;
+ uint8_t config_reg[15], cmd_reg[1], status_reg[10];
+ char tmp_buf[64];
+ int i, cfg_ret, cmd_ret, sts_ret = 0;
- ret += i2c_smbus_read_i2c_block_data(client, smb347_CHARGE, 15, config_reg)
- + i2c_smbus_read_i2c_block_data(client, smb347_CMD_REG, 2, cmd_reg)
- + i2c_smbus_read_i2c_block_data(client, smb347_INTR_STS_A, 11, status_reg);
+ cfg_ret = i2c_smbus_read_i2c_block_data(client, smb347_CHARGE, 15, config_reg);
+ cmd_ret = i2c_smbus_read_i2c_block_data(client, smb347_CMD_REG, 2, cmd_reg);
+ sts_ret = i2c_smbus_read_i2c_block_data(client, smb347_INTR_STS_A, 11, status_reg);
- if (ret < 0)
- SMB_ERR("failed to read charger reg !\n");
+ sprintf(tmp_buf, "SMB34x Configuration Registers Detail\n"
+ "==================\n");
+ strcpy(buf, tmp_buf);
- SMB_INFO("smb347 Registers\n");
- SMB_INFO("------------------\n");
- for(i=0;i<=14;i++)
- SMB_INFO("Reg[%02xh]=0x%02x\n", i, config_reg[i]);
- for(i=0;i<=1;i++)
- SMB_INFO("Reg[%02xh]=0x%02x\n", 48+i, cmd_reg[i]);
- for(i=0;i<=10;i++)
- SMB_INFO("Reg[%02xh]=0x%02x\n", 53+i, status_reg[i]);
-
- return sprintf(buf, "Reg[06h]=0x%02x\n"
- "Reg[08h]=0x%02x\n"
- "Reg[30h]=0x%02x\n"
- "Reg[31h]=0x%02x\n"
- "Reg[39h]=0x%02x\n"
- "Reg[3dh]=0x%02x\n"
- "Reg[3eh]=0x%02x\n"
- "Reg[3fh]=0x%02x\n",
- config_reg[6],
- config_reg[8],
- cmd_reg[0],
- cmd_reg[1],
- status_reg[4],
- status_reg[8],
- status_reg[9],
- status_reg[10]);
-
+ if (cfg_ret > 0) {
+ for(i=0;i<=14;i++) {
+ sprintf(tmp_buf, "Reg%02xh:\t0x%02x\n", i, config_reg[i]);
+ strcat(buf, tmp_buf);
+ }
+ }
+ if (cmd_ret > 0) {
+ for(i=0;i<=1;i++) {
+ sprintf(tmp_buf, "Reg%02xh:\t0x%02x\n", 48+i, cmd_reg[i]);
+ strcat(buf, tmp_buf);
+ }
+ }
+ if (sts_ret > 0) {
+ for(i=0;i<=10;i++) {
+ sprintf(tmp_buf, "Reg%02xh:\t0x%02x\n", 53+i, status_reg[i]);
+ strcat(buf, tmp_buf);
+ }
+ }
+ return strlen(buf);
}
static void smb347_default_setback(void)
@@ -1161,6 +1158,53 @@
return -1;
}
+int smb347_config_thermal_charging(int temp)
+{
+ struct i2c_client *client = charger->client;
+ int ret = 0, retval, setting = 0;
+
+ mdelay(150);
+ SMB_NOTICE("temp=%d\n", temp);
+
+ ret = smb347_volatile_writes(client, smb347_ENABLE_WRITE);
+ if (ret < 0) {
+ dev_err(&client->dev, "%s() charger enable write error..\n", __func__);
+ goto error;
+ }
+
+ /*charger enable/disable*/
+ retval = smb347_read(client, smb347_PIN_CTRL);
+ if (retval < 0) {
+ dev_err(&client->dev, "%s(): Failed in reading 0x%02x",
+ __func__, smb347_PIN_CTRL);
+ goto error;
+ }
+
+ setting = retval & ENABLE_PIN_CTRL_MASK;
+ if (temp > BAT_Hot_Limit) {
+ if (setting != 0x40) {
+ SMB_NOTICE("Charger disable\n");
+ smb347_charger_enable(false);
+ } else
+ SMB_NOTICE("Bypass charger disable\n");
+ } else {
+ if (setting != 0x60) {
+ SMB_NOTICE("Charger enable\n");
+ smb347_charger_enable(true);
+ } else
+ SMB_NOTICE("Bypass charger enable\n");
+ }
+
+ ret = smb347_volatile_writes(client, smb347_DISABLE_WRITE);
+ if (ret < 0) {
+ dev_err(&client->dev, "%s() charger enable write error..\n", __func__);
+ goto error;
+ }
+error:
+ return ret;
+}
+EXPORT_SYMBOL(smb347_config_thermal_charging);
+
static int __devinit smb347_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{