bq2415x_charger: Add support for offline and 100mA mode
[kernel-power] / kernel-power-2.6.28 / debian / patches / bq2415x_charger.patch
index a2796b8..5fd90ed 100644 (file)
@@ -1,6 +1,6 @@
 --- /dev/null
 +++ kernel-power/drivers/power/bq2415x_charger.c
-@@ -0,0 +1,1569 @@
+@@ -0,0 +1,1655 @@
 +/*
 +    bq2415x_charger.c - bq2415x charger driver
 +    Copyright (C) 2011-2012  Pali Rohár <pali.rohar@gmail.com>
@@ -31,6 +31,7 @@
 +*/
 +
 +#include <linux/version.h>
++#include <linux/kernel.h>
 +#include <linux/module.h>
 +#include <linux/param.h>
 +#include <linux/err.h>
@@ -44,7 +45,8 @@
 +
 +#include <linux/power/bq2415x_charger.h>
 +
-+#define BQ2415X_TIMER_TIMEOUT 10
++/* timeout for resetting chip timer */
++#define BQ2415X_TIMER_TIMEOUT         10
 +
 +#define BQ2415X_REG_STATUS            0x00
 +#define BQ2415X_REG_CONTROL           0x01
 +#define BQ2415X_SHIFT_REVISION                0
 +
 +/* current register */
-+/* RESET                              BIT(7) */
-+#define BQ2415X_MASK_VI_CHRG          (BIT(4)|BIT(5)|BIT(6)|BIT(7))
++#define BQ2415X_MASK_RESET            BIT(7)
++#define BQ2415X_MASK_VI_CHRG          (BIT(4)|BIT(5)|BIT(6))
 +#define BQ2415X_SHIFT_VI_CHRG         4
 +/* N/A                                        BIT(3) */
-+#define BQ2415X_MASK_VI_TERM          (BIT(0)|BIT(1)|BIT(2)|BIT(7))
++#define BQ2415X_MASK_VI_TERM          (BIT(0)|BIT(1)|BIT(2))
 +#define BQ2415X_SHIFT_VI_TERM         0
 +
 +
 +      enum bq2415x_mode reported_mode;/* mode reported by hook function */
 +      enum bq2415x_mode mode;         /* current configured mode */
 +      enum bq2415x_chip chip;
++      const char *timer_error;
 +      char *model;
 +      char *name;
 +      int autotimer;  /* 1 - if driver automatically reset timer, 0 - not */
 +      int id;
 +};
 +
++/* each registered chip must have unique id */
 +static DEFINE_IDR(bq2415x_id);
 +
 +static DEFINE_MUTEX(bq2415x_id_mutex);
 +static DEFINE_MUTEX(bq2415x_timer_mutex);
 +static DEFINE_MUTEX(bq2415x_i2c_mutex);
 +
-+/* i2c read functions */
++/**** i2c read functions ****/
 +
++/* read value from register */
 +static int bq2415x_i2c_read(struct bq2415x_device *bq, u8 reg)
 +{
 +      struct i2c_client *client = to_i2c_client(bq->dev);
 +      return val;
 +}
 +
++/* read value from register, apply mask and right shift it */
 +static int bq2415x_i2c_read_mask(struct bq2415x_device *bq, u8 reg,
 +                              u8 mask, u8 shift)
 +{
 +              return (ret & mask) >> shift;
 +}
 +
++/* read value from register and return one specified bit */
 +static int bq2415x_i2c_read_bit(struct bq2415x_device *bq, u8 reg, u8 bit)
 +{
 +      if (bit > 8)
 +              return bq2415x_i2c_read_mask(bq, reg, BIT(bit), bit);
 +}
 +
-+/* i2c write functions */
++/**** i2c write functions ****/
 +
++/* write value to register */
 +static int bq2415x_i2c_write(struct bq2415x_device *bq, u8 reg, u8 val)
 +{
 +      struct i2c_client *client = to_i2c_client(bq->dev);
 +      return 0;
 +}
 +
