--- /dev/null
+++ kernel-power/drivers/power/bq2415x_charger.c
-@@ -0,0 +1,1543 @@
+@@ -0,0 +1,1569 @@
+/*
+ bq2415x_charger.c - bq2415x charger driver
+ Copyright (C) 2011-2012 Pali Rohár <pali.rohar@gmail.com>
+
+static int bq2415x_set_weak_battery_voltage(struct bq2415x_device *bq, int mV)
+{
-+ int val = mV/100 + (mV%100 > 0 ? 1 : 0) - 34;
-+
-+ if (val < 0)
++ /* round to 100mV */
++ int val;
++ if (mV <= 3400 + 50)
+ val = 0;
-+ else if (val > 3)
++ else if (mV <= 3500 + 50)
++ val = 1;
++ else if (mV <= 3600 + 50)
++ val = 2;
++ else
+ val = 3;
-+
+ return bq2415x_i2c_write_mask(bq, BQ2415X_REG_CONTROL, val,
+ BQ2415X_MASK_VLOWV, BQ2415X_SHIFT_VLOWV);
+}
+static int bq2415x_set_battery_regulation_voltage(struct bq2415x_device *bq,
+ int mV)
+{
-+ int val = (mV/10 + (mV%10 > 0 ? 1 : 0) - 350) / 2;
++ int val = (mV/10 - 350) / 2;
+
+ if (val < 0)
+ val = 0;
-+ else if (val > 94) /* FIXME: Max is 94 or 122 ? */
++ else if (val > 94) /* FIXME: Max is 94 or 122 ? Set max value ? */
+ return -EINVAL;
+
+ return bq2415x_i2c_write_mask(bq, BQ2415X_REG_VOLTAGE, val,
+ if (bq->init_data.resistor_sense <= 0)
+ return -ENOSYS;
+
-+ val = (mA * bq->init_data.resistor_sense - 37400);
-+ val = val/6800 + (val%6800 > 0 ? 1 : 0);
++ val = (mA * bq->init_data.resistor_sense - 37400) / 6800;
+
+ if (val < 0)
+ val = 0;
+ if (bq->init_data.resistor_sense <= 0)
+ return -ENOSYS;
+
-+ val = (mA * bq->init_data.resistor_sense - 3400);
-+ val = val/3400 + (val%3400 > 0 ? 1 : 0);
++ val = (mA * bq->init_data.resistor_sense - 3400) / 3400;
+
+ if (val < 0)
+ val = 0;
+ return ret;
+}
+
++static ssize_t bq2415x_sysfs_show_reported_mode(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct power_supply *psy = dev_get_drvdata(dev);
++ struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
++ charger);
++
++ switch (bq->reported_mode) {
++ case BQ2415X_MODE_NONE:
++ return sprintf(buf, "none\n");
++ case BQ2415X_MODE_HOST_CHARGER:
++ return sprintf(buf, "host\n");
++ case BQ2415X_MODE_DEDICATED_CHARGER:
++ return sprintf(buf, "dedicated\n");
++ case BQ2415X_MODE_BOOST:
++ return sprintf(buf, "boost\n");
++ }
++
++ return -EINVAL;
++}
++
+static ssize_t bq2415x_sysfs_set_registers(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+static DEVICE_ATTR(stat_pin_enable, S_IWUSR | S_IRUGO,
+ bq2415x_sysfs_show_enable, bq2415x_sysfs_set_enable);
+
++static DEVICE_ATTR(reported_mode, S_IRUGO,
++ bq2415x_sysfs_show_reported_mode, NULL);
+static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO,
+ bq2415x_sysfs_show_mode, bq2415x_sysfs_set_mode);
+static DEVICE_ATTR(timer, S_IWUSR | S_IRUGO,
+ &dev_attr_otg_pin_enable.attr,
+ &dev_attr_stat_pin_enable.attr,
+
++ &dev_attr_reported_mode.attr,
+ &dev_attr_mode.attr,
+ &dev_attr_timer.attr,
+
+ if (bq->init_data.set_mode_hook(
+ bq2415x_hook_function, bq)) {
+ bq->automode = 1;
++ bq2415x_set_mode(bq, bq->reported_mode);
+ dev_info(bq->dev, "automode enabled\n");
+ } else {
+ bq->automode = -1;
#define RX51_DEBUG_BASE 0x08000000 /* debug board */
#define RX51_ETHR_START RX51_DEBUG_BASE
-@@ -563,6 +565,80 @@ static struct i2c_board_info __initdata
+@@ -563,6 +565,81 @@ static struct i2c_board_info __initdata
},
};
+{
+ rx51_charger_hook = hook;
+ rx51_charger_hook_data = data;
++ rx51_charger_hook(rx51_charger_mode, rx51_charger_hook_data);
+ return 1;
+}
+
static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = {
{
I2C_BOARD_INFO("lp5523", 0x32),
-@@ -575,6 +636,10 @@ static struct i2c_board_info __initdata
+@@ -575,6 +637,10 @@ static struct i2c_board_info __initdata
{
I2C_BOARD_INFO("bq27200", 0x55),
},