summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2013-08-27 12:36:47 +0800
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-08-30 15:39:31 +0000
commitea41735a4cfc658642b861fd2f68dd451824ca74 (patch)
treee607a5ce7138005715748992b0abc0ecf263fb85 /common
parent8f79405766c0172e0e958ce54b0a2b6f4a7c8be6 (diff)
downloadchrome-ec-ea41735a4cfc658642b861fd2f68dd451824ca74.tar.gz
Add BQ24192 charger driver
This is the initial version of BQ24192 charger driver. For now, it only probes for BQ24192 chip on initialization and get BQ24192 into host mode. Also, charger_closest_current() is identical across all charger drivers. Let's move it to charger_common.c. BUG=chrome-os-partner:22238 TEST=Build all boards. Boot Kirby and see BQ24192 initialized. BRANCH=None Change-Id: I5291362ff0e69b281bffd6d609ce6dc48eb10898 Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/167457
Diffstat (limited to 'common')
-rw-r--r--common/build.mk1
-rw-r--r--common/charger_bq24192.c243
-rw-r--r--common/charger_bq24707a.c19
-rw-r--r--common/charger_bq24715.c19
-rw-r--r--common/charger_bq24725.c19
-rw-r--r--common/charger_bq24738.c19
-rw-r--r--common/charger_common.c19
-rw-r--r--common/mock_charger.c6
8 files changed, 263 insertions, 82 deletions
diff --git a/common/build.mk b/common/build.mk
index a1660ad119..429f27b744 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -24,6 +24,7 @@ common-$(CONFIG_BATTERY_BQ20Z453)+=battery_bq20z453.o
common-$(CONFIG_BATTERY_MOCK)+=mock_smart_battery_stub.o mock_charger.o
common-$(CONFIG_BATTERY_SMART)+=smart_battery.o smart_battery_stub.o
common-$(CONFIG_CHARGER)+=charge_state.o charger_common.o
+common-$(CONFIG_CHARGER_BQ24192)+=charger_bq24192.o
common-$(CONFIG_CHARGER_BQ24715)+=charger_bq24715.o
common-$(CONFIG_CHARGER_BQ24725)+=charger_bq24725.o
common-$(CONFIG_CHARGER_BQ24707A)+=charger_bq24707a.o
diff --git a/common/charger_bq24192.c b/common/charger_bq24192.c
new file mode 100644
index 0000000000..8939cc9e71
--- /dev/null
+++ b/common/charger_bq24192.c
@@ -0,0 +1,243 @@
+/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * TI bq24192 battery charger driver.
+ */
+
+#include "charger.h"
+#include "charger_bq24192.h"
+#include "common.h"
+#include "console.h"
+#include "hooks.h"
+#include "i2c.h"
+#include "printf.h"
+#include "util.h"
+
+/* Console output macros */
+#define CPUTS(outstr) cputs(CC_CHARGER, outstr)
+#define CPRINTF(format, args...) cprintf(CC_CHARGER, format, ## args)
+
+/* Charger information */
+static const struct charger_info bq24192_charger_info = {
+ .name = "bq24192",
+ .voltage_max = 4400,
+ .voltage_min = 3504,
+ .voltage_step = 16,
+ .current_max = 4544,
+ .current_min = 512,
+ .current_step = 64,
+ .input_current_max = 3000,
+ .input_current_min = 100,
+ .input_current_step = -1,
+};
+
+static const int input_current_steps[] = {
+ 100, 150, 500, 900, 1200, 1500, 2000, 3000};
+
+int bq24192_read(int reg, int *value)
+{
+ return i2c_read8(I2C_PORT_HOST, BQ24192_ADDR, reg, value);
+}
+
+int bq24192_write(int reg, int value)
+{
+ return i2c_write8(I2C_PORT_HOST, BQ24192_ADDR, reg, value);
+}
+
+static int bq24192_watchdog_reset(void)
+{
+ int rv, val;
+
+ rv = bq24192_read(BQ24192_REG_POWER_ON_CFG, &val);
+ if (rv)
+ return rv;
+ val |= (1 << 6);
+ return bq24192_write(BQ24192_REG_POWER_ON_CFG, val) ||
+ bq24192_write(BQ24192_REG_POWER_ON_CFG, val);
+}
+
+int charger_set_input_current(int input_current)
+{
+ int i, value, rv;
+
+ for (i = 1; i < ARRAY_SIZE(input_current_steps); ++i)
+ if (input_current_steps[i] > input_current) {
+ --i;
+ break;
+ }
+ if (i == ARRAY_SIZE(input_current_steps))
+ --i;
+
+ rv = bq24192_read(BQ24192_REG_INPUT_CTRL, &value);
+ if (rv)
+ return rv;
+ value = value & ~(0x7);
+ value |= (i & 0x7);
+ return bq24192_write(BQ24192_REG_INPUT_CTRL, value);
+}
+
+int charger_get_input_current(int *input_current)
+{
+ int rv, value;
+
+ rv = bq24192_read(BQ24192_REG_INPUT_CTRL, &value);
+ if (rv)
+ return rv;
+ return input_current_steps[value & 0x7];
+}
+
+int charger_manufacturer_id(int *id)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+int charger_device_id(int *id)
+{
+ return bq24192_read(BQ24192_REG_ID, id);
+}
+
+int charger_get_option(int *option)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+int charger_set_option(int option)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+const struct charger_info *charger_get_info(void)
+{
+ return &bq24192_charger_info;
+}
+
+int charger_get_status(int *status)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+int charger_set_mode(int mode)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+int charger_get_current(int *current)
+{
+ int rv, val;
+ const struct charger_info * const info = charger_get_info();
+
+ rv = bq24192_read(BQ24192_REG_CHG_CURRENT, &val);
+ if (rv)
+ return rv;
+ val = (val >> 2) & 0x3f;
+ *current = val * info->current_step + info->current_min;
+ return EC_SUCCESS;
+}
+
+/* TODO(victoryang): remove this after enabling charger task on Kirby */
+int charger_closest_current(int current)
+{
+ return current;
+}
+
+int charger_set_current(int current)
+{
+ int rv, val;
+ const struct charger_info * const info = charger_get_info();
+
+ current = charger_closest_current(current);
+ rv = bq24192_read(BQ24192_REG_CHG_CURRENT, &val);
+ if (rv)
+ return rv;
+ val = val & 0x3;
+ val |= ((current - info->current_min) / info->current_step) << 2;
+ return bq24192_write(BQ24192_REG_CHG_CURRENT, val);
+}
+
+int charger_get_voltage(int *voltage)
+{
+ int rv, val;
+ const struct charger_info * const info = charger_get_info();
+
+ rv = bq24192_read(BQ24192_REG_CHG_VOLTAGE, &val);
+ if (rv)
+ return rv;
+ val = (val >> 2) & 0x3f;
+ *voltage = val * info->voltage_step + info->voltage_min;
+ return EC_SUCCESS;
+}
+
+int charger_set_voltage(int voltage)
+{
+ int rv, val;
+ const struct charger_info * const info = charger_get_info();
+
+ rv = bq24192_read(BQ24192_REG_CHG_VOLTAGE, &val);
+ if (rv)
+ return rv;
+ val = val & 0x3;
+ val |= ((voltage - info->voltage_min) / info->voltage_step) << 2;
+ return bq24192_write(BQ24192_REG_CHG_VOLTAGE, val);
+}
+
+
+/*****************************************************************************/
+/* Hooks */
+
+static void bq24192_init(void)
+{
+ int val, rv;
+
+ if (charger_device_id(&val) || val != BQ24192_DEVICE_ID) {
+ CPRINTF("[%T BQ24192 incorrent ID: 0x%02x]\n", val);
+ return;
+ }
+
+ /*
+ * Disable I2C watchdog timer.
+ * TODO(victoryang): Re-enable watchdog timer and kick it periodically
+ * in charger task.
+ */
+ rv = bq24192_read(BQ24192_REG_CHG_TERM_TMR, &val);
+ if (rv)
+ return;
+ val &= ~0x30;
+ rv = bq24192_write(BQ24192_REG_CHG_TERM_TMR, val);
+ if (rv)
+ return;
+
+ if (bq24192_watchdog_reset())
+ return;
+
+ CPRINTF("[%T BQ24192 initialized]\n");
+}
+DECLARE_HOOK(HOOK_INIT, bq24192_init, HOOK_PRIO_LAST);
+
+/*****************************************************************************/
+/* Console commands */
+
+static int command_bq24192(int argc, char **argv)
+{
+ int i;
+ int value;
+ int rv;
+
+ ccprintf("REG:");
+ for (i = 0; i <= 0xa; ++i)
+ ccprintf(" %02x", i);
+ ccprintf("\n");
+
+ ccprintf("VAL:");
+ for (i = 0; i <= 0xa; ++i) {
+ rv = bq24192_read(i, &value);
+ if (rv)
+ return rv;
+ ccprintf(" %02x", value);
+ }
+ ccprintf("\n");
+
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(bq24192, command_bq24192,
+ NULL, NULL, NULL);
diff --git a/common/charger_bq24707a.c b/common/charger_bq24707a.c
index 9538318997..e6afa629da 100644
--- a/common/charger_bq24707a.c
+++ b/common/charger_bq24707a.c
@@ -135,25 +135,6 @@ int charger_get_current(int *current)
return EC_SUCCESS;
}
-int charger_closest_current(int current)
-{
- const struct charger_info * const info = charger_get_info();
-
- /*
- * If the requested current is non-zero but below our minimum,
- * return the minimum. See crosbug.com/p/8662.
- */
- if (current > 0 && current < info->current_min)
- return info->current_min;
-
- /* Clip to max */
- if (current > info->current_max)
- return info->current_max;
-
- /* Otherwise round down to nearest current step */
- return current - (current % info->current_step);
-}
-
int charger_set_current(int current)
{
current = charger_closest_current(current);
diff --git a/common/charger_bq24715.c b/common/charger_bq24715.c
index 66d178a4c3..56e8b6ee34 100644
--- a/common/charger_bq24715.c
+++ b/common/charger_bq24715.c
@@ -129,25 +129,6 @@ int charger_get_current(int *current)
return EC_SUCCESS;
}
-int charger_closest_current(int current)
-{
- const struct charger_info * const info = charger_get_info();
-
- /*
- * If the requested current is non-zero but below our minimum,
- * return the minimum. See crosbug.com/p/8662.
- */
- if (current > 0 && current < info->current_min)
- return info->current_min;
-
- /* Clip to max */
- if (current > info->current_max)
- return info->current_max;
-
- /* Otherwise round down to nearest current step */
- return current - (current % info->current_step);
-}
-
int charger_set_current(int current)
{
current = charger_closest_current(current);
diff --git a/common/charger_bq24725.c b/common/charger_bq24725.c
index d69b3edf13..64eb81400b 100644
--- a/common/charger_bq24725.c
+++ b/common/charger_bq24725.c
@@ -134,25 +134,6 @@ int charger_get_current(int *current)
return EC_SUCCESS;
}
-int charger_closest_current(int current)
-{
- const struct charger_info * const info = charger_get_info();
-
- /*
- * If the requested current is non-zero but below our minimum,
- * return the minimum. See crosbug.com/p/8662.
- */
- if (current > 0 && current < info->current_min)
- return info->current_min;
-
- /* Clip to max */
- if (current > info->current_max)
- return info->current_max;
-
- /* Otherwise round down to nearest current step */
- return current - (current % info->current_step);
-}
-
int charger_set_current(int current)
{
current = charger_closest_current(current);
diff --git a/common/charger_bq24738.c b/common/charger_bq24738.c
index eaea6495d9..cb5047b5b5 100644
--- a/common/charger_bq24738.c
+++ b/common/charger_bq24738.c
@@ -134,25 +134,6 @@ int charger_get_current(int *current)
return EC_SUCCESS;
}
-int charger_closest_current(int current)
-{
- const struct charger_info * const info = charger_get_info();
-
- /*
- * If the requested current is non-zero but below our minimum,
- * return the minimum. See crosbug.com/p/8662.
- */
- if (current > 0 && current < info->current_min)
- return info->current_min;
-
- /* Clip to max */
- if (current > info->current_max)
- return info->current_max;
-
- /* Otherwise round down to nearest current step */
- return current - (current % info->current_step);
-}
-
int charger_set_current(int current)
{
current = charger_closest_current(current);
diff --git a/common/charger_common.c b/common/charger_common.c
index bb301c48a5..0c86a73156 100644
--- a/common/charger_common.c
+++ b/common/charger_common.c
@@ -25,6 +25,25 @@ int charger_closest_voltage(int voltage)
return voltage - (voltage % info->voltage_step);
}
+int charger_closest_current(int current)
+{
+ const struct charger_info * const info = charger_get_info();
+
+ /*
+ * If the requested current is non-zero but below our minimum,
+ * return the minimum. See crosbug.com/p/8662.
+ */
+ if (current > 0 && current < info->current_min)
+ return info->current_min;
+
+ /* Clip to max */
+ if (current > info->current_max)
+ return info->current_max;
+
+ /* Otherwise round down to nearest current step */
+ return current - (current % info->current_step);
+}
+
static int print_info(void)
{
int rv;
diff --git a/common/mock_charger.c b/common/mock_charger.c
index 47b2a96079..ebbf5e87bb 100644
--- a/common/mock_charger.c
+++ b/common/mock_charger.c
@@ -129,12 +129,6 @@ int charger_set_input_current(int input_current)
}
-int charger_closest_current(int current)
-{
- return current;
-}
-
-
int charger_post_init(void)
{
mock_current = CONFIG_CHARGER_INPUT_CURRENT;