summaryrefslogtreecommitdiff
path: root/driver/charger/bq24192.c
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2013-10-16 13:23:10 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2013-10-23 20:07:25 +0000
commit8cf03ac0563294fbdeca2dc133d06f0b51c9a546 (patch)
tree6b07c493e7567a3221d8592b4337d2787d6bc531 /driver/charger/bq24192.c
parent2464d08e4d310a3f63208f22df4502c5250c4b58 (diff)
downloadchrome-ec-8cf03ac0563294fbdeca2dc133d06f0b51c9a546.tar.gz
Move source files to driver/ and power/ subdirs
The common/ subdir was getting cluttered. Move drivers for external components to a new driver/ tree, and move what used to be called chipset_*.c to a new power/ directory. This does not move/rename header files or CONFIG options. That will be done in subsequent steps, since moving and modifying .c files in the same CL is harder to review. BUG=chrome-os-partner:18343 BRANCH=none TEST=build all boards; pass unit tests Change-Id: I67a3003dc8564783a320335cf0e9620a21982d5e Signed-off-by: Randall Spangler <rspangler@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/173601 Reviewed-by: Bill Richardson <wfrichar@chromium.org> Tested-by: Bill Richardson <wfrichar@chromium.org> Reviewed-by: Vic Yang <victoryang@chromium.org>
Diffstat (limited to 'driver/charger/bq24192.c')
-rw-r--r--driver/charger/bq24192.c273
1 files changed, 273 insertions, 0 deletions
diff --git a/driver/charger/bq24192.c b/driver/charger/bq24192.c
new file mode 100644
index 0000000000..72f778d367
--- /dev/null
+++ b/driver/charger/bq24192.c
@@ -0,0 +1,273 @@
+/* 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 "gpio.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);
+}
+
+static int bq24192_set_terminate_current(int current)
+{
+ int reg_val, rv;
+ int val = (current - 128) / 128;
+
+ rv = bq24192_read(BQ24192_REG_PRE_CHG_CURRENT, &reg_val);
+ if (rv)
+ return rv;
+ reg_val = (reg_val & ~0xf) | (val & 0xf);
+ return bq24192_write(BQ24192_REG_PRE_CHG_CURRENT, reg_val);
+}
+
+int charger_enable_otg_power(int enabled)
+{
+ int val, rv;
+
+ gpio_set_level(GPIO_BCHGR_OTG, enabled);
+ rv = bq24192_read(BQ24192_REG_POWER_ON_CFG, &val);
+ if (rv)
+ return rv;
+ val = (val & ~0x30) | (enabled ? 0x20 : 0x10);
+ return 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;
+ *input_current = input_current_steps[value & 0x7];
+ return EC_SUCCESS;
+}
+
+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;
+}
+
+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);
+}
+
+/* Charging power state initialization */
+int charger_post_init(void)
+{
+ /* Input current controlled by extpower module. Do nothing here. */
+ return EC_SUCCESS;
+}
+
+
+/*****************************************************************************/
+/* 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_set_terminate_current(128))
+ 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);