+static ssize_t twl4030_bci_ac_show_enable(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 boot_bci;
+ int ret;
+
+ ret = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &boot_bci,
+ TWL4030_PM_MASTER_BOOT_BCI);
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "%d\n", (boot_bci & TWL4030_BCIAUTOAC) ? 1 : 0);
+}
+
+static ssize_t twl4030_bci_ac_store_enable(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct power_supply *psy = dev_get_drvdata(dev);
+ struct twl4030_bci *bci = container_of(psy, struct twl4030_bci, ac);
+ unsigned long enable;
+ int ret;
+
+ ret = strict_strtoul(buf, 10, &enable);
+ if (ret || enable > 1)
+ return -EINVAL;
+
+ bci->ac_charge_enable = enable;
+ twl4030_charger_enable_ac(enable);
+
+ return count;
+}
+static struct device_attribute dev_attr_enable_ac =
+ __ATTR(enable, S_IRUGO | S_IWUSR, twl4030_bci_ac_show_enable,
+ twl4030_bci_ac_store_enable);
+
+static ssize_t twl4030_bci_usb_show_enable(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ u8 boot_bci;
+ int ret;
+
+ ret = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &boot_bci,
+ TWL4030_PM_MASTER_BOOT_BCI);
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "%d\n", (boot_bci & TWL4030_BCIAUTOUSB) ? 1 : 0);
+}
+
+static ssize_t twl4030_bci_usb_store_enable(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct power_supply *psy = dev_get_drvdata(dev);
+ struct twl4030_bci *bci = container_of(psy, struct twl4030_bci, usb);
+ unsigned long enable;
+ int ret;
+
+ ret = strict_strtoul(buf, 10, &enable);
+ if (ret || enable > 1)
+ return -EINVAL;
+
+ bci->usb_charge_enable = enable;
+ twl4030_charger_enable_usb(bci, enable);
+
+ return count;
+}
+static struct device_attribute dev_attr_enable_usb =
+ __ATTR(enable, S_IRUGO | S_IWUSR, twl4030_bci_usb_show_enable,
+ twl4030_bci_usb_store_enable);
+
+static ssize_t show_charge_current(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret, val;
+ u8 ctl;
+
+ val = twl4030bci_read_adc_val(TWL4030_BCIIREF1);
+ if (val < 0)
+ return val;
+ ret = twl4030_bci_read(TWL4030_BCICTL1, &ctl);
+ if (ret < 0)
+ return ret;
+
+ val &= 0x1ff;
+ if (ctl & TWL4030_CGAIN)
+ val |= 0x200;
+
+ return sprintf(buf, "%d\n", val);
+}
+
+static ssize_t store_charge_current(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ struct power_supply *psy = dev_get_drvdata(dev);
+ struct twl4030_bci *bci = dev_get_drvdata(psy->dev->parent);
+ unsigned long new_current;
+ int ret;
+
+ ret = strict_strtoul(buf, 10, &new_current);
+ if (ret)
+ return -EINVAL;
+
+ ret = set_charge_current(bci, new_current);
+ if (ret)
+ return ret;
+
+ if (psy->type == POWER_SUPPLY_TYPE_MAINS)
+ bci->ac_current = new_current;
+ else
+ bci->usb_current = new_current;
+
+ return count;
+}
+static DEVICE_ATTR(charge_current, S_IRUGO | S_IWUSR, show_charge_current,
+ store_charge_current);
+
+static struct attribute *bci_ac_attrs[] = {
+ &dev_attr_enable_ac.attr,
+ &dev_attr_charge_current.attr,
+ NULL,
+};
+
+static struct attribute *bci_usb_attrs[] = {
+ &dev_attr_enable_usb.attr,
+ &dev_attr_charge_current.attr,
+ NULL,
+};
+
+static const struct attribute_group bci_ac_attr_group = {
+ .attrs = bci_ac_attrs,
+};
+
+static const struct attribute_group bci_usb_attr_group = {
+ .attrs = bci_usb_attrs,
+};
+