+static ssize_t
+show_charge_current(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ 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
+set_charge_current(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long newCurrent;
+ int ret;
+
+ ret = strict_strtoul(buf, 10, &newCurrent);
+ if (ret)
+ return -EINVAL;
+
+ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, KEY_IIREF, REG_BCIMFKEY);
+ if (ret)
+ return ret;
+
+ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, newCurrent & 0xff, REG_BCIIREF1);
+ if (ret)
+ return ret;
+
+ ret = twl4030_i2c_write_u8(TWL4030_MODULE_MAIN_CHARGE, KEY_IIREF, REG_BCIMFKEY);
+ if (ret)
+ return ret;
+
+ 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_IWUSR, show_charge_current, set_charge_current);
+