bq2415x_charger: Add support for offline and 100mA mode
[kernel-power] / kernel-power-2.6.28 / debian / patches / bq2415x_charger.patch
index 40217e2..5fd90ed 100644 (file)
@@ -1,6 +1,6 @@
 --- /dev/null
 +++ kernel-power/drivers/power/bq2415x_charger.c
-@@ -0,0 +1,1637 @@
+@@ -0,0 +1,1655 @@
 +/*
 +    bq2415x_charger.c - bq2415x charger driver
 +    Copyright (C) 2011-2012  Pali Rohár <pali.rohar@gmail.com>
 +      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 */
 +      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 ****/
 +      int charger = 0;
 +      int boost = 0;
 +
-+      if (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_CHARGER_DISABLE);
 +              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_dbg(bq->dev, "changing mode to: N/A\n");
 +              ret = bq2415x_set_current_limit(bq, 100);
 +      if (!bq)
 +              return;
 +
-+      /* this should not happen, hook function is called only in automode */
++      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;
 +
-+      dev_dbg(bq->dev, "hook function was called\n");
-+
-+      bq->reported_mode = mode;
 +      sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode");
-+
 +      bq2415x_set_mode(bq, bq->reported_mode);
 +
 +}
 +      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);
 +      }
 +/* 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);
 +}
 +
 +      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 -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;
 +              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 -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:
 +      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;
 +
 +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>
 +
 +/* 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) */