diff options
Diffstat (limited to 'recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-2.patch')
-rw-r--r-- | recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-2.patch | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-2.patch b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-2.patch new file mode 100644 index 0000000000..ce5a98f69d --- /dev/null +++ b/recipes/linux/linux-omap-2.6.29/omap3-touchbook/battery1-tps65950-charging-management-2.patch @@ -0,0 +1,246 @@ +diff --git a/drivers/power/twl4030_bci_battery.c b/drivers/power/twl4030_bci_battery.c +index eab0933..d1220d7 100644 +--- a/drivers/power/twl4030_bci_battery.c ++++ b/drivers/power/twl4030_bci_battery.c +@@ -15,6 +15,9 @@ + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + ++/* Boot with automatic charge */ ++#define CHARGE_MODE 1 ++ + #include <linux/init.h> + #include <linux/module.h> + #include <linux/device.h> +@@ -50,6 +53,7 @@ + /* Boot BCI flag bits */ + #define BCIAUTOWEN 0x020 + #define CONFIG_DONE 0x010 ++#define CVENAC 0x004 + #define BCIAUTOUSB 0x002 + #define BCIAUTOAC 0x001 + #define BCIMSTAT_MASK 0x03F +@@ -81,6 +85,11 @@ + #define REG_BB_CFG 0x012 + #define BBCHEN 0x010 + ++/* GPBR */ ++#define REG_GPBR1 0x0c ++#define MADC_HFCLK_EN 0x80 ++#define DEFAULT_MADC_CLK_EN 0x10 ++ + /* Power supply charge interrupt */ + #define REG_PWR_ISR1 0x00 + #define REG_PWR_IMR1 0x01 +@@ -129,8 +138,12 @@ + #define REG_BCIIREF1 0x027 + #define REG_BCIIREF2 0x028 + ++/* BCIMFTH1 */ ++#define REG_BCIMFTH1 0x016 ++ + /* Key */ + #define KEY_IIREF 0xE7 ++#define KEY_FTH1 0xD2 + #define REG_BCIMFKEY 0x011 + + /* Step size and prescaler ratio */ +@@ -432,15 +445,21 @@ static int twl4030battery_hw_presence_en(int enable) + /* + * Enable/Disable AC Charge funtionality. + */ +-static int twl4030charger_ac_en(int enable) ++static int twl4030charger_ac_en(int enable, int automatic) + { + int ret; + + if (enable) { + /* forcing the field BCIAUTOAC (BOOT_BCI[0) to 1 */ +- ret = clear_n_set(TWL4030_MODULE_PM_MASTER, 0, +- (CONFIG_DONE | BCIAUTOWEN | BCIAUTOAC), +- REG_BOOT_BCI); ++ if(!automatic) { ++ ret = clear_n_set(TWL4030_MODULE_PM_MASTER, BCIAUTOAC | CVENAC, ++ (CONFIG_DONE | BCIAUTOWEN), ++ REG_BOOT_BCI); ++ } else { ++ ret = clear_n_set(TWL4030_MODULE_PM_MASTER, 0, ++ (CONFIG_DONE | BCIAUTOWEN | BCIAUTOAC | CVENAC), ++ REG_BOOT_BCI); ++ } + if (ret) + return ret; + } else { +@@ -672,6 +691,9 @@ static int twl4030bci_status(void) + return ret; + } + ++#ifdef DEBUG ++ printk("BCI DEBUG: BCIMSTATEC Charge state is 0x%x\n", status); ++#endif + return (int) (status & BCIMSTAT_MASK); + } + +@@ -720,14 +742,43 @@ static int twl4030backupbatt_voltage_setup(void) + */ + static int twl4030battery_temp_setup(void) + { +- int ret; ++#ifdef DEBUG ++ u8 i; ++#endif ++ u8 ret; + + /* Enabling thermistor current */ +- ret = clear_n_set(TWL4030_MODULE_MAIN_CHARGE, 0, ITHEN, ++ ret = clear_n_set(TWL4030_MODULE_MAIN_CHARGE, 0, 0x1B, + REG_BCICTL1); + if (ret) + return ret; + ++#ifdef DEBUG ++ twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &ret, REG_BOOT_BCI); ++ printk("BCI DEBUG: BOOT_BCI Value is 0x%x\n", ret); ++ ++ twl4030_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &ret, REG_STS_HW_CONDITIONS); ++ printk("BCI DEBUG: STS_HW_CONDITIONS Value is 0x%x\n", ret); ++ ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ret, REG_BCICTL1); ++ printk("BCI DEBUG: BCICTL1 Value is 0x%x\n", ret); ++ ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ret, REG_BCICTL2); ++ printk("BCI DEBUG: BCICTL2 Value is 0x%x\n", ret); ++ ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ret, 0x0); ++ printk("BCI DEBUG: BCIMDEN Value is 0x%x\n", ret); ++ ++ twl4030_i2c_read_u8(TWL4030_MODULE_INTBR, &ret, REG_GPBR1); ++ printk("BCI DEBUG: GPBR1 Value is 0x%x\n", ret); ++ ++ for(i = 0x0; i <= 0x32; i++) ++ { ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ret, i); ++ printk("BCI DEBUG: BCI 0x%x Value is 0x%x\n", i, ret); ++ } ++#endif ++ + return 0; + } + +@@ -743,7 +794,6 @@ static inline int clear_n_set(u8 mod_no, u8 clear, u8 set, u8 reg) + ret = twl4030_i2c_read_u8(mod_no, &val, reg); + if (ret) + return ret; +- + /* Clearing all those bits to clear */ + val &= ~(clear); + +@@ -834,7 +884,19 @@ static void twl4030_bci_battery_external_power_changed(struct power_supply *psy) + static ssize_t + show_charge_current(struct device *dev, struct device_attribute *attr, char *buf) + { +- return sprintf(buf, "%d\n", read_bci_val(REG_BCIIREF1)); ++ u8 ctl; ++ int ret = read_bci_val(REG_BCIIREF1) & 0x1FF; ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &ctl, REG_BCICTL1); ++ ++ if (ctl & CGAIN) ++ ret |= 0x200; ++ ++#ifdef DEBUG ++ /* Dump debug */ ++ twl4030battery_temp_setup(); ++#endif ++ ++ return sprintf(buf, "%d\n", ret); + } + + static ssize_t +@@ -859,13 +921,45 @@ set_charge_current(struct device *dev, struct device_attribute *attr, const char + if (ret) + return ret; + +- ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, (newCurrent >> 8) & 0x03, REG_BCIIREF2); ++ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, (newCurrent >> 8) & 0x1, REG_BCIIREF2); + if (ret) + return ret; + ++ /* Set software-controlled charge */ ++ twl4030charger_ac_en(ENABLE, 0); ++ ++ /* Set CGAIN = 0 or 1 */ ++ if(newCurrent > 511) { ++ u8 tmp; ++ ++ /* Set CGAIN = 1 -- need to wait until automatic charge turns off */ ++ while(!ret) { ++ clear_n_set(TWL4030_MODULE_MAIN_CHARGE, 0, CGAIN | 0x1B, REG_BCICTL1); ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &tmp, REG_BCICTL1); ++ ++ ret = tmp & CGAIN; ++ if(!ret) ++ mdelay(50); ++ } ++ } else { ++ u8 tmp; ++ ++ /* Set CGAIN = 0 -- need to wait until automatic charge turns off */ ++ while(!ret) { ++ clear_n_set(TWL4030_MODULE_MAIN_CHARGE, CGAIN, 0x1B, REG_BCICTL1); ++ twl4030_i2c_read_u8(TWL4030_MODULE_MAIN_CHARGE, &tmp, REG_BCICTL1); ++ ++ ret = !(tmp & CGAIN); ++ if(!ret) ++ mdelay(50); ++ } ++ } ++ ++ /* Set automatic charge (CGAIN = 0/1 persists) */ ++ twl4030charger_ac_en(ENABLE, 1); ++ + return count; + } +- + static DEVICE_ATTR(charge_current, S_IRUGO | S_IWUGO, show_charge_current, set_charge_current); + + static int twl4030_bk_bci_battery_get_property(struct power_supply *psy, +@@ -986,7 +1080,10 @@ static int __init twl4030_bci_battery_probe(struct platform_device *pdev) + di->bk_bat.external_power_changed = NULL; + di->pdata = pdata; + +- twl4030charger_ac_en(ENABLE); ++ /* Set up clocks */ ++ twl4030_i2c_write_u8(TWL4030_MODULE_INTBR, MADC_HFCLK_EN | DEFAULT_MADC_CLK_EN, REG_GPBR1); ++ ++ twl4030charger_ac_en(ENABLE, CHARGE_MODE); + twl4030charger_usb_en(ENABLE); + twl4030battery_hw_level_en(ENABLE); + twl4030battery_hw_presence_en(ENABLE); +@@ -1058,6 +1155,7 @@ static int __init twl4030_bci_battery_probe(struct platform_device *pdev) + twl4030_bk_bci_battery_work); + schedule_delayed_work(&di->twl4030_bk_bci_monitor_work, 500); + ++ set_charge_current (NULL, NULL, "1023", 4); + return 0; + + bk_batt_failed: +@@ -1071,7 +1169,7 @@ chg_irq_fail: + batt_irq_fail: + voltage_setup_fail: + temp_setup_fail: +- twl4030charger_ac_en(DISABLE); ++ twl4030charger_ac_en(DISABLE, CHARGE_MODE); + twl4030charger_usb_en(DISABLE); + twl4030battery_hw_level_en(DISABLE); + twl4030battery_hw_presence_en(DISABLE); +@@ -1085,7 +1183,7 @@ static int __exit twl4030_bci_battery_remove(struct platform_device *pdev) + struct twl4030_bci_device_info *di = platform_get_drvdata(pdev); + int irq; + +- twl4030charger_ac_en(DISABLE); ++ twl4030charger_ac_en(DISABLE, CHARGE_MODE); + twl4030charger_usb_en(DISABLE); + twl4030battery_hw_level_en(DISABLE); + twl4030battery_hw_presence_en(DISABLE); + + |