++/* read value from register, change it with mask left shifted and write back */
 +static int bq2415x_i2c_write_mask(struct bq2415x_device *bq, u8 reg, u8 val,
 +                              u8 mask, u8 shift)
 +{
 +      return bq2415x_i2c_write(bq, reg, ret);
 +}
 +
++/* change only one bit in register */
 +static int bq2415x_i2c_write_bit(struct bq2415x_device *bq, u8 reg,
 +                              bool val, u8 bit)
 +{
 +              return bq2415x_i2c_write_mask(bq, reg, val, BIT(bit), bit);
 +}
 +
-+/* global exec command function */
++/**** global functions ****/
 +
++/* exec command function */
 +static int bq2415x_exec_command(struct bq2415x_device *bq,
 +                              enum bq2415x_command command)
 +{
 +      }
 +}
 +
-+/* global detect chip */
-+
++/* detect chip type */
 +static enum bq2415x_chip bq2415x_detect_chip(struct bq2415x_device *bq)
 +{
 +      struct i2c_client *client = to_i2c_client(bq->dev);
 +      return BQUNKNOWN;
 +}
 +
++/* detect chip revision */
 +static int bq2415x_detect_revision(struct bq2415x_device *bq)
 +{
 +      int ret = bq2415x_exec_command(bq, BQ2415X_REVISION);
 +      return -1;
 +}
 +
++/* return chip vender code */
 +static int bq2415x_get_vender_code(struct bq2415x_device *bq)
 +{
 +      int ret = bq2415x_exec_command(bq, BQ2415X_VENDER_CODE);
 +                      ((ret >> 2) & 0x1) * 100;
 +}
 +
-+/* global other functions */
-+
++/* reset all chip registers to default state */
 +static void bq2415x_reset_chip(struct bq2415x_device *bq)
 +{
 +      bq2415x_i2c_write(bq, BQ2415X_REG_CURRENT, BQ2415X_RESET_CURRENT);
 +      bq2415x_i2c_write(bq, BQ2415X_REG_VOLTAGE, BQ2415X_RESET_VOLTAGE);
 +      bq2415x_i2c_write(bq, BQ2415X_REG_CONTROL, BQ2415X_RESET_CONTROL);
 +      bq2415x_i2c_write(bq, BQ2415X_REG_STATUS, BQ2415X_RESET_STATUS);
++      bq->timer_error = NULL;
 +}
 +
++/**** properties functions ****/
++
++/* set current limit in mA */
 +static int bq2415x_set_current_limit(struct bq2415x_device *bq, int mA)
 +{
 +      int val;
 +                      BQ2415X_MASK_LIMIT, BQ2415X_SHIFT_LIMIT);
 +}
 +
++/* get current limit in mA */
 +static int bq2415x_get_current_limit(struct bq2415x_device *bq)
 +{
 +      int ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CONTROL,
 +              return -EINVAL;
 +}
 +
++/* set weak battery voltage in mV */
 +static int bq2415x_set_weak_battery_voltage(struct bq2415x_device *bq, int mV)
 +{
 +      /* round to 100mV */
 +                      BQ2415X_MASK_VLOWV, BQ2415X_SHIFT_VLOWV);
 +}
 +
++/* get weak battery voltage in mV */
 +static int bq2415x_get_weak_battery_voltage(struct bq2415x_device *bq)
 +{
 +      int ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_CONTROL,
 +              return 100 * (34 + ret);
 +}
 +
++/* set battery regulation voltage in mV */
 +static int bq2415x_set_battery_regulation_voltage(struct bq2415x_device *bq,
 +                                              int mV)
 +{
 +                      BQ2415X_MASK_VO, BQ2415X_SHIFT_VO);
 +}
 +
