summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Palatin <vpalatin@chromium.org>2014-03-21 17:48:37 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-03-29 02:17:27 +0000
commit5945c6462f76eaf380f488d882e79660604e22d8 (patch)
treeb98be1efb4ea0c5ab0d99eb7ee9dfb40e1f536da
parent4681e6bc342b29f2f6e4527fbec58cd110515ee3 (diff)
downloadchrome-ec-5945c6462f76eaf380f488d882e79660604e22d8.tar.gz
Add driver for TI BQ24773 charger
Add support TI BQ24773 1S/2S/3S NVDC battery charger. This is not a "Smart Battery" compliant charger IC, it should and cannot use the sbc_ helpers. Signed-off-by: Vincent Palatin <vpalatin@chromium.org> BRANCH=none BUG=none TEST=on FruitPie, run "charger" command on the EC console, add the charger task and see the battery charging. Change-Id: I6f470184f0ce424a05007e493d802dcdb2156477 Reviewed-on: https://chromium-review.googlesource.com/191212 Tested-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-by: Randall Spangler <rspangler@chromium.org> Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--driver/build.mk1
-rw-r--r--driver/charger/bq24773.c194
-rw-r--r--driver/charger/bq24773.h31
-rw-r--r--include/config.h1
4 files changed, 227 insertions, 0 deletions
diff --git a/driver/build.mk b/driver/build.mk
index f9c31b143b..ab637f03e2 100644
--- a/driver/build.mk
+++ b/driver/build.mk
@@ -24,6 +24,7 @@ driver-$(CONFIG_CHARGER_BQ24707A)+=charger/bq24707a.o
driver-$(CONFIG_CHARGER_BQ24715)+=charger/bq24715.o
driver-$(CONFIG_CHARGER_BQ24725)+=charger/bq24725.o
driver-$(CONFIG_CHARGER_BQ24738)+=charger/bq24738.o
+driver-$(CONFIG_CHARGER_BQ24773)+=charger/bq24773.o
# LED drivers
driver-$(CONFIG_LED_DRIVER_DS2413)+=led/ds2413.o
diff --git a/driver/charger/bq24773.c b/driver/charger/bq24773.c
new file mode 100644
index 0000000000..854bb6dfb0
--- /dev/null
+++ b/driver/charger/bq24773.c
@@ -0,0 +1,194 @@
+/* Copyright (c) 2014 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 bq24773 battery charger driver.
+ */
+
+#include "battery_smart.h"
+#include "bq24773.h"
+#include "charger.h"
+#include "console.h"
+#include "common.h"
+#include "i2c.h"
+#include "util.h"
+
+/*
+ * on the I2C version of the charger,
+ * some registers are 8-bit only (eg input current)
+ * and they are shifted by 6 bits compared to the SMBUS version (bq24770).
+ */
+#define REG8_SHIFT 6
+#define R8 (1 << (REG8_SHIFT))
+/* Sense resistor configurations and macros */
+#define DEFAULT_SENSE_RESISTOR 10
+#define R_SNS CONFIG_CHARGER_SENSE_RESISTOR
+#define R_AC (CONFIG_CHARGER_SENSE_RESISTOR_AC)
+#define REG_TO_CURRENT(REG, RS) ((REG) * DEFAULT_SENSE_RESISTOR / (RS))
+#define CURRENT_TO_REG(CUR, RS) ((CUR) * (RS) / DEFAULT_SENSE_RESISTOR)
+#define REG8_TO_CURRENT(REG, RS) ((REG) * DEFAULT_SENSE_RESISTOR / (RS) * R8)
+#define CURRENT_TO_REG8(CUR, RS) ((CUR) * (RS) / DEFAULT_SENSE_RESISTOR / R8)
+
+/* Charger parameters */
+static const struct charger_info bq24773_charger_info = {
+ .name = "bq24773",
+ .voltage_max = 19200,
+ .voltage_min = 1024,
+ .voltage_step = 16,
+ .current_max = REG_TO_CURRENT(0x1FC0, R_SNS),
+ .current_min = REG_TO_CURRENT(128, R_SNS),
+ .current_step = REG_TO_CURRENT(64, R_SNS),
+ .input_current_max = REG8_TO_CURRENT(0x7F, R_AC),
+ .input_current_min = REG8_TO_CURRENT(2, R_AC),
+ .input_current_step = REG8_TO_CURRENT(1, R_AC),
+};
+
+/* bq24773 specific interfaces */
+
+int charger_set_input_current(int input_current)
+{
+ return i2c_write8(I2C_PORT_CHARGER, BQ24773_ADDR,
+ BQ24773_INPUT_CURRENT,
+ CURRENT_TO_REG8(input_current, R_AC));
+}
+
+int charger_get_input_current(int *input_current)
+{
+ int rv;
+ int reg;
+
+ rv = i2c_read8(I2C_PORT_CHARGER, BQ24773_ADDR,
+ BQ24773_INPUT_CURRENT, &reg);
+ if (rv)
+ return rv;
+
+ *input_current = REG8_TO_CURRENT(reg, R_AC);
+
+ return EC_SUCCESS;
+}
+
+int charger_manufacturer_id(int *id)
+{
+ *id = 0x40; /* TI */
+ return EC_SUCCESS;
+}
+
+int charger_device_id(int *id)
+{
+ return i2c_read8(I2C_PORT_CHARGER, BQ24773_ADDR,
+ BQ24773_DEVICE_ADDRESS, id);
+}
+
+int charger_get_option(int *option)
+{
+ return i2c_read16(I2C_PORT_CHARGER, BQ24773_ADDR,
+ BQ24773_CHARGE_OPTION0, option);
+}
+
+int charger_set_option(int option)
+{
+ return i2c_write16(I2C_PORT_CHARGER, BQ24773_ADDR,
+ BQ24773_CHARGE_OPTION0, option);
+}
+
+/* Charger interfaces */
+
+const struct charger_info *charger_get_info(void)
+{
+ return &bq24773_charger_info;
+}
+
+int charger_get_status(int *status)
+{
+ int rv;
+ int option;
+
+ rv = charger_get_option(&option);
+ if (rv)
+ return rv;
+
+ /* Default status */
+ *status = CHARGER_LEVEL_2;
+
+ if (option & OPTION0_CHARGE_INHIBIT)
+ *status |= CHARGER_CHARGE_INHIBITED;
+
+ return EC_SUCCESS;
+}
+
+int charger_set_mode(int mode)
+{
+ int rv;
+ int option;
+
+ rv = charger_get_option(&option);
+ if (rv)
+ return rv;
+
+ if (mode & CHARGE_FLAG_INHIBIT_CHARGE)
+ option |= OPTION0_CHARGE_INHIBIT;
+ else
+ option &= ~OPTION0_CHARGE_INHIBIT;
+ return charger_set_option(option);
+}
+
+int charger_get_current(int *current)
+{
+ int rv;
+ int reg;
+
+ rv = i2c_read16(I2C_PORT_CHARGER, BQ24773_ADDR,
+ BQ24773_CHARGE_CURRENT, &reg);
+ if (rv)
+ return rv;
+
+ *current = REG_TO_CURRENT(reg, R_SNS);
+ return EC_SUCCESS;
+}
+
+int charger_set_current(int current)
+{
+ current = charger_closest_current(current);
+
+ return i2c_write16(I2C_PORT_CHARGER, BQ24773_ADDR,
+ BQ24773_CHARGE_CURRENT, CURRENT_TO_REG(current, R_SNS));
+}
+
+int charger_get_voltage(int *voltage)
+{
+ return i2c_read16(I2C_PORT_CHARGER, BQ24773_ADDR,
+ BQ24773_MAX_CHARGE_VOLTAGE, voltage);
+}
+
+int charger_set_voltage(int voltage)
+{
+ return i2c_write16(I2C_PORT_CHARGER, BQ24773_ADDR,
+ BQ24773_MAX_CHARGE_VOLTAGE, voltage);
+}
+
+/* Charging power state initialization */
+int charger_post_init(void)
+{
+ int rv;
+
+ /* Set charger input current limit */
+ rv = charger_set_input_current(CONFIG_CHARGER_INPUT_CURRENT);
+ return rv;
+}
+
+int charger_discharge_on_ac(int enable)
+{
+ int rv;
+ int option;
+
+ rv = charger_get_option(&option);
+ if (rv)
+ return rv;
+
+ if (enable)
+ rv = charger_set_option(option | OPTION0_LEARN_ENABLE);
+ else
+ rv = charger_set_option(option & ~OPTION0_LEARN_ENABLE);
+
+ return rv;
+}
diff --git a/driver/charger/bq24773.h b/driver/charger/bq24773.h
new file mode 100644
index 0000000000..cce3e7e902
--- /dev/null
+++ b/driver/charger/bq24773.h
@@ -0,0 +1,31 @@
+/* Copyright (c) 2014 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 bq24773 battery charger driver.
+ */
+
+#ifndef __CROS_EC_CHARGER_BQ24773_H
+#define __CROS_EC_CHARGER_BQ24773_H
+
+/* I2C address */
+#define BQ24773_ADDR (0x6a << 1)
+
+/* Chip specific commands */
+#define BQ24773_CHARGE_OPTION0 0x00
+#define BQ24773_CHARGE_OPTION1 0x02
+#define BQ24773_PROTECT_OPTION0 0x04
+#define BQ24773_PROTECT_OPTION1 0x06
+#define BQ24773_PROTECT_STATUS 0x08
+#define BQ24773_DEVICE_ADDRESS 0x09
+#define BQ24773_CHARGE_CURRENT 0x0A
+#define BQ24773_MAX_CHARGE_VOLTAGE 0x0C
+#define BQ24773_MIN_SYSTEM_VOLTAGE 0x0E
+#define BQ24773_INPUT_CURRENT 0x0F
+#define BQ24773_CHARGE_OPTION2 0x10
+
+/* Option bits */
+#define OPTION0_CHARGE_INHIBIT (1 << 0)
+#define OPTION0_LEARN_ENABLE (1 << 5)
+
+#endif /* __CROS_EC_CHARGER_BQ24773_H */
diff --git a/include/config.h b/include/config.h
index bd0f2be9dd..7a882c3fcb 100644
--- a/include/config.h
+++ b/include/config.h
@@ -172,6 +172,7 @@
#undef CONFIG_CHARGER_BQ24715
#undef CONFIG_CHARGER_BQ24725
#undef CONFIG_CHARGER_BQ24738
+#undef CONFIG_CHARGER_BQ24773
#undef CONFIG_CHARGER_TPS65090 /* Note: does not use CONFIG_CHARGER */
/*