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>
This commit is contained in:
Vijay Hiremath
2016-03-17 11:21:34 -07:00
committed by chrome-bot
parent 719f5d6d01
commit 4826d592ce
4 changed files with 402 additions and 0 deletions

View File

@@ -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

234
driver/charger/bd99955.c Normal file
View File

@@ -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);
}

166
driver/charger/bd99955.h Normal file
View File

@@ -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 */

View File

@@ -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