++/* get battery regulation voltage in mV */
 +static int bq2415x_get_battery_regulation_voltage(struct bq2415x_device *bq)
 +{
 +      int ret = bq2415x_i2c_read_mask(bq, BQ2415X_REG_VOLTAGE,
 +              return 10 * (350 + 2*ret);
 +}
 +
++/* set charge current in mA (platform data must provide resistor sense) */
 +static int bq2415x_set_charge_current(struct bq2415x_device *bq, int mA)
 +{
 +      int val;
 +              val = 7;
 +
 +      return bq2415x_i2c_write_mask(bq, BQ2415X_REG_CURRENT, val,
-+                      BQ2415X_MASK_VI_CHRG, BQ2415X_SHIFT_VI_CHRG);
++                      BQ2415X_MASK_VI_CHRG | BQ2415X_MASK_RESET,
++                      BQ2415X_SHIFT_VI_CHRG);
 +}
 +
++/* get charge current in mA (platform data must provide resistor sense) */
 +static int bq2415x_get_charge_current(struct bq2415x_device *bq)
 +{
 +      int ret;
 +              return (37400 + 6800*ret) / bq->init_data.resistor_sense;
 +}
 +
++/* set termination current in mA (platform data must provide resistor sense) */
 +static int bq2415x_set_termination_current(struct bq2415x_device *bq, int mA)
 +{
 +      int val;
 +              val = 7;
 +
 +      return bq2415x_i2c_write_mask(bq, BQ2415X_REG_CURRENT, val,
-+                      BQ2415X_MASK_VI_TERM, BQ2415X_SHIFT_VI_TERM);
++                      BQ2415X_MASK_VI_TERM | BQ2415X_MASK_RESET,
++                      BQ2415X_SHIFT_VI_TERM);
 +}
 +
++/* get termination current in mA (platform data must provide resistor sense) */
 +static int bq2415x_get_termination_current(struct bq2415x_device *bq)
 +{
 +      int ret;
 +              return (3400 + 3400*ret) / bq->init_data.resistor_sense;
 +}
 +
-+#define bq2415x_set_default_value(bq, value) \
++/* set default value of property */
++#define bq2415x_set_default_value(bq, prop) \
 +      do { \
 +              int ret = 0; \
-+              if (bq->init_data.value != -1) \
-+                      ret = bq2415x_set_##value(bq, bq->init_data.value); \
++              if (bq->init_data.prop != -1) \
++                      ret = bq2415x_set_##prop(bq, bq->init_data.prop); \
 +              if (ret < 0) \
 +                      return ret; \
 +      } while (0)
 +
++/* set default values of all properties */
 +static int bq2415x_set_defaults(struct bq2415x_device *bq)
 +{
 +      bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_DISABLE);
 +      bq2415x_exec_command(bq, BQ2415X_CHARGER_DISABLE);
++      bq2415x_exec_command(bq, BQ2415X_CHARGE_TERMINATION_DISABLE);
 +      bq2415x_set_default_value(bq, current_limit);
 +      bq2415x_set_default_value(bq, weak_battery_voltage);
 +      bq2415x_set_default_value(bq, battery_regulation_voltage);
 +      return 0;
 +}
 +
-+#undef bq2415x_set_default_value
-+
-+/* charger mode functions */
++/**** charger mode functions ****/
 +
++/* set charger mode */
 +static int bq2415x_set_mode(struct bq2415x_device *bq, enum bq2415x_mode mode)
 +{
 +      int ret = 0;
 +      int charger = 0;
++      int boost = 0;
 +
-+      if (mode == BQ2415X_MODE_NONE ||
-+              mode == BQ2415X_MODE_HOST_CHARGER ||
-+              mode == BQ2415X_MODE_DEDICATED_CHARGER)
-+                      charger = 1;
++      if (mode == BQ2415X_MODE_BOOST)
++              boost = 1;
++      else if (mode != BQ2415X_MODE_OFF)
++              charger = 1;
 +
-+      if (charger)
-+              ret = bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_DISABLE);
-+      else
++      if (!charger)
 +              ret = bq2415x_exec_command(bq, BQ2415X_CHARGER_DISABLE);
 +
