mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-30 18:41:11 +00:00
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
This commit is contained in:
committed by
chrome-internal-fetch
parent
8f79405766
commit
ea41735a4c
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
243
common/charger_bq24192.c
Normal file
243
common/charger_bq24192.c
Normal file
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
28
include/charger_bq24192.h
Normal file
28
include/charger_bq24192.h
Normal file
@@ -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 */
|
||||
Reference in New Issue
Block a user