summaryrefslogtreecommitdiff
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
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
-rw-r--r--board/kirby/board.h2
-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
-rw-r--r--include/charger_bq24192.h28
10 files changed, 293 insertions, 82 deletions
diff --git a/board/kirby/board.h b/board/kirby/board.h
index 26e031b7b2..d246622504 100644
--- a/board/kirby/board.h
+++ b/board/kirby/board.h
@@ -9,6 +9,8 @@
#define __BOARD_H
/* Optional features */
+#define CONFIG_CHARGER
+#define CONFIG_CHARGER_BQ24192
#define CONFIG_CHIPSET_GAIA
#define CONFIG_HOST_COMMAND_STATUS
#define CONFIG_I2C
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;
diff --git a/include/charger_bq24192.h b/include/charger_bq24192.h
new file mode 100644
index 0000000000..4177dc5c2c
--- /dev/null
+++ b/include/charger_bq24192.h
@@ -0,0 +1,28 @@
+/* Copyright (c) 2013 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.
+ */
+
+#ifndef __CROS_EC_CHARGER_BQ24192_H
+#define __CROS_EC_CHARGER_BQ24192_H
+
+#define BQ24192_ADDR 0xd6
+
+/* Registers */
+#define BQ24192_REG_INPUT_CTRL 0x0
+#define BQ24192_REG_POWER_ON_CFG 0x1
+#define BQ24192_REG_CHG_CURRENT 0x2
+#define BQ24192_REG_PRE_CHG_CURRENT 0x3
+#define BQ24192_REG_CHG_VOLTAGE 0x4
+#define BQ24192_REG_CHG_TERM_TMR 0x5
+#define BQ24192_REG_IR_COMP 0x6
+#define BQ24192_REG_MISC_OP 0x7
+#define BQ24192_REG_STATUS 0x8
+#define BQ24192_REG_FAULT 0x9
+#define BQ24192_REG_ID 0xa
+
+#define BQ24192_DEVICE_ID 0x2b
+
+#endif /* __CROS_EC_CHARGER_BQ24192_H */