++      if (!boost)
++              ret = bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_DISABLE);
++
 +      if (ret < 0)
 +              return ret;
 +
 +      switch (mode) {
++      case BQ2415X_MODE_OFF:
++              dev_dbg(bq->dev, "changing mode to: Offline\n");
++              ret = bq2415x_set_current_limit(bq, 100);
++              break;
 +      case BQ2415X_MODE_NONE:
-+              dev_info(bq->dev, "mode: N/A\n");
++              dev_dbg(bq->dev, "changing mode to: N/A\n");
 +              ret = bq2415x_set_current_limit(bq, 100);
 +              break;
 +      case BQ2415X_MODE_HOST_CHARGER:
-+              dev_info(bq->dev, "mode: Host/HUB charger\n");
++              dev_dbg(bq->dev, "changing mode to: Host/HUB charger\n");
 +              ret = bq2415x_set_current_limit(bq, 500);
 +              break;
 +      case BQ2415X_MODE_DEDICATED_CHARGER:
-+              dev_info(bq->dev, "mode: Dedicated charger\n");
++              dev_dbg(bq->dev, "changing mode to: Dedicated charger\n");
 +              ret = bq2415x_set_current_limit(bq, 1800);
 +              break;
 +      case BQ2415X_MODE_BOOST: /* Boost mode */
-+              dev_info(bq->dev, "mode: Boost\n");
++              dev_dbg(bq->dev, "changing mode to: Boost\n");
 +              ret = bq2415x_set_current_limit(bq, 100);
 +              break;
 +      }
 +
 +      if (charger)
 +              ret = bq2415x_exec_command(bq, BQ2415X_CHARGER_ENABLE);
-+      else
++      else if (boost)
 +              ret = bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_ENABLE);
 +
 +      if (ret < 0)
 +              return ret;
 +
++      bq2415x_set_default_value(bq, weak_battery_voltage);
++      bq2415x_set_default_value(bq, battery_regulation_voltage);
++
 +      bq->mode = mode;
++      sysfs_notify(&bq->charger.dev->kobj, NULL, "mode");
++
 +      return 0;
 +
 +}
 +
++/* hook function called by other driver which set reported mode */
 +static void bq2415x_hook_function(enum bq2415x_mode mode, void *data)
 +{
 +      struct bq2415x_device *bq = data;
 +      if (!bq)
 +              return;
 +
++      dev_dbg(bq->dev, "hook function was called\n");
 +      bq->reported_mode = mode;
 +
++      /* if automode is not enabled do not tell about reported_mode */
 +      if (bq->automode < 1)
 +              return;
 +
++      sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode");
 +      bq2415x_set_mode(bq, bq->reported_mode);
 +
 +}
 +
-+/* timer functions */
++/**** timer functions ****/
 +
++/* enable/disable auto resetting chip timer */
 +static void bq2415x_set_autotimer(struct bq2415x_device *bq, int state)
 +{
 +      mutex_lock(&bq2415x_timer_mutex);
 +      if (state) {
 +              schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ);
 +              bq2415x_exec_command(bq, BQ2415X_TIMER_RESET);
++              bq->timer_error = NULL;
 +      } else {
 +              cancel_delayed_work_sync(&bq->work);
 +      }
 +      mutex_unlock(&bq2415x_timer_mutex);
 +}
 +
++/* called by bq2415x_timer_work on timer error */
 +static void bq2415x_timer_error(struct bq2415x_device *bq, const char *msg)
 +{
++      bq->timer_error = msg;
++      sysfs_notify(&bq->charger.dev->kobj, NULL, "timer");
 +      dev_err(bq->dev, "%s\n", msg);
 +      if (bq->automode > 0)
 +              bq->automode = 0;
-+      bq2415x_set_mode(bq, BQ2415X_MODE_NONE);
++      bq2415x_set_mode(bq, BQ2415X_MODE_OFF);
 +      bq2415x_set_autotimer(bq, 0);
 +}
 +
