summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVijay Hiremath <vijay.p.hiremath@intel.com>2016-03-17 11:21:34 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-03-22 19:54:44 -0700
commit4826d592ce100cd7b5086c4b0949ae3034b5a394 (patch)
tree84ca6f533c21d771f2e10d5f4bf3744b872876d5
parent719f5d6d01ea6a4afb239b2e58600ec854faa8ad (diff)
downloadchrome-ec-4826d592ce100cd7b5086c4b0949ae3034b5a394.tar.gz
Driver: bd99955: Add ROHM bd99955 initial charger driver
BUG=none BRANCH=none TEST=Manually tested on Amenia prototype. Used 'charger' console command to check the charger properties. Used 'battery' console command to check the battery charging. Change-Id: Ic8787bfa3e0e3a615542b9cf72e6404fccc96e18 Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com> Reviewed-on: https://chromium-review.googlesource.com/334021 Commit-Ready: Vijay P Hiremath <vijay.p.hiremath@intel.com> Tested-by: Vijay P Hiremath <vijay.p.hiremath@intel.com> Reviewed-by: Shawn N <shawnn@chromium.org>
-rw-r--r--driver/build.mk1
-rw-r--r--driver/charger/bd99955.c234
-rw-r--r--driver/charger/bd99955.h166
-rw-r--r--include/config.h1
4 files changed, 402 insertions, 0 deletions
diff --git a/driver/build.mk b/driver/build.mk
index 1a33ee714e..13aae200bc 100644
--- a/driver/build.mk
+++ b/driver/build.mk
@@ -30,6 +30,7 @@ driver-$(CONFIG_BATTERY_SAMUS)+=battery/samus.o
driver-$(CONFIG_BATTERY_SMART)+=battery/smart.o
# Battery charger ICs
+driver-$(CONFIG_CHARGER_BD99955)+=charger/bd99955.o
driver-$(CONFIG_CHARGER_BQ24192)+=charger/bq24192.o
driver-$(CONFIG_CHARGER_BQ24707A)+=charger/bq24707a.o
driver-$(CONFIG_CHARGER_BQ24715)+=charger/bq24715.o
diff --git a/driver/charger/bd99955.c b/driver/charger/bd99955.c
new file mode 100644
index 0000000000..27b50cade1
--- /dev/null
+++ b/driver/charger/bd99955.c
@@ -0,0 +1,234 @@
+/* Copyright 2016 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.
+ *
+ * ROHM BD99955 battery charger driver.
+ */
+
+#include "battery.h"
+#include "battery_smart.h"
+#include "bd99955.h"
+#include "charger.h"
+#include "console.h"
+#include "i2c.h"
+#include "task.h"
+#include "util.h"
+
+/* Console output macros */
+#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)
+
+/* Charger parameters */
+static const struct charger_info bd99955_charger_info = {
+ .name = CHARGER_NAME,
+ .voltage_max = CHARGE_V_MAX,
+ .voltage_min = CHARGE_V_MIN,
+ .voltage_step = CHARGE_V_STEP,
+ .current_max = CHARGE_I_MAX,
+ .current_min = CHARGE_I_MIN,
+ .current_step = CHARGE_I_STEP,
+ .input_current_max = INPUT_I_MAX,
+ .input_current_min = INPUT_I_MIN,
+ .input_current_step = INPUT_I_STEP,
+};
+
+/* Charge command code map */
+static enum BD99955_COMMANDS charger_map_cmd = BD99955_INVALID_COMMAND;
+
+static struct mutex bd99955_map_mutex;
+
+static inline int ch_raw_read16(int cmd, int *param,
+ enum BD99955_COMMANDS map_cmd)
+{
+ int rv;
+
+ /* Map the Charge command code to appropriate region */
+ mutex_lock(&bd99955_map_mutex);
+ if (charger_map_cmd != map_cmd) {
+ rv = i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER,
+ BD99955_CMD_MAP_SET, map_cmd);
+ if (rv)
+ goto bd99955_read_cleanup;
+
+ charger_map_cmd = map_cmd;
+ }
+
+ rv = i2c_read16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER, cmd, param);
+
+bd99955_read_cleanup:
+ mutex_unlock(&bd99955_map_mutex);
+
+ return rv;
+}
+
+static inline int ch_raw_write16(int cmd, int param,
+ enum BD99955_COMMANDS map_cmd)
+{
+ int rv;
+
+ /* Map the Charge command code to appropriate region */
+ mutex_lock(&bd99955_map_mutex);
+ if (charger_map_cmd != map_cmd) {
+ rv = i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER,
+ BD99955_CMD_MAP_SET, map_cmd);
+ if (rv)
+ goto bd99955_write_cleanup;
+
+ charger_map_cmd = map_cmd;
+ }
+
+ rv = i2c_write16(I2C_PORT_CHARGER, I2C_ADDR_CHARGER, cmd, param);
+
+bd99955_write_cleanup:
+ mutex_unlock(&bd99955_map_mutex);
+
+ return rv;
+}
+
+/* chip specific interfaces */
+
+int charger_set_input_current(int input_current)
+{
+ int rv;
+
+ /* Input current step 32 mA */
+ input_current &= ~0x1F;
+
+ rv = ch_raw_write16(BD99955_CMD_IBUS_LIM_SET, input_current,
+ BD99955_BAT_CHG_COMMAND);
+ if (rv)
+ return rv;
+
+ return ch_raw_write16(BD99955_CMD_ICC_LIM_SET, input_current,
+ BD99955_BAT_CHG_COMMAND);
+}
+
+int charger_get_input_current(int *input_current)
+{
+ int rv;
+
+ rv = ch_raw_read16(BD99955_CMD_IBUS_LIM_SET, input_current,
+ BD99955_BAT_CHG_COMMAND);
+ if (rv)
+ return rv;
+
+ return ch_raw_read16(BD99955_CMD_ICC_LIM_SET, input_current,
+ BD99955_BAT_CHG_COMMAND);
+}
+
+int charger_manufacturer_id(int *id)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+int charger_device_id(int *id)
+{
+ return ch_raw_read16(BD99955_CMD_CHIP_ID, id, BD99955_EXTENDED_COMMAND);
+}
+
+int charger_get_option(int *option)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+int charger_set_option(int option)
+{
+ return EC_ERROR_UNIMPLEMENTED;
+}
+
+/* Charger interfaces */
+
+const struct charger_info *charger_get_info(void)
+{
+ return &bd99955_charger_info;
+}
+
+int charger_get_status(int *status)
+{
+ *status = CHARGER_LEVEL_2;
+
+ return EC_SUCCESS;
+}
+
+int charger_set_mode(int mode)
+{
+ /* BD99955 does not support inhibit mode setting. */
+ return EC_SUCCESS;
+}
+
+int charger_get_current(int *current)
+{
+ return ch_raw_read16(BD99955_CMD_CHG_CURRENT, current,
+ BD99955_BAT_CHG_COMMAND);
+}
+
+int charger_set_current(int current)
+{
+ /* Charge current step 64 mA */
+ current &= ~0x3F;
+
+ return ch_raw_write16(BD99955_CMD_CHG_CURRENT, current,
+ BD99955_BAT_CHG_COMMAND);
+}
+
+int charger_get_voltage(int *voltage)
+{
+ return ch_raw_read16(BD99955_CMD_CHG_VOLTAGE, voltage,
+ BD99955_BAT_CHG_COMMAND);
+}
+
+int charger_set_voltage(int voltage)
+{
+ /*
+ * The BD99955 will drop voltage to as low as requested. As the
+ * charger state machine will pass in 0 voltage, protect the system
+ * voltage by capping to the minimum. The reason is that the BD99955
+ * only can regulate the system voltage which will kill the board's
+ * power if below 0.
+ */
+ if (voltage == 0) {
+ const struct battery_info *bi = battery_get_info();
+
+ voltage = bi->voltage_min;
+ }
+
+ /* Charge voltage step 16 mV */
+ voltage &= ~0x0F;
+ return ch_raw_write16(BD99955_CMD_CHG_VOLTAGE, voltage,
+ BD99955_BAT_CHG_COMMAND);
+}
+
+int charger_post_init(void)
+{
+ int rv;
+
+ /*
+ * TODO: Disable charger & re-enable to initialize it.
+ */
+ rv = charger_discharge_on_ac(1);
+ if (rv)
+ return rv;
+
+ return charger_discharge_on_ac(0);
+}
+
+int charger_discharge_on_ac(int enable)
+{
+ int rv;
+ int reg;
+
+ rv = ch_raw_read16(BD99955_CMD_CHGOP_SET2, &reg,
+ BD99955_EXTENDED_COMMAND);
+ if (rv)
+ return rv;
+
+ if (enable) {
+ reg |= BD99955_CHGOP_SET2_BATT_LEARN;
+ reg &= ~BD99955_CHGOP_SET2_CHG_EN;
+ } else {
+ reg &= ~BD99955_CHGOP_SET2_BATT_LEARN;
+ reg |= BD99955_CHGOP_SET2_CHG_EN;
+ }
+
+ return ch_raw_write16(BD99955_CMD_CHGOP_SET2, reg,
+ BD99955_EXTENDED_COMMAND);
+}
diff --git a/driver/charger/bd99955.h b/driver/charger/bd99955.h
new file mode 100644
index 0000000000..e027f8e357
--- /dev/null
+++ b/driver/charger/bd99955.h
@@ -0,0 +1,166 @@
+/* Copyright 2016 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.
+ *
+ * ROHM BD99955 battery charger driver.
+ */
+
+#ifndef __CROS_EC_BD99955_H
+#define __CROS_EC_BD99955_H
+
+#define BD99955_ADDR 0x12 /* 7bit address 0001_001 */
+#define I2C_ADDR_CHARGER BD99955_ADDR
+
+/* BD99955 commands to change the command code map */
+enum BD99955_COMMANDS {
+ BD99955_BAT_CHG_COMMAND,
+ BD99955_EXTENDED_COMMAND,
+ BD99955_DEBUG_COMMAND,
+ BD99955_INVALID_COMMAND
+};
+
+/* Charger parameters */
+#define CHARGER_NAME "bd99955"
+#define CHARGE_V_MAX 19200
+#define CHARGE_V_MIN 3072
+#define CHARGE_V_STEP 16
+#define CHARGE_I_MAX 16320
+#define CHARGE_I_MIN 0
+#define CHARGE_I_OFF 0
+#define CHARGE_I_STEP 64
+#define INPUT_I_MAX 16352
+#define INPUT_I_MIN 0
+#define INPUT_I_STEP 32
+
+/* Battery Charger Commands */
+#define BD99955_CMD_CHG_CURRENT 0x14
+#define BD99955_CMD_CHG_VOLTAGE 0x15
+#define BD99955_CMD_IBUS_LIM_SET 0x3C
+#define BD99955_CMD_ICC_LIM_SET 0x3D
+#define BD99955_CMD_PROTECT_SET 0x3E
+#define BD99955_CMD_MAP_SET 0x3F
+
+/* Extended commands */
+#define BD99955_CMD_CHGSTM_STATUS 0x00
+#define BD99955_CMD_VBAT_VSYS_STATUS 0x01
+#define BD99955_CMD_VBUS_VCC_STATUS 0x02
+#define BD99955_CMD_CHGOP_STATUS 0x03
+#define BD99955_CMD_WDT_STATUS 0x04
+#define BD99955_CMD_CUR_ILIM_VAL 0x05
+#define BD99955_CMD_SEL_ILIM_VAL 0x06
+#define BD99955_CMD_EXT_IBUS_LIM_SET 0x07
+#define BD99955_CMD_EXT_ICC_LIM_SET 0x08
+#define BD99955_CMD_IOTG_LIM_SET 0x09
+#define BD99955_CMD_VIN_CTRL_SET 0x0A
+#define BD99955_CMD_CHGOP_SET1 0x0B
+#define BD99955_CMD_CHGOP_SET2 0x0C
+#define BD99955_CMD_VBUSCLPS_TH_SET 0x0D
+#define BD99955_CMD_VCCCLPS_TH_SET 0x0E
+#define BD99955_CMD_CHGWDT_SET 0x0F
+#define BD99955_CMD_BATTWDT_SET 0x10
+#define BD99955_CMD_VSYSREG_SETa 0x11
+#define BD99955_CMD_VSYSVAL_THH_SET 0x12
+#define BD99955_CMD_VSYSVAL_THL_SET 0x13
+#define BD99955_CMD_ITRICH_SET 0x14
+#define BD99955_CMD_IPRECH_SET 0x15
+#define BD99955_CMD_ICHG_SET 0x16
+#define BD99955_CMD_ITERM_SET 0x17
+#define BD99955_CMD_VPRECHG_TH_SET 0x18
+#define BD99955_CMD_VRBOOST_SET 0x19
+#define BD99955_CMD_VFASTCHG_REG_SET1 0x1A
+#define BD99955_CMD_VFASTCHG_REG_SET2 0x1B
+#define BD99955_CMD_VFASTCHG_REG_SET3 0x1C
+#define BD99955_CMD_VRECHG_SET 0x1D
+#define BD99955_CMD_VBATOVP_SET 0x1E
+#define BD99955_CMD_IBATSHORT_SET 0x1F
+#define BD99955_CMD_PROCHOT_CTRL_SET 0x20
+#define BD99955_CMD_PROCHOT_ICRIT_SET 0x21
+#define BD99955_CMD_PROCHOT_INORM_SET 0x22
+#define BD99955_CMD_PROCHOT_IDCHG_SET 0x23
+#define BD99955_CMD_PROCHOT_VSYS_SET 0x24
+#define BD99955_CMD_PMON_IOUT_CTRL_SET 0x25
+#define BD99955_CMD_PMON_DACIN_VAL 0x26
+#define BD99955_CMD_IOUT_DACIN_VAL 0x27
+#define BD99955_CMD_VCC_UCD_SET 0x28
+#define BD99955_CMD_VCC_UCD_STATUS 0x29
+#define BD99955_CMD_VCC_IDD_STATUS 0x2A
+#define BD99955_CMD_VCC_UCD_FCTRL_SET 0x2B
+#define BD99955_CMD_VCC_UCD_FCTRL_EN 0x2C
+#define BD99955_CMD_VBUS_UCD_SET 0x30
+#define BD99955_CMD_VBUS_UCD_STATUS 0x31
+#define BD99955_CMD_VBUS_IDD_STATUS 0x32
+#define BD99955_CMD_VBUS_UCD_FCTRL_SET 0x33
+#define BD99955_CMD_VBUS_UCD_FCTRL_EN 0x34
+#define BD99955_CMD_CHIP_ID 0x38
+#define BD99955_CMD_CHIP_REV 0x39
+#define BD99955_CMD_IC_SET1 0x3A
+#define BD99955_CMD_IC_SET2 0x3B
+#define BD99955_CMD_SYSTEM_STATUS 0x3C
+#define BD99955_CMD_SYSTEM_CTRL_SET 0x3D
+#define BD99955_CMD_EXT_PROTECT_SET 0x3E
+#define BD99955_CMD_EXT_MAP_SET 0x3F
+#define BD99955_CMD_VM_CTRL_SET 0x40
+#define BD99955_CMD_THERM_WINDOW_SET1 0x41
+#define BD99955_CMD_THERM_WINDOW_SET2 0x42
+#define BD99955_CMD_THERM_WINDOW_SET3 0x43
+#define BD99955_CMD_THERM_WINDOW_SET4 0x44
+#define BD99955_CMD_THERM_WINDOW_SET5 0x45
+#define BD99955_CMD_IBATP_TH_SET 0x46
+#define BD99955_CMD_IBATM_TH_SET 0x47
+#define BD99955_CMD_VBAT_TH_SET 0x48
+#define BD99955_CMD_THERM_TH_SET 0x49
+#define BD99955_CMD_IACP_TH_SET 0x4A
+#define BD99955_CMD_VACP_TH_SET 0x4B
+#define BD99955_CMD_VBUS_TH_SET 0x4C
+#define BD99955_CMD_VCC_TH_SET 0x4D
+#define BD99955_CMD_VSYS_TH_SET 0x4E
+#define BD99955_CMD_EXTIADP_TH_SET 0x4F
+#define BD99955_CMD_IBATP_VAL 0x50
+#define BD99955_CMD_IBATP_AVE_VAL 0x51
+#define BD99955_CMD_IBATM_VAL 0x52
+#define BD99955_CMD_IBATM_AVE_VAL 0x53
+#define BD99955_CMD_VBAT_VAL 0x54
+#define BD99955_CMD_VBAT_AVE_VAL 0x55
+#define BD99955_CMD_THERM_VAL 0x56
+#define BD99955_CMD_VTH_VAL 0x57
+#define BD99955_CMD_IACP_VAL 0x58
+#define BD99955_CMD_IACP_AVE_VAL 0x59
+#define BD99955_CMD_VACP_VAL 0x5A
+#define BD99955_CMD_VACP_AVE_VAL 0x5B
+#define BD99955_CMD_VBUS_VAL 0x5C
+#define BD99955_CMD_VBUS_AVE_VAL 0x5D
+#define BD99955_CMD_VCC_VAL 0x5E
+#define BD99955_CMD_VCC_AVE_VAL 0x5F
+#define BD99955_CMD_VSYS_VAL 0x60
+#define BD99955_CMD_VSYS_AVE_VAL 0x61
+#define BD99955_CMD_EXTIADP_VAL 0x62
+#define BD99955_CMD_EXTIADP_AVE_VAL 0x63
+#define BD99955_CMD_VACPCLPS_TH_SET 0x64
+#define BD99955_CMD_INT0_SET 0x68
+#define BD99955_CMD_INT1_SET 0x69
+#define BD99955_CMD_INT2_SET 0x6A
+#define BD99955_CMD_INT3_SET 0x6B
+#define BD99955_CMD_INT4_SET 0x6C
+#define BD99955_CMD_INT5_SET 0x6D
+#define BD99955_CMD_INT6_SET 0x6E
+#define BD99955_CMD_INT7_SET 0x6F
+#define BD99955_CMD_INT0_STATUS 0x70
+#define BD99955_CMD_INT1_STATUS 0x71
+#define BD99955_CMD_INT2_STATUS 0x72
+#define BD99955_CMD_INT3_STATUS 0x73
+#define BD99955_CMD_INT4_STATUS 0x74
+#define BD99955_CMD_INT5_STATUS 0x75
+#define BD99955_CMD_INT6_STATUS 0x76
+#define BD99955_CMD_INT7_STATUS 0x77
+#define BD99955_CMD_REG0 0x78
+#define BD99955_CMD_REG1 0x79
+#define BD99955_CMD_OTPREG0 0x7A
+#define BD99955_CMD_OTPREG1 0x7B
+#define BD99955_CMD_SMBREG 0x7C
+#define BD99955_CMD_DEBUG_MODE_SET 0x7F
+
+/* Charger operation control setting 2 */
+#define BD99955_CHGOP_SET2_CHG_EN (1 << 7)
+#define BD99955_CHGOP_SET2_BATT_LEARN (1 << 8)
+
+#endif /* __CROS_EC_BD99955_H */
diff --git a/include/config.h b/include/config.h
index 196990ac05..225aaedf4d 100644
--- a/include/config.h
+++ b/include/config.h
@@ -337,6 +337,7 @@
#undef CONFIG_CHARGER_ADC_AMON_BMON
/* Compile charger-specific code for these chargers (pick at most one) */
+#undef CONFIG_CHARGER_BD99955
#undef CONFIG_CHARGER_BQ24707A
#undef CONFIG_CHARGER_BQ24715
#undef CONFIG_CHARGER_BQ24725