++/* delayed work function for auto resetting chip timer */
 +static void bq2415x_timer_work(struct work_struct *work)
 +{
 +      struct bq2415x_device *bq = container_of(work, struct bq2415x_device,
 +
 +      ret = bq2415x_exec_command(bq, BQ2415X_TIMER_RESET);
 +      if (ret < 0) {
-+              bq2415x_timer_error(bq, "Reseting timer failed");
++              bq2415x_timer_error(bq, "Resetting timer failed");
 +              return;
 +      }
 +
 +      boost = bq2415x_exec_command(bq, BQ2415X_BOOST_MODE_STATUS);
 +      if (boost < 0) {
-+              bq2415x_timer_error(bq, "Unknow error");
++              bq2415x_timer_error(bq, "Unknown error");
 +              return;
 +      }
 +
 +      error = bq2415x_exec_command(bq, BQ2415X_FAULT_STATUS);
 +      if (error < 0) {
-+              bq2415x_timer_error(bq, "Unknow error");
++              bq2415x_timer_error(bq, "Unknown error");
 +              return;
 +      }
 +
 +      if (boost) {
 +              switch (error) {
++              /* Non fatal errors, chip is OK */
 +              case 0: /* No error */
 +                      break;
 +              case 6: /* Timer expired */
 +                      dev_err(bq->dev, "Battery voltage to low\n");
 +                      break;
 +
++              /* Fatal errors, disable and reset chip */
 +              case 1: /* Overvoltage protection (chip fried) */
 +                      bq2415x_timer_error(bq,
-+                              "Overvolatge protection (chip fried)");
++                              "Overvoltage protection (chip fried)");
 +                      return;
 +              case 2: /* Overload */
 +                      bq2415x_timer_error(bq, "Overload");
 +              }
 +      } else {
 +              switch (error) {
++              /* Non fatal errors, chip is OK */
 +              case 0: /* No error */
 +                      break;
 +              case 2: /* Sleep mode */
 +                      dev_err(bq->dev, "No battery\n");
 +                      break;
 +
++              /* Fatal errors, disable and reset chip */
 +              case 1: /* Overvoltage protection (chip fried) */
 +                      bq2415x_timer_error(bq,
-+                              "Overvolatge protection (chip fried)");
++                              "Overvoltage protection (chip fried)");
 +                      return;
 +              case 4: /* Battery overvoltage protection */
 +                      bq2415x_timer_error(bq,
 +      schedule_delayed_work(&bq->work, BQ2415X_TIMER_TIMEOUT * HZ);
 +}
 +
-+/* power supply */
++/**** power supply interface code ****/
 +
 +static enum power_supply_property bq2415x_power_supply_props[] = {
-+      /* TODO: more power supply properties */
++      /* TODO: maybe add more power supply properties */
 +      POWER_SUPPLY_PROP_STATUS,
 +      POWER_SUPPLY_PROP_MODEL_NAME,
 +};
 +      kfree(bq->model);
 +}
 +
-+/* sysfs files */
++/**** additional sysfs entries for power supply interface ****/
 +
++/* show *_status entries */
 +static ssize_t bq2415x_sysfs_show_status(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +              return sprintf(buf, "%d\n", ret);
 +}
 +
++/* set timer entry:
++     auto - enable auto mode
++     off - disable auto mode
++     (other values) - reset chip timer
++*/
 +static ssize_t bq2415x_sysfs_set_timer(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t count)
 +{
 +              return count;
 +}
 +
++/* show timer entry (auto or off) */
 +static ssize_t bq2415x_sysfs_show_timer(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
 +                                              charger);
 +
++      if (bq->timer_error)
++              return sprintf(buf, "%s\n", bq->timer_error);
++
 +      if (bq->autotimer)
 +              return sprintf(buf, "auto\n");
 +      else
 +              return sprintf(buf, "off\n");
 +}
 +
++/* set mode entry:
++     auto - if automode is supported, enable it and set mode to reported
++     none - disable charger and boost mode
++     host - charging mode for host/hub chargers (current limit 500mA)
++     dedicated - charging mode for dedicated chargers (unlimited current limit)
++     boost - disable charger and enable boost mode
++*/
 +static ssize_t bq2415x_sysfs_set_mode(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t count)
 +{
 +                      return -ENOSYS;
 +              bq->automode = 1;
 +              mode = bq->reported_mode;
++      } else if (strncmp(buf, "off", 3) == 0) {
++              if (bq->automode > 0)
++                      bq->automode = 0;
++              mode = BQ2415X_MODE_OFF;
 +      } else if (strncmp(buf, "none", 4) == 0) {
 +              if (bq->automode > 0)
 +                      bq->automode = 0;
 +      } else if (strncmp(buf, "reset", 5) == 0) {
 +              bq2415x_reset_chip(bq);
 +              bq2415x_set_defaults(bq);
-+              if (bq->automode > 0)
-+                      bq->automode = 1;
-+              return count;
++              if (bq->automode <= 0)
++                      return count;
++              bq->automode = 1;
++              mode = bq->reported_mode;
 +      } else
 +              return -EINVAL;
 +
 +              return count;
 +}
 +
++/* show mode entry (auto, none, host, dedicated or boost) */
 +static ssize_t bq2415x_sysfs_show_mode(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +              ret += sprintf(buf+ret, "auto (");
 +
 +      switch (bq->mode) {
++      case BQ2415X_MODE_OFF:
++              ret += sprintf(buf+ret, "off");
++              break;
 +      case BQ2415X_MODE_NONE:
 +              ret += sprintf(buf+ret, "none");
 +              break;
 +      return ret;
 +}
 +
++/* show reported_mode entry (none, host, dedicated or boost) */
 +static ssize_t bq2415x_sysfs_show_reported_mode(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
 +                                              charger);
 +
++      if (bq->automode < 0)
++              return -EINVAL;
++
 +      switch (bq->reported_mode) {
++      case BQ2415X_MODE_OFF:
++              return sprintf(buf, "off\n");
 +      case BQ2415X_MODE_NONE:
 +              return sprintf(buf, "none\n");
 +      case BQ2415X_MODE_HOST_CHARGER:
 +      return -EINVAL;
 +}
 +
++/* directly set raw value to chip register, format: 'register value' */
 +static ssize_t bq2415x_sysfs_set_registers(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t count)
 +{
 +      struct bq2415x_device *bq = container_of(psy, struct bq2415x_device,
 +                                              charger);
 +      ssize_t ret = 0;
-+      char *end;
-+      int reg;
-+      int val;
++      unsigned int reg;
++      unsigned int val;
 +
-+      reg = simple_strtol(buf, &end, 16);
-+      if (reg < 0 || reg > 4)
++      if (sscanf(buf, "%x %x", &reg, &val) != 2)
 +              return -EINVAL;
 +
-+      val = simple_strtol(end+1, NULL, 16);
-+      if (val < 0 || val > 255)
++      if (reg > 4 || val > 255)
 +              return -EINVAL;
 +
 +      ret = bq2415x_i2c_write(bq, reg, val);
 +              return count;
 +}
 +
++/* print value of chip register, format: 'register=value' */
 +static ssize_t bq2415x_sysfs_print_reg(struct bq2415x_device *bq,
 +                                      u8 reg, char *buf)
 +{
 +              return sprintf(buf, "%#.2x=%#.2x\n", reg, ret);
 +}
 +
++/* show all raw values of chip register, format per line: 'register=value' */
 +static ssize_t bq2415x_sysfs_show_registers(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      return ret;
 +}
 +
-+/* Current & Volatage settings */
-+
++/* set current and voltage limit entries (in mA or mV) */
 +static ssize_t bq2415x_sysfs_set_limit(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t count)
 +{
 +      long val;
 +      int ret;
 +
-+      if (strict_strtol(buf, 10, &val) < 0)
++      if (kstrtol(buf, 10, &val) < 0)
 +              return -EINVAL;
 +
 +      if (strcmp(attr->attr.name, "current_limit") == 0)
 +              return count;
 +}
 +
++/* show current and voltage limit entries (in mA or mV) */
 +static ssize_t bq2415x_sysfs_show_limit(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +              return sprintf(buf, "%d\n", ret);
 +}
 +
++/* set *_enable entries */
 +static ssize_t bq2415x_sysfs_set_enable(struct device *dev,
 +              struct device_attribute *attr, const char *buf, size_t count)
 +{
 +      long val;
 +      int ret;
 +
-+      if (strict_strtol(buf, 10, &val) < 0)
++      if (kstrtol(buf, 10, &val) < 0)
 +              return -EINVAL;
 +
 +      if (strcmp(attr->attr.name, "charge_termination_enable") == 0)
 +              return count;
 +}
 +
++/* show *_enable entries */
 +static ssize_t bq2415x_sysfs_show_enable(struct device *dev,
 +              struct device_attribute *attr, char *buf)
 +{
 +      sysfs_remove_group(&bq->charger.dev->kobj, &bq2415x_sysfs_attr_group);
 +}
 +
-+/* bq2415x register */
-+
++/* main bq2415x probe function */
 +static int bq2415x_probe(struct i2c_client *client,
 +              const struct i2c_device_id *id)
 +{
 +      bq->dev = &client->dev;
 +      bq->chip = id->driver_data;
 +      bq->name = name;
-+      bq->mode = BQ2415X_MODE_NONE;
-+      bq->reported_mode = BQ2415X_MODE_NONE;
++      bq->mode = BQ2415X_MODE_OFF;
++      bq->reported_mode = BQ2415X_MODE_OFF;
 +      bq->autotimer = 0;
 +      bq->automode = 0;
 +
 +      INIT_DELAYED_WORK(&bq->work, bq2415x_timer_work);
 +      bq2415x_set_autotimer(bq, 1);
 +
-+      dev_info(bq->dev, "driver registred\n");
++      dev_info(bq->dev, "driver registered\n");
 +      return 0;
 +
 +error_5:
 +      return ret;
 +}
 +
-+/* bq2415x unregister */
++/* main bq2415x remove function */
 +
 +static int bq2415x_remove(struct i2c_client *client)
 +{
 +      idr_remove(&bq2415x_id, bq->id);
 +      mutex_unlock(&bq2415x_id_mutex);
 +
-+      dev_info(bq->dev, "driver unregistred\n");
++      dev_info(bq->dev, "driver unregistered\n");
 +
 +      kfree(bq->name);
 +      kfree(bq);
 +MODULE_LICENSE("GPL");
 --- /dev/null
 +++ kernel-power/include/linux/power/bq2415x_charger.h
-@@ -0,0 +1,90 @@
+@@ -0,0 +1,91 @@
 +/*
 +    bq2415x_charger.h - bq2415x charger driver
 +    Copyright (C) 2011-2012  Pali Rohár <pali.rohar@gmail.com>
 +    platform_data->set_mode_hook(bq2415x_hook_function, bq2415x_device);
 +
 +  Board/platform function set_mode_hook return non zero value when hook
-+  function was successfull registred. Platform code should call that hook
++  function was successful registered. Platform code should call that hook
 +  function (which get from pointer, with data) every time when charger was
 +  connected/disconnected or require to enable boost mode. bq2415x driver then
 +  will set correct current limit, enable/disable charger or boost mode.
 +
 +  (hook function and driver private data are NULL)
 +
-+  After thet board/platform code must not call driver hook function! It is
++  After that board/platform code must not call driver hook function! It is
 +  possible that pointer to hook function will not be valid and calling will
 +  cause undefined result.
 +
 +
 +/* Supported modes with maximal current limit */
 +enum bq2415x_mode {
-+      BQ2415X_MODE_NONE,              /* unknown or no charger (100mA) */
++      BQ2415X_MODE_OFF,               /* offline mode (charger disabled) */
++      BQ2415X_MODE_NONE,              /* unknown charger (100mA) */
 +      BQ2415X_MODE_HOST_CHARGER,      /* usb host/hub charger (500mA) */
 +      BQ2415X_MODE_DEDICATED_CHARGER, /* dedicated charger (unlimited) */
 +      BQ2415X_MODE_BOOST,             /* boost mode (charging disabled) */