Various small bugfixes and enhancements, plus two new drivers:
- A quite complex ab8500 charger driver, submitted by Arun Murthy @ ST-Ericsson; - Summit Microelectronics SMB347 Battery Charger, submitted by Bruce E. Robertson and Alan Cox @ Intel. And that's all. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.18 (GNU/Linux) iQIcBAABAgAGBQJPdhj7AAoJEGgI9fZJve1bSKEQAKzKXPwqpBREXzS888YWzb34 0r3Bly+F8eSRTjclbEEvEOVVCjxKOFpow5lN+eAkRNAMLDBcMamfBTR+rpoYb822 d7R4Hy/stVnmD5nul0WMezZ0OZf6qRy8kHazmvb63Jk37ykof52TqoEInKdHL/ww afUNfCnAFAbZkjxEr/9MwpM+nzYKdlGIoQlu9CJLARJiT9CyICjgHG48MGmyxOws 1LPha40jXuKLoyE+6nvG1Ji71NzZlFaVuFpzk75kjsWoB78zkRsMSv+zboHRz3QP PI+uS54auIkGhqeIeEuuSzPZx+1K2Fr2/qyut3tqM8AejBE4kETiBAy0b0BREBSd NqA4/Yw24c8xglIFP6OlNjHnLgCsExfHATzqzML2El/dXG8P2ggEayZzDh9bmsuU ZNKOmHZYgEj2eEorJcmlfZ23rJwlxuspl1m2nH2WEnqw6Z6TnskK4N1JSNlpGRPU j+iHbTPA04hultQkzNHCdPRR/jK1IC5eGdwc612QgxOhZPkvhmW92e8EOVz/3E3X TqKXfBiKxKtkIncLPYFh7oeZINKnlqZrXsYrHhxhlm9UstGOqfEIqbCGqlf0Q4P1 WOhIQe1cP/JpB9T58e3mLF2dQIGScTqzQCRSW6/m+3HmDwZb8JyUQRw5188s3yJr umrBS5hqS+z3bISWrcGi =Y8fe -----END PGP SIGNATURE----- Merge tag 'for-v3.4-rc1' of git://git.infradead.org/battery-2.6 Pull battery updates from Anton Vorontsov: "Various small bugfixes and enhancements, plus two new drivers: - A quite complex ab8500 charger driver, submitted by Arun Murthy @ ST-Ericsson; - Summit Microelectronics SMB347 Battery Charger, submitted by Bruce E Robertson and Alan Cox @ Intel. And that's all." * tag 'for-v3.4-rc1' of git://git.infradead.org/battery-2.6: (36 commits) max17042_battery: Clean up interrupt handling Revert "max8998_charger: Include linux/module.h just once" ab8500_fg: Fix some build warnings on x86_64 max17042_battery: Fix CHARGE_FULL representation. max8998_charger: Include linux/module.h just once power_supply: Convert i2c drivers to module_i2c_driver lp8727_charger: Add MODULE_DEVICE_TABLE charger-manager: Simplify charger_get_property(), get rid of a warning charger-manager: Clean up for better readability da9052-battery: Convert to use module_platform_driver da9052-battery: Fix a memory leak when unload the module da9052-battery: Add missing platform_set_drvdata ab8500: Turn unneeded global symbols into local ones ab8500_fg: Fix copy-paste error ab8500_fg: Get rid of 'struct battery_type' ab8500_fg: Get rid of 'struct v_to_cap' ab8500_btemp: Get rid of 'enum adc_therm' ab8500_charger: Convert to the new USB OTG calls ab8500-btemp: AB8500 battery temperature driver ab8500-fg: A8500 fuel gauge driver ...
This commit is contained in:
commit
919c840167
|
@ -0,0 +1,18 @@
|
|||
max17042_battery
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Required properties :
|
||||
- compatible : "maxim,max17042"
|
||||
|
||||
Optional properties :
|
||||
- maxim,rsns-microohm : Resistance of rsns resistor in micro Ohms
|
||||
(datasheet-recommended value is 10000).
|
||||
Defining this property enables current-sense functionality.
|
||||
|
||||
Example:
|
||||
|
||||
battery-charger@36 {
|
||||
compatible = "maxim,max17042";
|
||||
reg = <0x36>;
|
||||
maxim,rsns-microohm = <10000>;
|
||||
};
|
|
@ -249,7 +249,7 @@ config CHARGER_TWL4030
|
|||
Say Y here to enable support for TWL4030 Battery Charge Interface.
|
||||
|
||||
config CHARGER_LP8727
|
||||
tristate "National Semiconductor LP8727 charger driver"
|
||||
tristate "TI/National Semiconductor LP8727 charger driver"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y here to enable support for LP8727 Charger Driver.
|
||||
|
@ -288,4 +288,23 @@ config CHARGER_MAX8998
|
|||
Say Y to enable support for the battery charger control sysfs and
|
||||
platform data of MAX8998/LP3974 PMICs.
|
||||
|
||||
config CHARGER_SMB347
|
||||
tristate "Summit Microelectronics SMB347 Battery Charger"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y to include support for Summit Microelectronics SMB347
|
||||
Battery Charger.
|
||||
|
||||
config AB8500_BM
|
||||
bool "AB8500 Battery Management Driver"
|
||||
depends on AB8500_CORE && AB8500_GPADC
|
||||
help
|
||||
Say Y to include support for AB5500 battery management.
|
||||
|
||||
config AB8500_BATTERY_THERM_ON_BATCTRL
|
||||
bool "Thermistor connected on BATCTRL ADC"
|
||||
depends on AB8500_BM
|
||||
help
|
||||
Say Y to enable battery temperature measurements using
|
||||
thermistor connected on BATCTRL ADC.
|
||||
endif # POWER_SUPPLY
|
||||
|
|
|
@ -34,6 +34,7 @@ obj-$(CONFIG_BATTERY_S3C_ADC) += s3c_adc_battery.o
|
|||
obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
|
||||
obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o
|
||||
obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o
|
||||
obj-$(CONFIG_AB8500_BM) += ab8500_charger.o ab8500_btemp.o ab8500_fg.o abx500_chargalg.o
|
||||
obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX8903) += max8903_charger.o
|
||||
obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o
|
||||
|
@ -42,3 +43,4 @@ obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
|
|||
obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
|
||||
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
|
||||
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
|
||||
obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -134,12 +134,11 @@ static int get_batt_uV(struct charger_manager *cm, int *uV)
|
|||
union power_supply_propval val;
|
||||
int ret;
|
||||
|
||||
if (cm->fuel_gauge)
|
||||
ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
|
||||
else
|
||||
if (!cm->fuel_gauge)
|
||||
return -ENODEV;
|
||||
|
||||
ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
|
||||
POWER_SUPPLY_PROP_VOLTAGE_NOW, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -245,9 +244,7 @@ static int try_charger_enable(struct charger_manager *cm, bool enable)
|
|||
struct charger_desc *desc = cm->desc;
|
||||
|
||||
/* Ignore if it's redundent command */
|
||||
if (enable && cm->charger_enabled)
|
||||
return 0;
|
||||
if (!enable && !cm->charger_enabled)
|
||||
if (enable == cm->charger_enabled)
|
||||
return 0;
|
||||
|
||||
if (enable) {
|
||||
|
@ -309,9 +306,7 @@ static void uevent_notify(struct charger_manager *cm, const char *event)
|
|||
|
||||
if (!strncmp(env_str_save, event, UEVENT_BUF_SIZE))
|
||||
return; /* Duplicated. */
|
||||
else
|
||||
strncpy(env_str_save, event, UEVENT_BUF_SIZE);
|
||||
|
||||
strncpy(env_str_save, event, UEVENT_BUF_SIZE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -387,8 +382,10 @@ static bool cm_monitor(void)
|
|||
|
||||
mutex_lock(&cm_list_mtx);
|
||||
|
||||
list_for_each_entry(cm, &cm_list, entry)
|
||||
stop = stop || _cm_monitor(cm);
|
||||
list_for_each_entry(cm, &cm_list, entry) {
|
||||
if (_cm_monitor(cm))
|
||||
stop = true;
|
||||
}
|
||||
|
||||
mutex_unlock(&cm_list_mtx);
|
||||
|
||||
|
@ -402,7 +399,8 @@ static int charger_get_property(struct power_supply *psy,
|
|||
struct charger_manager *cm = container_of(psy,
|
||||
struct charger_manager, charger_psy);
|
||||
struct charger_desc *desc = cm->desc;
|
||||
int i, ret = 0, uV;
|
||||
int ret = 0;
|
||||
int uV;
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_STATUS:
|
||||
|
@ -428,8 +426,7 @@ static int charger_get_property(struct power_supply *psy,
|
|||
val->intval = 0;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_VOLTAGE_NOW:
|
||||
ret = get_batt_uV(cm, &i);
|
||||
val->intval = i;
|
||||
ret = get_batt_uV(cm, &val->intval);
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_NOW:
|
||||
ret = cm->fuel_gauge->get_property(cm->fuel_gauge,
|
||||
|
@ -697,8 +694,10 @@ bool cm_suspend_again(void)
|
|||
mutex_lock(&cm_list_mtx);
|
||||
list_for_each_entry(cm, &cm_list, entry) {
|
||||
if (cm->status_save_ext_pwr_inserted != is_ext_pwr_online(cm) ||
|
||||
cm->status_save_batt != is_batt_present(cm))
|
||||
cm->status_save_batt != is_batt_present(cm)) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&cm_list_mtx);
|
||||
|
||||
|
@ -855,11 +854,10 @@ static int charger_manager_probe(struct platform_device *pdev)
|
|||
|
||||
platform_set_drvdata(pdev, cm);
|
||||
|
||||
memcpy(&cm->charger_psy, &psy_default,
|
||||
sizeof(psy_default));
|
||||
memcpy(&cm->charger_psy, &psy_default, sizeof(psy_default));
|
||||
|
||||
if (!desc->psy_name) {
|
||||
strncpy(cm->psy_name_buf, psy_default.name,
|
||||
PSY_NAME_MAX);
|
||||
strncpy(cm->psy_name_buf, psy_default.name, PSY_NAME_MAX);
|
||||
} else {
|
||||
strncpy(cm->psy_name_buf, desc->psy_name, PSY_NAME_MAX);
|
||||
}
|
||||
|
@ -894,15 +892,15 @@ static int charger_manager_probe(struct platform_device *pdev)
|
|||
POWER_SUPPLY_PROP_CURRENT_NOW;
|
||||
cm->charger_psy.num_properties++;
|
||||
}
|
||||
if (!desc->measure_battery_temp) {
|
||||
cm->charger_psy.properties[cm->charger_psy.num_properties] =
|
||||
POWER_SUPPLY_PROP_TEMP_AMBIENT;
|
||||
cm->charger_psy.num_properties++;
|
||||
}
|
||||
|
||||
if (desc->measure_battery_temp) {
|
||||
cm->charger_psy.properties[cm->charger_psy.num_properties] =
|
||||
POWER_SUPPLY_PROP_TEMP;
|
||||
cm->charger_psy.num_properties++;
|
||||
} else {
|
||||
cm->charger_psy.properties[cm->charger_psy.num_properties] =
|
||||
POWER_SUPPLY_PROP_TEMP_AMBIENT;
|
||||
cm->charger_psy.num_properties++;
|
||||
}
|
||||
|
||||
ret = power_supply_register(NULL, &cm->charger_psy);
|
||||
|
@ -933,9 +931,8 @@ static int charger_manager_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
|
||||
err_chg_enable:
|
||||
if (desc->charger_regulators)
|
||||
regulator_bulk_free(desc->num_charger_regulators,
|
||||
desc->charger_regulators);
|
||||
regulator_bulk_free(desc->num_charger_regulators,
|
||||
desc->charger_regulators);
|
||||
err_bulk_get:
|
||||
power_supply_unregister(&cm->charger_psy);
|
||||
err_register:
|
||||
|
@ -961,10 +958,8 @@ static int __devexit charger_manager_remove(struct platform_device *pdev)
|
|||
list_del(&cm->entry);
|
||||
mutex_unlock(&cm_list_mtx);
|
||||
|
||||
if (desc->charger_regulators)
|
||||
regulator_bulk_free(desc->num_charger_regulators,
|
||||
desc->charger_regulators);
|
||||
|
||||
regulator_bulk_free(desc->num_charger_regulators,
|
||||
desc->charger_regulators);
|
||||
power_supply_unregister(&cm->charger_psy);
|
||||
kfree(cm->charger_psy.properties);
|
||||
kfree(cm->charger_stat);
|
||||
|
@ -982,9 +977,7 @@ MODULE_DEVICE_TABLE(platform, charger_manager_id);
|
|||
|
||||
static int cm_suspend_prepare(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = container_of(dev, struct platform_device,
|
||||
dev);
|
||||
struct charger_manager *cm = platform_get_drvdata(pdev);
|
||||
struct charger_manager *cm = dev_get_drvdata(dev);
|
||||
|
||||
if (!cm_suspended) {
|
||||
if (rtc_dev) {
|
||||
|
@ -1020,9 +1013,7 @@ static int cm_suspend_prepare(struct device *dev)
|
|||
|
||||
static void cm_suspend_complete(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = container_of(dev, struct platform_device,
|
||||
dev);
|
||||
struct charger_manager *cm = platform_get_drvdata(pdev);
|
||||
struct charger_manager *cm = dev_get_drvdata(dev);
|
||||
|
||||
if (cm_suspended) {
|
||||
if (rtc_dev) {
|
||||
|
|
|
@ -612,6 +612,7 @@ static s32 __devinit da9052_bat_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
goto err;
|
||||
|
||||
platform_set_drvdata(pdev, bat);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
@ -633,6 +634,7 @@ static int __devexit da9052_bat_remove(struct platform_device *pdev)
|
|||
free_irq(bat->da9052->irq_base + irq, bat);
|
||||
}
|
||||
power_supply_unregister(&bat->psy);
|
||||
kfree(bat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -645,18 +647,7 @@ static struct platform_driver da9052_bat_driver = {
|
|||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init da9052_bat_init(void)
|
||||
{
|
||||
return platform_driver_register(&da9052_bat_driver);
|
||||
}
|
||||
module_init(da9052_bat_init);
|
||||
|
||||
static void __exit da9052_bat_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&da9052_bat_driver);
|
||||
}
|
||||
module_exit(da9052_bat_exit);
|
||||
module_platform_driver(da9052_bat_driver);
|
||||
|
||||
MODULE_DESCRIPTION("DA9052 BAT Device Driver");
|
||||
MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
|
||||
|
|
|
@ -403,18 +403,7 @@ static struct i2c_driver ds278x_battery_driver = {
|
|||
.remove = ds278x_battery_remove,
|
||||
.id_table = ds278x_id,
|
||||
};
|
||||
|
||||
static int __init ds278x_init(void)
|
||||
{
|
||||
return i2c_add_driver(&ds278x_battery_driver);
|
||||
}
|
||||
module_init(ds278x_init);
|
||||
|
||||
static void __exit ds278x_exit(void)
|
||||
{
|
||||
i2c_del_driver(&ds278x_battery_driver);
|
||||
}
|
||||
module_exit(ds278x_exit);
|
||||
module_i2c_driver(ds278x_battery_driver);
|
||||
|
||||
MODULE_AUTHOR("Ryan Mallon");
|
||||
MODULE_DESCRIPTION("Maxim/Dallas DS2782 Stand-Alone Fuel Gauage IC driver");
|
||||
|
|
|
@ -480,6 +480,7 @@ fail0:
|
|||
|
||||
dev_err(&pdev->dev, "failed to register isp1704 with error %d\n", ret);
|
||||
|
||||
isp1704_charger_set_power(isp, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Driver for LP8727 Micro/Mini USB IC with intergrated charger
|
||||
* Driver for LP8727 Micro/Mini USB IC with integrated charger
|
||||
*
|
||||
* Copyright (C) 2011 Texas Instruments
|
||||
* Copyright (C) 2011 National Semiconductor
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -25,7 +26,7 @@
|
|||
#define INT1 0x4
|
||||
#define INT2 0x5
|
||||
#define STATUS1 0x6
|
||||
#define STATUS2 0x7
|
||||
#define STATUS2 0x7
|
||||
#define CHGCTRL2 0x9
|
||||
|
||||
/* CTRL1 register */
|
||||
|
@ -91,7 +92,7 @@ struct lp8727_chg {
|
|||
enum lp8727_dev_id devid;
|
||||
};
|
||||
|
||||
static int lp8727_i2c_read(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len)
|
||||
static int lp8727_read_bytes(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len)
|
||||
{
|
||||
s32 ret;
|
||||
|
||||
|
@ -102,29 +103,22 @@ static int lp8727_i2c_read(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len)
|
|||
return (ret != len) ? -EIO : 0;
|
||||
}
|
||||
|
||||
static int lp8727_i2c_write(struct lp8727_chg *pchg, u8 reg, u8 *data, u8 len)
|
||||
static inline int lp8727_read_byte(struct lp8727_chg *pchg, u8 reg, u8 *data)
|
||||
{
|
||||
s32 ret;
|
||||
return lp8727_read_bytes(pchg, reg, data, 1);
|
||||
}
|
||||
|
||||
static int lp8727_write_byte(struct lp8727_chg *pchg, u8 reg, u8 data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
mutex_lock(&pchg->xfer_lock);
|
||||
ret = i2c_smbus_write_i2c_block_data(pchg->client, reg, len, data);
|
||||
ret = i2c_smbus_write_byte_data(pchg->client, reg, data);
|
||||
mutex_unlock(&pchg->xfer_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int lp8727_i2c_read_byte(struct lp8727_chg *pchg, u8 reg,
|
||||
u8 *data)
|
||||
{
|
||||
return lp8727_i2c_read(pchg, reg, data, 1);
|
||||
}
|
||||
|
||||
static inline int lp8727_i2c_write_byte(struct lp8727_chg *pchg, u8 reg,
|
||||
u8 *data)
|
||||
{
|
||||
return lp8727_i2c_write(pchg, reg, data, 1);
|
||||
}
|
||||
|
||||
static int lp8727_is_charger_attached(const char *name, int id)
|
||||
{
|
||||
if (name) {
|
||||
|
@ -137,37 +131,41 @@ static int lp8727_is_charger_attached(const char *name, int id)
|
|||
return (id >= ID_TA && id <= ID_USB_CHG) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void lp8727_init_device(struct lp8727_chg *pchg)
|
||||
static int lp8727_init_device(struct lp8727_chg *pchg)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
val = ID200_EN | ADC_EN | CP_EN;
|
||||
if (lp8727_i2c_write_byte(pchg, CTRL1, &val))
|
||||
dev_err(pchg->dev, "i2c write err : addr=0x%.2x\n", CTRL1);
|
||||
ret = lp8727_write_byte(pchg, CTRL1, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
val = INT_EN | CHGDET_EN;
|
||||
if (lp8727_i2c_write_byte(pchg, CTRL2, &val))
|
||||
dev_err(pchg->dev, "i2c write err : addr=0x%.2x\n", CTRL2);
|
||||
ret = lp8727_write_byte(pchg, CTRL2, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lp8727_is_dedicated_charger(struct lp8727_chg *pchg)
|
||||
{
|
||||
u8 val;
|
||||
lp8727_i2c_read_byte(pchg, STATUS1, &val);
|
||||
return (val & DCPORT);
|
||||
lp8727_read_byte(pchg, STATUS1, &val);
|
||||
return val & DCPORT;
|
||||
}
|
||||
|
||||
static int lp8727_is_usb_charger(struct lp8727_chg *pchg)
|
||||
{
|
||||
u8 val;
|
||||
lp8727_i2c_read_byte(pchg, STATUS1, &val);
|
||||
return (val & CHPORT);
|
||||
lp8727_read_byte(pchg, STATUS1, &val);
|
||||
return val & CHPORT;
|
||||
}
|
||||
|
||||
static void lp8727_ctrl_switch(struct lp8727_chg *pchg, u8 sw)
|
||||
{
|
||||
u8 val = sw;
|
||||
lp8727_i2c_write_byte(pchg, SWCTRL, &val);
|
||||
lp8727_write_byte(pchg, SWCTRL, sw);
|
||||
}
|
||||
|
||||
static void lp8727_id_detection(struct lp8727_chg *pchg, u8 id, int vbusin)
|
||||
|
@ -207,9 +205,9 @@ static void lp8727_enable_chgdet(struct lp8727_chg *pchg)
|
|||
{
|
||||
u8 val;
|
||||
|
||||
lp8727_i2c_read_byte(pchg, CTRL2, &val);
|
||||
lp8727_read_byte(pchg, CTRL2, &val);
|
||||
val |= CHGDET_EN;
|
||||
lp8727_i2c_write_byte(pchg, CTRL2, &val);
|
||||
lp8727_write_byte(pchg, CTRL2, val);
|
||||
}
|
||||
|
||||
static void lp8727_delayed_func(struct work_struct *_work)
|
||||
|
@ -218,7 +216,7 @@ static void lp8727_delayed_func(struct work_struct *_work)
|
|||
struct lp8727_chg *pchg =
|
||||
container_of(_work, struct lp8727_chg, work.work);
|
||||
|
||||
if (lp8727_i2c_read(pchg, INT1, intstat, 2)) {
|
||||
if (lp8727_read_bytes(pchg, INT1, intstat, 2)) {
|
||||
dev_err(pchg->dev, "can not read INT registers\n");
|
||||
return;
|
||||
}
|
||||
|
@ -244,20 +242,22 @@ static irqreturn_t lp8727_isr_func(int irq, void *ptr)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void lp8727_intr_config(struct lp8727_chg *pchg)
|
||||
static int lp8727_intr_config(struct lp8727_chg *pchg)
|
||||
{
|
||||
INIT_DELAYED_WORK(&pchg->work, lp8727_delayed_func);
|
||||
|
||||
pchg->irqthread = create_singlethread_workqueue("lp8727-irqthd");
|
||||
if (!pchg->irqthread)
|
||||
if (!pchg->irqthread) {
|
||||
dev_err(pchg->dev, "can not create thread for lp8727\n");
|
||||
|
||||
if (request_threaded_irq(pchg->client->irq,
|
||||
NULL,
|
||||
lp8727_isr_func,
|
||||
IRQF_TRIGGER_FALLING, "lp8727_irq", pchg)) {
|
||||
dev_err(pchg->dev, "lp8727 irq can not be registered\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return request_threaded_irq(pchg->client->irq,
|
||||
NULL,
|
||||
lp8727_isr_func,
|
||||
IRQF_TRIGGER_FALLING,
|
||||
"lp8727_irq",
|
||||
pchg);
|
||||
}
|
||||
|
||||
static enum power_supply_property lp8727_charger_prop[] = {
|
||||
|
@ -300,7 +300,7 @@ static int lp8727_battery_get_property(struct power_supply *psy,
|
|||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_STATUS:
|
||||
if (lp8727_is_charger_attached(psy->name, pchg->devid)) {
|
||||
lp8727_i2c_read_byte(pchg, STATUS1, &read);
|
||||
lp8727_read_byte(pchg, STATUS1, &read);
|
||||
if (((read & CHGSTAT) >> 4) == EOC)
|
||||
val->intval = POWER_SUPPLY_STATUS_FULL;
|
||||
else
|
||||
|
@ -310,7 +310,7 @@ static int lp8727_battery_get_property(struct power_supply *psy,
|
|||
}
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_HEALTH:
|
||||
lp8727_i2c_read_byte(pchg, STATUS2, &read);
|
||||
lp8727_read_byte(pchg, STATUS2, &read);
|
||||
read = (read & TEMP_STAT) >> 5;
|
||||
if (read >= 0x1 && read <= 0x3)
|
||||
val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
|
||||
|
@ -351,7 +351,7 @@ static void lp8727_charger_changed(struct power_supply *psy)
|
|||
eoc_level = pchg->chg_parm->eoc_level;
|
||||
ichg = pchg->chg_parm->ichg;
|
||||
val = (ichg << 4) | eoc_level;
|
||||
lp8727_i2c_write_byte(pchg, CHGCTRL2, &val);
|
||||
lp8727_write_byte(pchg, CHGCTRL2, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -439,15 +439,29 @@ static int lp8727_probe(struct i2c_client *cl, const struct i2c_device_id *id)
|
|||
|
||||
mutex_init(&pchg->xfer_lock);
|
||||
|
||||
lp8727_init_device(pchg);
|
||||
lp8727_intr_config(pchg);
|
||||
ret = lp8727_init_device(pchg);
|
||||
if (ret) {
|
||||
dev_err(pchg->dev, "i2c communication err: %d", ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = lp8727_intr_config(pchg);
|
||||
if (ret) {
|
||||
dev_err(pchg->dev, "irq handler err: %d", ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = lp8727_register_psy(pchg);
|
||||
if (ret)
|
||||
dev_err(pchg->dev,
|
||||
"can not register power supplies. err=%d", ret);
|
||||
if (ret) {
|
||||
dev_err(pchg->dev, "power supplies register err: %d", ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
kfree(pchg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit lp8727_remove(struct i2c_client *cl)
|
||||
|
@ -466,6 +480,7 @@ static const struct i2c_device_id lp8727_ids[] = {
|
|||
{"lp8727", 0},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, lp8727_ids);
|
||||
|
||||
static struct i2c_driver lp8727_driver = {
|
||||
.driver = {
|
||||
|
@ -475,21 +490,9 @@ static struct i2c_driver lp8727_driver = {
|
|||
.remove = __devexit_p(lp8727_remove),
|
||||
.id_table = lp8727_ids,
|
||||
};
|
||||
module_i2c_driver(lp8727_driver);
|
||||
|
||||
static int __init lp8727_init(void)
|
||||
{
|
||||
return i2c_add_driver(&lp8727_driver);
|
||||
}
|
||||
|
||||
static void __exit lp8727_exit(void)
|
||||
{
|
||||
i2c_del_driver(&lp8727_driver);
|
||||
}
|
||||
|
||||
module_init(lp8727_init);
|
||||
module_exit(lp8727_exit);
|
||||
|
||||
MODULE_DESCRIPTION("National Semiconductor LP8727 charger driver");
|
||||
MODULE_AUTHOR
|
||||
("Woogyom Kim <milo.kim@ti.com>, Daniel Jeong <daniel.jeong@ti.com>");
|
||||
MODULE_DESCRIPTION("TI/National Semiconductor LP8727 charger driver");
|
||||
MODULE_AUTHOR("Woogyom Kim <milo.kim@ti.com>, "
|
||||
"Daniel Jeong <daniel.jeong@ti.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -290,18 +290,7 @@ static struct i2c_driver max17040_i2c_driver = {
|
|||
.resume = max17040_resume,
|
||||
.id_table = max17040_id,
|
||||
};
|
||||
|
||||
static int __init max17040_init(void)
|
||||
{
|
||||
return i2c_add_driver(&max17040_i2c_driver);
|
||||
}
|
||||
module_init(max17040_init);
|
||||
|
||||
static void __exit max17040_exit(void)
|
||||
{
|
||||
i2c_del_driver(&max17040_i2c_driver);
|
||||
}
|
||||
module_exit(max17040_exit);
|
||||
module_i2c_driver(max17040_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");
|
||||
MODULE_DESCRIPTION("MAX17040 Fuel Gauge");
|
||||
|
|
|
@ -26,14 +26,47 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/power/max17042_battery.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
/* Status register bits */
|
||||
#define STATUS_POR_BIT (1 << 1)
|
||||
#define STATUS_BST_BIT (1 << 3)
|
||||
#define STATUS_VMN_BIT (1 << 8)
|
||||
#define STATUS_TMN_BIT (1 << 9)
|
||||
#define STATUS_SMN_BIT (1 << 10)
|
||||
#define STATUS_BI_BIT (1 << 11)
|
||||
#define STATUS_VMX_BIT (1 << 12)
|
||||
#define STATUS_TMX_BIT (1 << 13)
|
||||
#define STATUS_SMX_BIT (1 << 14)
|
||||
#define STATUS_BR_BIT (1 << 15)
|
||||
|
||||
/* Interrupt mask bits */
|
||||
#define CONFIG_ALRT_BIT_ENBL (1 << 2)
|
||||
#define STATUS_INTR_SOCMIN_BIT (1 << 10)
|
||||
#define STATUS_INTR_SOCMAX_BIT (1 << 14)
|
||||
|
||||
#define VFSOC0_LOCK 0x0000
|
||||
#define VFSOC0_UNLOCK 0x0080
|
||||
#define MODEL_UNLOCK1 0X0059
|
||||
#define MODEL_UNLOCK2 0X00C4
|
||||
#define MODEL_LOCK1 0X0000
|
||||
#define MODEL_LOCK2 0X0000
|
||||
|
||||
#define dQ_ACC_DIV 0x4
|
||||
#define dP_ACC_100 0x1900
|
||||
#define dP_ACC_200 0x3200
|
||||
|
||||
struct max17042_chip {
|
||||
struct i2c_client *client;
|
||||
struct power_supply battery;
|
||||
struct max17042_platform_data *pdata;
|
||||
struct work_struct work;
|
||||
int init_complete;
|
||||
};
|
||||
|
||||
static int max17042_write_reg(struct i2c_client *client, u8 reg, u16 value)
|
||||
|
@ -87,6 +120,9 @@ static int max17042_get_property(struct power_supply *psy,
|
|||
struct max17042_chip, battery);
|
||||
int ret;
|
||||
|
||||
if (!chip->init_complete)
|
||||
return -EAGAIN;
|
||||
|
||||
switch (psp) {
|
||||
case POWER_SUPPLY_PROP_PRESENT:
|
||||
ret = max17042_read_reg(chip->client, MAX17042_STATUS);
|
||||
|
@ -136,21 +172,18 @@ static int max17042_get_property(struct power_supply *psy,
|
|||
val->intval = ret * 625 / 8;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CAPACITY:
|
||||
ret = max17042_read_reg(chip->client, MAX17042_SOC);
|
||||
ret = max17042_read_reg(chip->client, MAX17042_RepSOC);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
val->intval = ret >> 8;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CHARGE_FULL:
|
||||
ret = max17042_read_reg(chip->client, MAX17042_RepSOC);
|
||||
ret = max17042_read_reg(chip->client, MAX17042_FullCAP);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if ((ret >> 8) >= MAX17042_BATTERY_FULL)
|
||||
val->intval = 1;
|
||||
else if (ret >= 0)
|
||||
val->intval = 0;
|
||||
val->intval = ret * 1000 / 2;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_TEMP:
|
||||
ret = max17042_read_reg(chip->client, MAX17042_TEMP);
|
||||
|
@ -210,22 +243,419 @@ static int max17042_get_property(struct power_supply *psy,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int max17042_write_verify_reg(struct i2c_client *client,
|
||||
u8 reg, u16 value)
|
||||
{
|
||||
int retries = 8;
|
||||
int ret;
|
||||
u16 read_value;
|
||||
|
||||
do {
|
||||
ret = i2c_smbus_write_word_data(client, reg, value);
|
||||
read_value = max17042_read_reg(client, reg);
|
||||
if (read_value != value) {
|
||||
ret = -EIO;
|
||||
retries--;
|
||||
}
|
||||
} while (retries && read_value != value);
|
||||
|
||||
if (ret < 0)
|
||||
dev_err(&client->dev, "%s: err %d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void max17042_override_por(
|
||||
struct i2c_client *client, u8 reg, u16 value)
|
||||
{
|
||||
if (value)
|
||||
max17042_write_reg(client, reg, value);
|
||||
}
|
||||
|
||||
static inline void max10742_unlock_model(struct max17042_chip *chip)
|
||||
{
|
||||
struct i2c_client *client = chip->client;
|
||||
max17042_write_reg(client, MAX17042_MLOCKReg1, MODEL_UNLOCK1);
|
||||
max17042_write_reg(client, MAX17042_MLOCKReg2, MODEL_UNLOCK2);
|
||||
}
|
||||
|
||||
static inline void max10742_lock_model(struct max17042_chip *chip)
|
||||
{
|
||||
struct i2c_client *client = chip->client;
|
||||
max17042_write_reg(client, MAX17042_MLOCKReg1, MODEL_LOCK1);
|
||||
max17042_write_reg(client, MAX17042_MLOCKReg2, MODEL_LOCK2);
|
||||
}
|
||||
|
||||
static inline void max17042_write_model_data(struct max17042_chip *chip,
|
||||
u8 addr, int size)
|
||||
{
|
||||
struct i2c_client *client = chip->client;
|
||||
int i;
|
||||
for (i = 0; i < size; i++)
|
||||
max17042_write_reg(client, addr + i,
|
||||
chip->pdata->config_data->cell_char_tbl[i]);
|
||||
}
|
||||
|
||||
static inline void max17042_read_model_data(struct max17042_chip *chip,
|
||||
u8 addr, u16 *data, int size)
|
||||
{
|
||||
struct i2c_client *client = chip->client;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
data[i] = max17042_read_reg(client, addr + i);
|
||||
}
|
||||
|
||||
static inline int max17042_model_data_compare(struct max17042_chip *chip,
|
||||
u16 *data1, u16 *data2, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (memcmp(data1, data2, size)) {
|
||||
dev_err(&chip->client->dev, "%s compare failed\n", __func__);
|
||||
for (i = 0; i < size; i++)
|
||||
dev_info(&chip->client->dev, "0x%x, 0x%x",
|
||||
data1[i], data2[i]);
|
||||
dev_info(&chip->client->dev, "\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max17042_init_model(struct max17042_chip *chip)
|
||||
{
|
||||
int ret;
|
||||
int table_size =
|
||||
sizeof(chip->pdata->config_data->cell_char_tbl)/sizeof(u16);
|
||||
u16 *temp_data;
|
||||
|
||||
temp_data = kzalloc(table_size, GFP_KERNEL);
|
||||
if (!temp_data)
|
||||
return -ENOMEM;
|
||||
|
||||
max10742_unlock_model(chip);
|
||||
max17042_write_model_data(chip, MAX17042_MODELChrTbl,
|
||||
table_size);
|
||||
max17042_read_model_data(chip, MAX17042_MODELChrTbl, temp_data,
|
||||
table_size);
|
||||
|
||||
ret = max17042_model_data_compare(
|
||||
chip,
|
||||
chip->pdata->config_data->cell_char_tbl,
|
||||
temp_data,
|
||||
table_size);
|
||||
|
||||
max10742_lock_model(chip);
|
||||
kfree(temp_data);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max17042_verify_model_lock(struct max17042_chip *chip)
|
||||
{
|
||||
int i;
|
||||
int table_size =
|
||||
sizeof(chip->pdata->config_data->cell_char_tbl);
|
||||
u16 *temp_data;
|
||||
int ret = 0;
|
||||
|
||||
temp_data = kzalloc(table_size, GFP_KERNEL);
|
||||
if (!temp_data)
|
||||
return -ENOMEM;
|
||||
|
||||
max17042_read_model_data(chip, MAX17042_MODELChrTbl, temp_data,
|
||||
table_size);
|
||||
for (i = 0; i < table_size; i++)
|
||||
if (temp_data[i])
|
||||
ret = -EINVAL;
|
||||
|
||||
kfree(temp_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void max17042_write_config_regs(struct max17042_chip *chip)
|
||||
{
|
||||
struct max17042_config_data *config = chip->pdata->config_data;
|
||||
|
||||
max17042_write_reg(chip->client, MAX17042_CONFIG, config->config);
|
||||
max17042_write_reg(chip->client, MAX17042_LearnCFG, config->learn_cfg);
|
||||
max17042_write_reg(chip->client, MAX17042_FilterCFG,
|
||||
config->filter_cfg);
|
||||
max17042_write_reg(chip->client, MAX17042_RelaxCFG, config->relax_cfg);
|
||||
}
|
||||
|
||||
static void max17042_write_custom_regs(struct max17042_chip *chip)
|
||||
{
|
||||
struct max17042_config_data *config = chip->pdata->config_data;
|
||||
|
||||
max17042_write_verify_reg(chip->client, MAX17042_RCOMP0,
|
||||
config->rcomp0);
|
||||
max17042_write_verify_reg(chip->client, MAX17042_TempCo,
|
||||
config->tcompc0);
|
||||
max17042_write_reg(chip->client, MAX17042_EmptyTempCo,
|
||||
config->empty_tempco);
|
||||
max17042_write_verify_reg(chip->client, MAX17042_K_empty0,
|
||||
config->kempty0);
|
||||
max17042_write_verify_reg(chip->client, MAX17042_ICHGTerm,
|
||||
config->ichgt_term);
|
||||
}
|
||||
|
||||
static void max17042_update_capacity_regs(struct max17042_chip *chip)
|
||||
{
|
||||
struct max17042_config_data *config = chip->pdata->config_data;
|
||||
|
||||
max17042_write_verify_reg(chip->client, MAX17042_FullCAP,
|
||||
config->fullcap);
|
||||
max17042_write_reg(chip->client, MAX17042_DesignCap,
|
||||
config->design_cap);
|
||||
max17042_write_verify_reg(chip->client, MAX17042_FullCAPNom,
|
||||
config->fullcapnom);
|
||||
}
|
||||
|
||||
static void max17042_reset_vfsoc0_reg(struct max17042_chip *chip)
|
||||
{
|
||||
u16 vfSoc;
|
||||
|
||||
vfSoc = max17042_read_reg(chip->client, MAX17042_VFSOC);
|
||||
max17042_write_reg(chip->client, MAX17042_VFSOC0Enable, VFSOC0_UNLOCK);
|
||||
max17042_write_verify_reg(chip->client, MAX17042_VFSOC0, vfSoc);
|
||||
max17042_write_reg(chip->client, MAX17042_VFSOC0Enable, VFSOC0_LOCK);
|
||||
}
|
||||
|
||||
static void max17042_load_new_capacity_params(struct max17042_chip *chip)
|
||||
{
|
||||
u16 full_cap0, rep_cap, dq_acc, vfSoc;
|
||||
u32 rem_cap;
|
||||
|
||||
struct max17042_config_data *config = chip->pdata->config_data;
|
||||
|
||||
full_cap0 = max17042_read_reg(chip->client, MAX17042_FullCAP0);
|
||||
vfSoc = max17042_read_reg(chip->client, MAX17042_VFSOC);
|
||||
|
||||
/* fg_vfSoc needs to shifted by 8 bits to get the
|
||||
* perc in 1% accuracy, to get the right rem_cap multiply
|
||||
* full_cap0, fg_vfSoc and devide by 100
|
||||
*/
|
||||
rem_cap = ((vfSoc >> 8) * full_cap0) / 100;
|
||||
max17042_write_verify_reg(chip->client, MAX17042_RemCap, (u16)rem_cap);
|
||||
|
||||
rep_cap = (u16)rem_cap;
|
||||
max17042_write_verify_reg(chip->client, MAX17042_RepCap, rep_cap);
|
||||
|
||||
/* Write dQ_acc to 200% of Capacity and dP_acc to 200% */
|
||||
dq_acc = config->fullcap / dQ_ACC_DIV;
|
||||
max17042_write_verify_reg(chip->client, MAX17042_dQacc, dq_acc);
|
||||
max17042_write_verify_reg(chip->client, MAX17042_dPacc, dP_ACC_200);
|
||||
|
||||
max17042_write_verify_reg(chip->client, MAX17042_FullCAP,
|
||||
config->fullcap);
|
||||
max17042_write_reg(chip->client, MAX17042_DesignCap,
|
||||
config->design_cap);
|
||||
max17042_write_verify_reg(chip->client, MAX17042_FullCAPNom,
|
||||
config->fullcapnom);
|
||||
}
|
||||
|
||||
/*
|
||||
* Block write all the override values coming from platform data.
|
||||
* This function MUST be called before the POR initialization proceedure
|
||||
* specified by maxim.
|
||||
*/
|
||||
static inline void max17042_override_por_values(struct max17042_chip *chip)
|
||||
{
|
||||
struct i2c_client *client = chip->client;
|
||||
struct max17042_config_data *config = chip->pdata->config_data;
|
||||
|
||||
max17042_override_por(client, MAX17042_TGAIN, config->tgain);
|
||||
max17042_override_por(client, MAx17042_TOFF, config->toff);
|
||||
max17042_override_por(client, MAX17042_CGAIN, config->cgain);
|
||||
max17042_override_por(client, MAX17042_COFF, config->coff);
|
||||
|
||||
max17042_override_por(client, MAX17042_VALRT_Th, config->valrt_thresh);
|
||||
max17042_override_por(client, MAX17042_TALRT_Th, config->talrt_thresh);
|
||||
max17042_override_por(client, MAX17042_SALRT_Th,
|
||||
config->soc_alrt_thresh);
|
||||
max17042_override_por(client, MAX17042_CONFIG, config->config);
|
||||
max17042_override_por(client, MAX17042_SHDNTIMER, config->shdntimer);
|
||||
|
||||
max17042_override_por(client, MAX17042_DesignCap, config->design_cap);
|
||||
max17042_override_por(client, MAX17042_ICHGTerm, config->ichgt_term);
|
||||
|
||||
max17042_override_por(client, MAX17042_AtRate, config->at_rate);
|
||||
max17042_override_por(client, MAX17042_LearnCFG, config->learn_cfg);
|
||||
max17042_override_por(client, MAX17042_FilterCFG, config->filter_cfg);
|
||||
max17042_override_por(client, MAX17042_RelaxCFG, config->relax_cfg);
|
||||
max17042_override_por(client, MAX17042_MiscCFG, config->misc_cfg);
|
||||
max17042_override_por(client, MAX17042_MaskSOC, config->masksoc);
|
||||
|
||||
max17042_override_por(client, MAX17042_FullCAP, config->fullcap);
|
||||
max17042_override_por(client, MAX17042_FullCAPNom, config->fullcapnom);
|
||||
max17042_override_por(client, MAX17042_SOC_empty, config->socempty);
|
||||
max17042_override_por(client, MAX17042_LAvg_empty, config->lavg_empty);
|
||||
max17042_override_por(client, MAX17042_dQacc, config->dqacc);
|
||||
max17042_override_por(client, MAX17042_dPacc, config->dpacc);
|
||||
|
||||
max17042_override_por(client, MAX17042_V_empty, config->vempty);
|
||||
max17042_override_por(client, MAX17042_TempNom, config->temp_nom);
|
||||
max17042_override_por(client, MAX17042_TempLim, config->temp_lim);
|
||||
max17042_override_por(client, MAX17042_FCTC, config->fctc);
|
||||
max17042_override_por(client, MAX17042_RCOMP0, config->rcomp0);
|
||||
max17042_override_por(client, MAX17042_TempCo, config->tcompc0);
|
||||
max17042_override_por(client, MAX17042_EmptyTempCo,
|
||||
config->empty_tempco);
|
||||
max17042_override_por(client, MAX17042_K_empty0, config->kempty0);
|
||||
}
|
||||
|
||||
static int max17042_init_chip(struct max17042_chip *chip)
|
||||
{
|
||||
int ret;
|
||||
int val;
|
||||
|
||||
max17042_override_por_values(chip);
|
||||
/* After Power up, the MAX17042 requires 500mS in order
|
||||
* to perform signal debouncing and initial SOC reporting
|
||||
*/
|
||||
msleep(500);
|
||||
|
||||
/* Initialize configaration */
|
||||
max17042_write_config_regs(chip);
|
||||
|
||||
/* write cell characterization data */
|
||||
ret = max17042_init_model(chip);
|
||||
if (ret) {
|
||||
dev_err(&chip->client->dev, "%s init failed\n",
|
||||
__func__);
|
||||
return -EIO;
|
||||
}
|
||||
max17042_verify_model_lock(chip);
|
||||
if (ret) {
|
||||
dev_err(&chip->client->dev, "%s lock verify failed\n",
|
||||
__func__);
|
||||
return -EIO;
|
||||
}
|
||||
/* write custom parameters */
|
||||
max17042_write_custom_regs(chip);
|
||||
|
||||
/* update capacity params */
|
||||
max17042_update_capacity_regs(chip);
|
||||
|
||||
/* delay must be atleast 350mS to allow VFSOC
|
||||
* to be calculated from the new configuration
|
||||
*/
|
||||
msleep(350);
|
||||
|
||||
/* reset vfsoc0 reg */
|
||||
max17042_reset_vfsoc0_reg(chip);
|
||||
|
||||
/* load new capacity params */
|
||||
max17042_load_new_capacity_params(chip);
|
||||
|
||||
/* Init complete, Clear the POR bit */
|
||||
val = max17042_read_reg(chip->client, MAX17042_STATUS);
|
||||
max17042_write_reg(chip->client, MAX17042_STATUS,
|
||||
val & (~STATUS_POR_BIT));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void max17042_set_soc_threshold(struct max17042_chip *chip, u16 off)
|
||||
{
|
||||
u16 soc, soc_tr;
|
||||
|
||||
/* program interrupt thesholds such that we should
|
||||
* get interrupt for every 'off' perc change in the soc
|
||||
*/
|
||||
soc = max17042_read_reg(chip->client, MAX17042_RepSOC) >> 8;
|
||||
soc_tr = (soc + off) << 8;
|
||||
soc_tr |= (soc - off);
|
||||
max17042_write_reg(chip->client, MAX17042_SALRT_Th, soc_tr);
|
||||
}
|
||||
|
||||
static irqreturn_t max17042_thread_handler(int id, void *dev)
|
||||
{
|
||||
struct max17042_chip *chip = dev;
|
||||
u16 val;
|
||||
|
||||
val = max17042_read_reg(chip->client, MAX17042_STATUS);
|
||||
if ((val & STATUS_INTR_SOCMIN_BIT) ||
|
||||
(val & STATUS_INTR_SOCMAX_BIT)) {
|
||||
dev_info(&chip->client->dev, "SOC threshold INTR\n");
|
||||
max17042_set_soc_threshold(chip, 1);
|
||||
}
|
||||
|
||||
power_supply_changed(&chip->battery);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void max17042_init_worker(struct work_struct *work)
|
||||
{
|
||||
struct max17042_chip *chip = container_of(work,
|
||||
struct max17042_chip, work);
|
||||
int ret;
|
||||
|
||||
/* Initialize registers according to values from the platform data */
|
||||
if (chip->pdata->enable_por_init && chip->pdata->config_data) {
|
||||
ret = max17042_init_chip(chip);
|
||||
if (ret)
|
||||
return;
|
||||
}
|
||||
|
||||
chip->init_complete = 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static struct max17042_platform_data *
|
||||
max17042_get_pdata(struct device *dev)
|
||||
{
|
||||
struct device_node *np = dev->of_node;
|
||||
u32 prop;
|
||||
struct max17042_platform_data *pdata;
|
||||
|
||||
if (!np)
|
||||
return dev->platform_data;
|
||||
|
||||
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* Require current sense resistor value to be specified for
|
||||
* current-sense functionality to be enabled at all.
|
||||
*/
|
||||
if (of_property_read_u32(np, "maxim,rsns-microohm", &prop) == 0) {
|
||||
pdata->r_sns = prop;
|
||||
pdata->enable_current_sense = true;
|
||||
}
|
||||
|
||||
return pdata;
|
||||
}
|
||||
#else
|
||||
static struct max17042_platform_data *
|
||||
max17042_get_pdata(struct device *dev)
|
||||
{
|
||||
return dev->platform_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __devinit max17042_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
|
||||
struct max17042_chip *chip;
|
||||
int ret;
|
||||
int reg;
|
||||
|
||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
|
||||
return -EIO;
|
||||
|
||||
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
|
||||
chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
return -ENOMEM;
|
||||
|
||||
chip->client = client;
|
||||
chip->pdata = client->dev.platform_data;
|
||||
chip->pdata = max17042_get_pdata(&client->dev);
|
||||
if (!chip->pdata) {
|
||||
dev_err(&client->dev, "no platform data provided\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, chip);
|
||||
|
||||
|
@ -243,17 +673,9 @@ static int __devinit max17042_probe(struct i2c_client *client,
|
|||
if (chip->pdata->r_sns == 0)
|
||||
chip->pdata->r_sns = MAX17042_DEFAULT_SNS_RESISTOR;
|
||||
|
||||
ret = power_supply_register(&client->dev, &chip->battery);
|
||||
if (ret) {
|
||||
dev_err(&client->dev, "failed: power supply register\n");
|
||||
kfree(chip);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initialize registers according to values from the platform data */
|
||||
if (chip->pdata->init_data)
|
||||
max17042_set_reg(client, chip->pdata->init_data,
|
||||
chip->pdata->num_init_data);
|
||||
chip->pdata->num_init_data);
|
||||
|
||||
if (!chip->pdata->enable_current_sense) {
|
||||
max17042_write_reg(client, MAX17042_CGAIN, 0x0000);
|
||||
|
@ -261,7 +683,34 @@ static int __devinit max17042_probe(struct i2c_client *client,
|
|||
max17042_write_reg(client, MAX17042_LearnCFG, 0x0007);
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (client->irq) {
|
||||
ret = request_threaded_irq(client->irq, NULL,
|
||||
max17042_thread_handler,
|
||||
IRQF_TRIGGER_FALLING,
|
||||
chip->battery.name, chip);
|
||||
if (!ret) {
|
||||
reg = max17042_read_reg(client, MAX17042_CONFIG);
|
||||
reg |= CONFIG_ALRT_BIT_ENBL;
|
||||
max17042_write_reg(client, MAX17042_CONFIG, reg);
|
||||
max17042_set_soc_threshold(chip, 1);
|
||||
} else
|
||||
dev_err(&client->dev, "%s(): cannot get IRQ\n",
|
||||
__func__);
|
||||
}
|
||||
|
||||
reg = max17042_read_reg(chip->client, MAX17042_STATUS);
|
||||
|
||||
if (reg & STATUS_POR_BIT) {
|
||||
INIT_WORK(&chip->work, max17042_init_worker);
|
||||
schedule_work(&chip->work);
|
||||
} else {
|
||||
chip->init_complete = 1;
|
||||
}
|
||||
|
||||
ret = power_supply_register(&client->dev, &chip->battery);
|
||||
if (ret)
|
||||
dev_err(&client->dev, "failed: power supply register\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit max17042_remove(struct i2c_client *client)
|
||||
|
@ -269,10 +718,17 @@ static int __devexit max17042_remove(struct i2c_client *client)
|
|||
struct max17042_chip *chip = i2c_get_clientdata(client);
|
||||
|
||||
power_supply_unregister(&chip->battery);
|
||||
kfree(chip);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id max17042_dt_match[] = {
|
||||
{ .compatible = "maxim,max17042" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max17042_dt_match);
|
||||
#endif
|
||||
|
||||
static const struct i2c_device_id max17042_id[] = {
|
||||
{ "max17042", 0 },
|
||||
{ }
|
||||
|
@ -282,23 +738,13 @@ MODULE_DEVICE_TABLE(i2c, max17042_id);
|
|||
static struct i2c_driver max17042_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "max17042",
|
||||
.of_match_table = of_match_ptr(max17042_dt_match),
|
||||
},
|
||||
.probe = max17042_probe,
|
||||
.remove = __devexit_p(max17042_remove),
|
||||
.id_table = max17042_id,
|
||||
};
|
||||
|
||||
static int __init max17042_init(void)
|
||||
{
|
||||
return i2c_add_driver(&max17042_i2c_driver);
|
||||
}
|
||||
module_init(max17042_init);
|
||||
|
||||
static void __exit max17042_exit(void)
|
||||
{
|
||||
i2c_del_driver(&max17042_i2c_driver);
|
||||
}
|
||||
module_exit(max17042_exit);
|
||||
module_i2c_driver(max17042_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
|
||||
MODULE_DESCRIPTION("MAX17042 Fuel Gauge");
|
||||
|
|
|
@ -852,18 +852,7 @@ static struct i2c_driver sbs_battery_driver = {
|
|||
.of_match_table = sbs_dt_ids,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init sbs_battery_init(void)
|
||||
{
|
||||
return i2c_add_driver(&sbs_battery_driver);
|
||||
}
|
||||
module_init(sbs_battery_init);
|
||||
|
||||
static void __exit sbs_battery_exit(void)
|
||||
{
|
||||
i2c_del_driver(&sbs_battery_driver);
|
||||
}
|
||||
module_exit(sbs_battery_exit);
|
||||
module_i2c_driver(sbs_battery_driver);
|
||||
|
||||
MODULE_DESCRIPTION("SBS battery monitor driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -316,19 +316,7 @@ static struct i2c_driver z2_batt_driver = {
|
|||
.remove = __devexit_p(z2_batt_remove),
|
||||
.id_table = z2_batt_id,
|
||||
};
|
||||
|
||||
static int __init z2_batt_init(void)
|
||||
{
|
||||
return i2c_add_driver(&z2_batt_driver);
|
||||
}
|
||||
|
||||
static void __exit z2_batt_exit(void)
|
||||
{
|
||||
i2c_del_driver(&z2_batt_driver);
|
||||
}
|
||||
|
||||
module_init(z2_batt_init);
|
||||
module_exit(z2_batt_exit);
|
||||
module_i2c_driver(z2_batt_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_AUTHOR("Peter Edwards <sweetlilmre@gmail.com>");
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
/*
|
||||
* LP8727 Micro/Mini USB IC with integrated charger
|
||||
*
|
||||
* Copyright (C) 2011 Texas Instruments
|
||||
* Copyright (C) 2011 National Semiconductor
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -32,13 +35,24 @@ enum lp8727_ichg {
|
|||
ICHG_1000mA,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct lp8727_chg_param
|
||||
* @eoc_level : end of charge level setting
|
||||
* @ichg : charging current
|
||||
*/
|
||||
struct lp8727_chg_param {
|
||||
/* end of charge level setting */
|
||||
enum lp8727_eoc_level eoc_level;
|
||||
/* charging current */
|
||||
enum lp8727_ichg ichg;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct lp8727_platform_data
|
||||
* @get_batt_present : check battery status - exists or not
|
||||
* @get_batt_level : get battery voltage (mV)
|
||||
* @get_batt_capacity : get battery capacity (%)
|
||||
* @get_batt_temp : get battery temperature
|
||||
* @ac, @usb : charging parameters each charger type
|
||||
*/
|
||||
struct lp8727_platform_data {
|
||||
u8 (*get_batt_present)(void);
|
||||
u16 (*get_batt_level)(void);
|
||||
|
|
|
@ -146,6 +146,279 @@ struct abx500_init_settings {
|
|||
u8 setting;
|
||||
};
|
||||
|
||||
/* Battery driver related data */
|
||||
/*
|
||||
* ADC for the battery thermistor.
|
||||
* When using the ABx500_ADC_THERM_BATCTRL the battery ID resistor is combined
|
||||
* with a NTC resistor to both identify the battery and to measure its
|
||||
* temperature. Different phone manufactures uses different techniques to both
|
||||
* identify the battery and to read its temperature.
|
||||
*/
|
||||
enum abx500_adc_therm {
|
||||
ABx500_ADC_THERM_BATCTRL,
|
||||
ABx500_ADC_THERM_BATTEMP,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct abx500_res_to_temp - defines one point in a temp to res curve. To
|
||||
* be used in battery packs that combines the identification resistor with a
|
||||
* NTC resistor.
|
||||
* @temp: battery pack temperature in Celcius
|
||||
* @resist: NTC resistor net total resistance
|
||||
*/
|
||||
struct abx500_res_to_temp {
|
||||
int temp;
|
||||
int resist;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct abx500_v_to_cap - Table for translating voltage to capacity
|
||||
* @voltage: Voltage in mV
|
||||
* @capacity: Capacity in percent
|
||||
*/
|
||||
struct abx500_v_to_cap {
|
||||
int voltage;
|
||||
int capacity;
|
||||
};
|
||||
|
||||
/* Forward declaration */
|
||||
struct abx500_fg;
|
||||
|
||||
/**
|
||||
* struct abx500_fg_parameters - Fuel gauge algorithm parameters, in seconds
|
||||
* if not specified
|
||||
* @recovery_sleep_timer: Time between measurements while recovering
|
||||
* @recovery_total_time: Total recovery time
|
||||
* @init_timer: Measurement interval during startup
|
||||
* @init_discard_time: Time we discard voltage measurement at startup
|
||||
* @init_total_time: Total init time during startup
|
||||
* @high_curr_time: Time current has to be high to go to recovery
|
||||
* @accu_charging: FG accumulation time while charging
|
||||
* @accu_high_curr: FG accumulation time in high current mode
|
||||
* @high_curr_threshold: High current threshold, in mA
|
||||
* @lowbat_threshold: Low battery threshold, in mV
|
||||
* @overbat_threshold: Over battery threshold, in mV
|
||||
* @battok_falling_th_sel0 Threshold in mV for battOk signal sel0
|
||||
* Resolution in 50 mV step.
|
||||
* @battok_raising_th_sel1 Threshold in mV for battOk signal sel1
|
||||
* Resolution in 50 mV step.
|
||||
* @user_cap_limit Capacity reported from user must be within this
|
||||
* limit to be considered as sane, in percentage
|
||||
* points.
|
||||
* @maint_thres This is the threshold where we stop reporting
|
||||
* battery full while in maintenance, in per cent
|
||||
*/
|
||||
struct abx500_fg_parameters {
|
||||
int recovery_sleep_timer;
|
||||
int recovery_total_time;
|
||||
int init_timer;
|
||||
int init_discard_time;
|
||||
int init_total_time;
|
||||
int high_curr_time;
|
||||
int accu_charging;
|
||||
int accu_high_curr;
|
||||
int high_curr_threshold;
|
||||
int lowbat_threshold;
|
||||
int overbat_threshold;
|
||||
int battok_falling_th_sel0;
|
||||
int battok_raising_th_sel1;
|
||||
int user_cap_limit;
|
||||
int maint_thres;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct abx500_charger_maximization - struct used by the board config.
|
||||
* @use_maxi: Enable maximization for this battery type
|
||||
* @maxi_chg_curr: Maximum charger current allowed
|
||||
* @maxi_wait_cycles: cycles to wait before setting charger current
|
||||
* @charger_curr_step delta between two charger current settings (mA)
|
||||
*/
|
||||
struct abx500_maxim_parameters {
|
||||
bool ena_maxi;
|
||||
int chg_curr;
|
||||
int wait_cycles;
|
||||
int charger_curr_step;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct abx500_battery_type - different batteries supported
|
||||
* @name: battery technology
|
||||
* @resis_high: battery upper resistance limit
|
||||
* @resis_low: battery lower resistance limit
|
||||
* @charge_full_design: Maximum battery capacity in mAh
|
||||
* @nominal_voltage: Nominal voltage of the battery in mV
|
||||
* @termination_vol: max voltage upto which battery can be charged
|
||||
* @termination_curr battery charging termination current in mA
|
||||
* @recharge_vol battery voltage limit that will trigger a new
|
||||
* full charging cycle in the case where maintenan-
|
||||
* -ce charging has been disabled
|
||||
* @normal_cur_lvl: charger current in normal state in mA
|
||||
* @normal_vol_lvl: charger voltage in normal state in mV
|
||||
* @maint_a_cur_lvl: charger current in maintenance A state in mA
|
||||
* @maint_a_vol_lvl: charger voltage in maintenance A state in mV
|
||||
* @maint_a_chg_timer_h: charge time in maintenance A state
|
||||
* @maint_b_cur_lvl: charger current in maintenance B state in mA
|
||||
* @maint_b_vol_lvl: charger voltage in maintenance B state in mV
|
||||
* @maint_b_chg_timer_h: charge time in maintenance B state
|
||||
* @low_high_cur_lvl: charger current in temp low/high state in mA
|
||||
* @low_high_vol_lvl: charger voltage in temp low/high state in mV'
|
||||
* @battery_resistance: battery inner resistance in mOhm.
|
||||
* @n_r_t_tbl_elements: number of elements in r_to_t_tbl
|
||||
* @r_to_t_tbl: table containing resistance to temp points
|
||||
* @n_v_cap_tbl_elements: number of elements in v_to_cap_tbl
|
||||
* @v_to_cap_tbl: Voltage to capacity (in %) table
|
||||
* @n_batres_tbl_elements number of elements in the batres_tbl
|
||||
* @batres_tbl battery internal resistance vs temperature table
|
||||
*/
|
||||
struct abx500_battery_type {
|
||||
int name;
|
||||
int resis_high;
|
||||
int resis_low;
|
||||
int charge_full_design;
|
||||
int nominal_voltage;
|
||||
int termination_vol;
|
||||
int termination_curr;
|
||||
int recharge_vol;
|
||||
int normal_cur_lvl;
|
||||
int normal_vol_lvl;
|
||||
int maint_a_cur_lvl;
|
||||
int maint_a_vol_lvl;
|
||||
int maint_a_chg_timer_h;
|
||||
int maint_b_cur_lvl;
|
||||
int maint_b_vol_lvl;
|
||||
int maint_b_chg_timer_h;
|
||||
int low_high_cur_lvl;
|
||||
int low_high_vol_lvl;
|
||||
int battery_resistance;
|
||||
int n_temp_tbl_elements;
|
||||
struct abx500_res_to_temp *r_to_t_tbl;
|
||||
int n_v_cap_tbl_elements;
|
||||
struct abx500_v_to_cap *v_to_cap_tbl;
|
||||
int n_batres_tbl_elements;
|
||||
struct batres_vs_temp *batres_tbl;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct abx500_bm_capacity_levels - abx500 capacity level data
|
||||
* @critical: critical capacity level in percent
|
||||
* @low: low capacity level in percent
|
||||
* @normal: normal capacity level in percent
|
||||
* @high: high capacity level in percent
|
||||
* @full: full capacity level in percent
|
||||
*/
|
||||
struct abx500_bm_capacity_levels {
|
||||
int critical;
|
||||
int low;
|
||||
int normal;
|
||||
int high;
|
||||
int full;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct abx500_bm_charger_parameters - Charger specific parameters
|
||||
* @usb_volt_max: maximum allowed USB charger voltage in mV
|
||||
* @usb_curr_max: maximum allowed USB charger current in mA
|
||||
* @ac_volt_max: maximum allowed AC charger voltage in mV
|
||||
* @ac_curr_max: maximum allowed AC charger current in mA
|
||||
*/
|
||||
struct abx500_bm_charger_parameters {
|
||||
int usb_volt_max;
|
||||
int usb_curr_max;
|
||||
int ac_volt_max;
|
||||
int ac_curr_max;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct abx500_bm_data - abx500 battery management data
|
||||
* @temp_under under this temp, charging is stopped
|
||||
* @temp_low between this temp and temp_under charging is reduced
|
||||
* @temp_high between this temp and temp_over charging is reduced
|
||||
* @temp_over over this temp, charging is stopped
|
||||
* @temp_now present battery temperature
|
||||
* @temp_interval_chg temperature measurement interval in s when charging
|
||||
* @temp_interval_nochg temperature measurement interval in s when not charging
|
||||
* @main_safety_tmr_h safety timer for main charger
|
||||
* @usb_safety_tmr_h safety timer for usb charger
|
||||
* @bkup_bat_v voltage which we charge the backup battery with
|
||||
* @bkup_bat_i current which we charge the backup battery with
|
||||
* @no_maintenance indicates that maintenance charging is disabled
|
||||
* @abx500_adc_therm placement of thermistor, batctrl or battemp adc
|
||||
* @chg_unknown_bat flag to enable charging of unknown batteries
|
||||
* @enable_overshoot flag to enable VBAT overshoot control
|
||||
* @auto_trig flag to enable auto adc trigger
|
||||
* @fg_res resistance of FG resistor in 0.1mOhm
|
||||
* @n_btypes number of elements in array bat_type
|
||||
* @batt_id index of the identified battery in array bat_type
|
||||
* @interval_charging charge alg cycle period time when charging (sec)
|
||||
* @interval_not_charging charge alg cycle period time when not charging (sec)
|
||||
* @temp_hysteresis temperature hysteresis
|
||||
* @gnd_lift_resistance Battery ground to phone ground resistance (mOhm)
|
||||
* @maxi: maximization parameters
|
||||
* @cap_levels capacity in percent for the different capacity levels
|
||||
* @bat_type table of supported battery types
|
||||
* @chg_params charger parameters
|
||||
* @fg_params fuel gauge parameters
|
||||
*/
|
||||
struct abx500_bm_data {
|
||||
int temp_under;
|
||||
int temp_low;
|
||||
int temp_high;
|
||||
int temp_over;
|
||||
int temp_now;
|
||||
int temp_interval_chg;
|
||||
int temp_interval_nochg;
|
||||
int main_safety_tmr_h;
|
||||
int usb_safety_tmr_h;
|
||||
int bkup_bat_v;
|
||||
int bkup_bat_i;
|
||||
bool no_maintenance;
|
||||
bool chg_unknown_bat;
|
||||
bool enable_overshoot;
|
||||
bool auto_trig;
|
||||
enum abx500_adc_therm adc_therm;
|
||||
int fg_res;
|
||||
int n_btypes;
|
||||
int batt_id;
|
||||
int interval_charging;
|
||||
int interval_not_charging;
|
||||
int temp_hysteresis;
|
||||
int gnd_lift_resistance;
|
||||
const struct abx500_maxim_parameters *maxi;
|
||||
const struct abx500_bm_capacity_levels *cap_levels;
|
||||
const struct abx500_battery_type *bat_type;
|
||||
const struct abx500_bm_charger_parameters *chg_params;
|
||||
const struct abx500_fg_parameters *fg_params;
|
||||
};
|
||||
|
||||
struct abx500_chargalg_platform_data {
|
||||
char **supplied_to;
|
||||
size_t num_supplicants;
|
||||
};
|
||||
|
||||
struct abx500_charger_platform_data {
|
||||
char **supplied_to;
|
||||
size_t num_supplicants;
|
||||
bool autopower_cfg;
|
||||
};
|
||||
|
||||
struct abx500_btemp_platform_data {
|
||||
char **supplied_to;
|
||||
size_t num_supplicants;
|
||||
};
|
||||
|
||||
struct abx500_fg_platform_data {
|
||||
char **supplied_to;
|
||||
size_t num_supplicants;
|
||||
};
|
||||
|
||||
struct abx500_bm_plat_data {
|
||||
struct abx500_bm_data *battery;
|
||||
struct abx500_charger_platform_data *charger;
|
||||
struct abx500_btemp_platform_data *btemp;
|
||||
struct abx500_fg_platform_data *fg;
|
||||
struct abx500_chargalg_platform_data *chargalg;
|
||||
};
|
||||
|
||||
int abx500_set_register_interruptible(struct device *dev, u8 bank, u8 reg,
|
||||
u8 value);
|
||||
int abx500_get_register_interruptible(struct device *dev, u8 bank, u8 reg,
|
||||
|
|
|
@ -0,0 +1,474 @@
|
|||
/*
|
||||
* Copyright ST-Ericsson 2012.
|
||||
*
|
||||
* Author: Arun Murthy <arun.murthy@stericsson.com>
|
||||
* Licensed under GPLv2.
|
||||
*/
|
||||
|
||||
#ifndef _AB8500_BM_H
|
||||
#define _AB8500_BM_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mfd/abx500.h>
|
||||
|
||||
/*
|
||||
* System control 2 register offsets.
|
||||
* bank = 0x02
|
||||
*/
|
||||
#define AB8500_MAIN_WDOG_CTRL_REG 0x01
|
||||
#define AB8500_LOW_BAT_REG 0x03
|
||||
#define AB8500_BATT_OK_REG 0x04
|
||||
/*
|
||||
* USB/ULPI register offsets
|
||||
* Bank : 0x5
|
||||
*/
|
||||
#define AB8500_USB_LINE_STAT_REG 0x80
|
||||
|
||||
/*
|
||||
* Charger / status register offfsets
|
||||
* Bank : 0x0B
|
||||
*/
|
||||
#define AB8500_CH_STATUS1_REG 0x00
|
||||
#define AB8500_CH_STATUS2_REG 0x01
|
||||
#define AB8500_CH_USBCH_STAT1_REG 0x02
|
||||
#define AB8500_CH_USBCH_STAT2_REG 0x03
|
||||
#define AB8500_CH_FSM_STAT_REG 0x04
|
||||
#define AB8500_CH_STAT_REG 0x05
|
||||
|
||||
/*
|
||||
* Charger / control register offfsets
|
||||
* Bank : 0x0B
|
||||
*/
|
||||
#define AB8500_CH_VOLT_LVL_REG 0x40
|
||||
#define AB8500_CH_VOLT_LVL_MAX_REG 0x41 /*Only in Cut2.0*/
|
||||
#define AB8500_CH_OPT_CRNTLVL_REG 0x42
|
||||
#define AB8500_CH_OPT_CRNTLVL_MAX_REG 0x43 /*Only in Cut2.0*/
|
||||
#define AB8500_CH_WD_TIMER_REG 0x50
|
||||
#define AB8500_CHARG_WD_CTRL 0x51
|
||||
#define AB8500_BTEMP_HIGH_TH 0x52
|
||||
#define AB8500_LED_INDICATOR_PWM_CTRL 0x53
|
||||
#define AB8500_LED_INDICATOR_PWM_DUTY 0x54
|
||||
#define AB8500_BATT_OVV 0x55
|
||||
#define AB8500_CHARGER_CTRL 0x56
|
||||
#define AB8500_BAT_CTRL_CURRENT_SOURCE 0x60 /*Only in Cut2.0*/
|
||||
|
||||
/*
|
||||
* Charger / main control register offsets
|
||||
* Bank : 0x0B
|
||||
*/
|
||||
#define AB8500_MCH_CTRL1 0x80
|
||||
#define AB8500_MCH_CTRL2 0x81
|
||||
#define AB8500_MCH_IPT_CURLVL_REG 0x82
|
||||
#define AB8500_CH_WD_REG 0x83
|
||||
|
||||
/*
|
||||
* Charger / USB control register offsets
|
||||
* Bank : 0x0B
|
||||
*/
|
||||
#define AB8500_USBCH_CTRL1_REG 0xC0
|
||||
#define AB8500_USBCH_CTRL2_REG 0xC1
|
||||
#define AB8500_USBCH_IPT_CRNTLVL_REG 0xC2
|
||||
|
||||
/*
|
||||
* Gas Gauge register offsets
|
||||
* Bank : 0x0C
|
||||
*/
|
||||
#define AB8500_GASG_CC_CTRL_REG 0x00
|
||||
#define AB8500_GASG_CC_ACCU1_REG 0x01
|
||||
#define AB8500_GASG_CC_ACCU2_REG 0x02
|
||||
#define AB8500_GASG_CC_ACCU3_REG 0x03
|
||||
#define AB8500_GASG_CC_ACCU4_REG 0x04
|
||||
#define AB8500_GASG_CC_SMPL_CNTRL_REG 0x05
|
||||
#define AB8500_GASG_CC_SMPL_CNTRH_REG 0x06
|
||||
#define AB8500_GASG_CC_SMPL_CNVL_REG 0x07
|
||||
#define AB8500_GASG_CC_SMPL_CNVH_REG 0x08
|
||||
#define AB8500_GASG_CC_CNTR_AVGOFF_REG 0x09
|
||||
#define AB8500_GASG_CC_OFFSET_REG 0x0A
|
||||
#define AB8500_GASG_CC_NCOV_ACCU 0x10
|
||||
#define AB8500_GASG_CC_NCOV_ACCU_CTRL 0x11
|
||||
#define AB8500_GASG_CC_NCOV_ACCU_LOW 0x12
|
||||
#define AB8500_GASG_CC_NCOV_ACCU_MED 0x13
|
||||
#define AB8500_GASG_CC_NCOV_ACCU_HIGH 0x14
|
||||
|
||||
/*
|
||||
* Interrupt register offsets
|
||||
* Bank : 0x0E
|
||||
*/
|
||||
#define AB8500_IT_SOURCE2_REG 0x01
|
||||
#define AB8500_IT_SOURCE21_REG 0x14
|
||||
|
||||
/*
|
||||
* RTC register offsets
|
||||
* Bank: 0x0F
|
||||
*/
|
||||
#define AB8500_RTC_BACKUP_CHG_REG 0x0C
|
||||
#define AB8500_RTC_CC_CONF_REG 0x01
|
||||
#define AB8500_RTC_CTRL_REG 0x0B
|
||||
|
||||
/*
|
||||
* OTP register offsets
|
||||
* Bank : 0x15
|
||||
*/
|
||||
#define AB8500_OTP_CONF_15 0x0E
|
||||
|
||||
/* GPADC constants from AB8500 spec, UM0836 */
|
||||
#define ADC_RESOLUTION 1024
|
||||
#define ADC_CH_MAIN_MIN 0
|
||||
#define ADC_CH_MAIN_MAX 20030
|
||||
#define ADC_CH_VBUS_MIN 0
|
||||
#define ADC_CH_VBUS_MAX 20030
|
||||
#define ADC_CH_VBAT_MIN 2300
|
||||
#define ADC_CH_VBAT_MAX 4800
|
||||
#define ADC_CH_BKBAT_MIN 0
|
||||
#define ADC_CH_BKBAT_MAX 3200
|
||||
|
||||
/* Main charge i/p current */
|
||||
#define MAIN_CH_IP_CUR_0P9A 0x80
|
||||
#define MAIN_CH_IP_CUR_1P0A 0x90
|
||||
#define MAIN_CH_IP_CUR_1P1A 0xA0
|
||||
#define MAIN_CH_IP_CUR_1P2A 0xB0
|
||||
#define MAIN_CH_IP_CUR_1P3A 0xC0
|
||||
#define MAIN_CH_IP_CUR_1P4A 0xD0
|
||||
#define MAIN_CH_IP_CUR_1P5A 0xE0
|
||||
|
||||
/* ChVoltLevel */
|
||||
#define CH_VOL_LVL_3P5 0x00
|
||||
#define CH_VOL_LVL_4P0 0x14
|
||||
#define CH_VOL_LVL_4P05 0x16
|
||||
#define CH_VOL_LVL_4P1 0x1B
|
||||
#define CH_VOL_LVL_4P15 0x20
|
||||
#define CH_VOL_LVL_4P2 0x25
|
||||
#define CH_VOL_LVL_4P6 0x4D
|
||||
|
||||
/* ChOutputCurrentLevel */
|
||||
#define CH_OP_CUR_LVL_0P1 0x00
|
||||
#define CH_OP_CUR_LVL_0P2 0x01
|
||||
#define CH_OP_CUR_LVL_0P3 0x02
|
||||
#define CH_OP_CUR_LVL_0P4 0x03
|
||||
#define CH_OP_CUR_LVL_0P5 0x04
|
||||
#define CH_OP_CUR_LVL_0P6 0x05
|
||||
#define CH_OP_CUR_LVL_0P7 0x06
|
||||
#define CH_OP_CUR_LVL_0P8 0x07
|
||||
#define CH_OP_CUR_LVL_0P9 0x08
|
||||
#define CH_OP_CUR_LVL_1P4 0x0D
|
||||
#define CH_OP_CUR_LVL_1P5 0x0E
|
||||
#define CH_OP_CUR_LVL_1P6 0x0F
|
||||
|
||||
/* BTEMP High thermal limits */
|
||||
#define BTEMP_HIGH_TH_57_0 0x00
|
||||
#define BTEMP_HIGH_TH_52 0x01
|
||||
#define BTEMP_HIGH_TH_57_1 0x02
|
||||
#define BTEMP_HIGH_TH_62 0x03
|
||||
|
||||
/* current is mA */
|
||||
#define USB_0P1A 100
|
||||
#define USB_0P2A 200
|
||||
#define USB_0P3A 300
|
||||
#define USB_0P4A 400
|
||||
#define USB_0P5A 500
|
||||
|
||||
#define LOW_BAT_3P1V 0x20
|
||||
#define LOW_BAT_2P3V 0x00
|
||||
#define LOW_BAT_RESET 0x01
|
||||
#define LOW_BAT_ENABLE 0x01
|
||||
|
||||
/* Backup battery constants */
|
||||
#define BUP_ICH_SEL_50UA 0x00
|
||||
#define BUP_ICH_SEL_150UA 0x04
|
||||
#define BUP_ICH_SEL_300UA 0x08
|
||||
#define BUP_ICH_SEL_700UA 0x0C
|
||||
|
||||
#define BUP_VCH_SEL_2P5V 0x00
|
||||
#define BUP_VCH_SEL_2P6V 0x01
|
||||
#define BUP_VCH_SEL_2P8V 0x02
|
||||
#define BUP_VCH_SEL_3P1V 0x03
|
||||
|
||||
/* Battery OVV constants */
|
||||
#define BATT_OVV_ENA 0x02
|
||||
#define BATT_OVV_TH_3P7 0x00
|
||||
#define BATT_OVV_TH_4P75 0x01
|
||||
|
||||
/* A value to indicate over voltage */
|
||||
#define BATT_OVV_VALUE 4750
|
||||
|
||||
/* VBUS OVV constants */
|
||||
#define VBUS_OVV_SELECT_MASK 0x78
|
||||
#define VBUS_OVV_SELECT_5P6V 0x00
|
||||
#define VBUS_OVV_SELECT_5P7V 0x08
|
||||
#define VBUS_OVV_SELECT_5P8V 0x10
|
||||
#define VBUS_OVV_SELECT_5P9V 0x18
|
||||
#define VBUS_OVV_SELECT_6P0V 0x20
|
||||
#define VBUS_OVV_SELECT_6P1V 0x28
|
||||
#define VBUS_OVV_SELECT_6P2V 0x30
|
||||
#define VBUS_OVV_SELECT_6P3V 0x38
|
||||
|
||||
#define VBUS_AUTO_IN_CURR_LIM_ENA 0x04
|
||||
|
||||
/* Fuel Gauge constants */
|
||||
#define RESET_ACCU 0x02
|
||||
#define READ_REQ 0x01
|
||||
#define CC_DEEP_SLEEP_ENA 0x02
|
||||
#define CC_PWR_UP_ENA 0x01
|
||||
#define CC_SAMPLES_40 0x28
|
||||
#define RD_NCONV_ACCU_REQ 0x01
|
||||
#define CC_CALIB 0x08
|
||||
#define CC_INTAVGOFFSET_ENA 0x10
|
||||
#define CC_MUXOFFSET 0x80
|
||||
#define CC_INT_CAL_N_AVG_MASK 0x60
|
||||
#define CC_INT_CAL_SAMPLES_16 0x40
|
||||
#define CC_INT_CAL_SAMPLES_8 0x20
|
||||
#define CC_INT_CAL_SAMPLES_4 0x00
|
||||
|
||||
/* RTC constants */
|
||||
#define RTC_BUP_CH_ENA 0x10
|
||||
|
||||
/* BatCtrl Current Source Constants */
|
||||
#define BAT_CTRL_7U_ENA 0x01
|
||||
#define BAT_CTRL_20U_ENA 0x02
|
||||
#define BAT_CTRL_CMP_ENA 0x04
|
||||
#define FORCE_BAT_CTRL_CMP_HIGH 0x08
|
||||
#define BAT_CTRL_PULL_UP_ENA 0x10
|
||||
|
||||
/* Battery type */
|
||||
#define BATTERY_UNKNOWN 00
|
||||
|
||||
/**
|
||||
* struct res_to_temp - defines one point in a temp to res curve. To
|
||||
* be used in battery packs that combines the identification resistor with a
|
||||
* NTC resistor.
|
||||
* @temp: battery pack temperature in Celcius
|
||||
* @resist: NTC resistor net total resistance
|
||||
*/
|
||||
struct res_to_temp {
|
||||
int temp;
|
||||
int resist;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct batres_vs_temp - defines one point in a temp vs battery internal
|
||||
* resistance curve.
|
||||
* @temp: battery pack temperature in Celcius
|
||||
* @resist: battery internal reistance in mOhm
|
||||
*/
|
||||
struct batres_vs_temp {
|
||||
int temp;
|
||||
int resist;
|
||||
};
|
||||
|
||||
/* Forward declaration */
|
||||
struct ab8500_fg;
|
||||
|
||||
/**
|
||||
* struct ab8500_fg_parameters - Fuel gauge algorithm parameters, in seconds
|
||||
* if not specified
|
||||
* @recovery_sleep_timer: Time between measurements while recovering
|
||||
* @recovery_total_time: Total recovery time
|
||||
* @init_timer: Measurement interval during startup
|
||||
* @init_discard_time: Time we discard voltage measurement at startup
|
||||
* @init_total_time: Total init time during startup
|
||||
* @high_curr_time: Time current has to be high to go to recovery
|
||||
* @accu_charging: FG accumulation time while charging
|
||||
* @accu_high_curr: FG accumulation time in high current mode
|
||||
* @high_curr_threshold: High current threshold, in mA
|
||||
* @lowbat_threshold: Low battery threshold, in mV
|
||||
* @battok_falling_th_sel0 Threshold in mV for battOk signal sel0
|
||||
* Resolution in 50 mV step.
|
||||
* @battok_raising_th_sel1 Threshold in mV for battOk signal sel1
|
||||
* Resolution in 50 mV step.
|
||||
* @user_cap_limit Capacity reported from user must be within this
|
||||
* limit to be considered as sane, in percentage
|
||||
* points.
|
||||
* @maint_thres This is the threshold where we stop reporting
|
||||
* battery full while in maintenance, in per cent
|
||||
*/
|
||||
struct ab8500_fg_parameters {
|
||||
int recovery_sleep_timer;
|
||||
int recovery_total_time;
|
||||
int init_timer;
|
||||
int init_discard_time;
|
||||
int init_total_time;
|
||||
int high_curr_time;
|
||||
int accu_charging;
|
||||
int accu_high_curr;
|
||||
int high_curr_threshold;
|
||||
int lowbat_threshold;
|
||||
int battok_falling_th_sel0;
|
||||
int battok_raising_th_sel1;
|
||||
int user_cap_limit;
|
||||
int maint_thres;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ab8500_charger_maximization - struct used by the board config.
|
||||
* @use_maxi: Enable maximization for this battery type
|
||||
* @maxi_chg_curr: Maximum charger current allowed
|
||||
* @maxi_wait_cycles: cycles to wait before setting charger current
|
||||
* @charger_curr_step delta between two charger current settings (mA)
|
||||
*/
|
||||
struct ab8500_maxim_parameters {
|
||||
bool ena_maxi;
|
||||
int chg_curr;
|
||||
int wait_cycles;
|
||||
int charger_curr_step;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ab8500_bm_capacity_levels - ab8500 capacity level data
|
||||
* @critical: critical capacity level in percent
|
||||
* @low: low capacity level in percent
|
||||
* @normal: normal capacity level in percent
|
||||
* @high: high capacity level in percent
|
||||
* @full: full capacity level in percent
|
||||
*/
|
||||
struct ab8500_bm_capacity_levels {
|
||||
int critical;
|
||||
int low;
|
||||
int normal;
|
||||
int high;
|
||||
int full;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ab8500_bm_charger_parameters - Charger specific parameters
|
||||
* @usb_volt_max: maximum allowed USB charger voltage in mV
|
||||
* @usb_curr_max: maximum allowed USB charger current in mA
|
||||
* @ac_volt_max: maximum allowed AC charger voltage in mV
|
||||
* @ac_curr_max: maximum allowed AC charger current in mA
|
||||
*/
|
||||
struct ab8500_bm_charger_parameters {
|
||||
int usb_volt_max;
|
||||
int usb_curr_max;
|
||||
int ac_volt_max;
|
||||
int ac_curr_max;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ab8500_bm_data - ab8500 battery management data
|
||||
* @temp_under under this temp, charging is stopped
|
||||
* @temp_low between this temp and temp_under charging is reduced
|
||||
* @temp_high between this temp and temp_over charging is reduced
|
||||
* @temp_over over this temp, charging is stopped
|
||||
* @temp_interval_chg temperature measurement interval in s when charging
|
||||
* @temp_interval_nochg temperature measurement interval in s when not charging
|
||||
* @main_safety_tmr_h safety timer for main charger
|
||||
* @usb_safety_tmr_h safety timer for usb charger
|
||||
* @bkup_bat_v voltage which we charge the backup battery with
|
||||
* @bkup_bat_i current which we charge the backup battery with
|
||||
* @no_maintenance indicates that maintenance charging is disabled
|
||||
* @adc_therm placement of thermistor, batctrl or battemp adc
|
||||
* @chg_unknown_bat flag to enable charging of unknown batteries
|
||||
* @enable_overshoot flag to enable VBAT overshoot control
|
||||
* @fg_res resistance of FG resistor in 0.1mOhm
|
||||
* @n_btypes number of elements in array bat_type
|
||||
* @batt_id index of the identified battery in array bat_type
|
||||
* @interval_charging charge alg cycle period time when charging (sec)
|
||||
* @interval_not_charging charge alg cycle period time when not charging (sec)
|
||||
* @temp_hysteresis temperature hysteresis
|
||||
* @gnd_lift_resistance Battery ground to phone ground resistance (mOhm)
|
||||
* @maxi: maximization parameters
|
||||
* @cap_levels capacity in percent for the different capacity levels
|
||||
* @bat_type table of supported battery types
|
||||
* @chg_params charger parameters
|
||||
* @fg_params fuel gauge parameters
|
||||
*/
|
||||
struct ab8500_bm_data {
|
||||
int temp_under;
|
||||
int temp_low;
|
||||
int temp_high;
|
||||
int temp_over;
|
||||
int temp_interval_chg;
|
||||
int temp_interval_nochg;
|
||||
int main_safety_tmr_h;
|
||||
int usb_safety_tmr_h;
|
||||
int bkup_bat_v;
|
||||
int bkup_bat_i;
|
||||
bool no_maintenance;
|
||||
bool chg_unknown_bat;
|
||||
bool enable_overshoot;
|
||||
enum abx500_adc_therm adc_therm;
|
||||
int fg_res;
|
||||
int n_btypes;
|
||||
int batt_id;
|
||||
int interval_charging;
|
||||
int interval_not_charging;
|
||||
int temp_hysteresis;
|
||||
int gnd_lift_resistance;
|
||||
const struct ab8500_maxim_parameters *maxi;
|
||||
const struct ab8500_bm_capacity_levels *cap_levels;
|
||||
const struct ab8500_bm_charger_parameters *chg_params;
|
||||
const struct ab8500_fg_parameters *fg_params;
|
||||
};
|
||||
|
||||
struct ab8500_charger_platform_data {
|
||||
char **supplied_to;
|
||||
size_t num_supplicants;
|
||||
bool autopower_cfg;
|
||||
};
|
||||
|
||||
struct ab8500_btemp_platform_data {
|
||||
char **supplied_to;
|
||||
size_t num_supplicants;
|
||||
};
|
||||
|
||||
struct ab8500_fg_platform_data {
|
||||
char **supplied_to;
|
||||
size_t num_supplicants;
|
||||
};
|
||||
|
||||
struct ab8500_chargalg_platform_data {
|
||||
char **supplied_to;
|
||||
size_t num_supplicants;
|
||||
};
|
||||
struct ab8500_btemp;
|
||||
struct ab8500_gpadc;
|
||||
struct ab8500_fg;
|
||||
#ifdef CONFIG_AB8500_BM
|
||||
void ab8500_fg_reinit(void);
|
||||
void ab8500_charger_usb_state_changed(u8 bm_usb_state, u16 mA);
|
||||
struct ab8500_btemp *ab8500_btemp_get(void);
|
||||
int ab8500_btemp_get_batctrl_temp(struct ab8500_btemp *btemp);
|
||||
struct ab8500_fg *ab8500_fg_get(void);
|
||||
int ab8500_fg_inst_curr_blocking(struct ab8500_fg *dev);
|
||||
int ab8500_fg_inst_curr_start(struct ab8500_fg *di);
|
||||
int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res);
|
||||
int ab8500_fg_inst_curr_done(struct ab8500_fg *di);
|
||||
|
||||
#else
|
||||
int ab8500_fg_inst_curr_done(struct ab8500_fg *di)
|
||||
{
|
||||
}
|
||||
static void ab8500_fg_reinit(void)
|
||||
{
|
||||
}
|
||||
static void ab8500_charger_usb_state_changed(u8 bm_usb_state, u16 mA)
|
||||
{
|
||||
}
|
||||
static struct ab8500_btemp *ab8500_btemp_get(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static int ab8500_btemp_get_batctrl_temp(struct ab8500_btemp *btemp)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
struct ab8500_fg *ab8500_fg_get(void)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
static int ab8500_fg_inst_curr_blocking(struct ab8500_fg *dev)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int ab8500_fg_inst_curr_start(struct ab8500_fg *di)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static inline int ab8500_fg_inst_curr_finalize(struct ab8500_fg *di, int *res)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* _AB8500_BM_H */
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) ST-Ericsson SA 2012
|
||||
* Author: Johan Gardsmark <johan.gardsmark@stericsson.com> for ST-Ericsson.
|
||||
* License terms: GNU General Public License (GPL), version 2
|
||||
*/
|
||||
|
||||
#ifndef _UX500_CHARGALG_H
|
||||
#define _UX500_CHARGALG_H
|
||||
|
||||
#include <linux/power_supply.h>
|
||||
|
||||
#define psy_to_ux500_charger(x) container_of((x), \
|
||||
struct ux500_charger, psy)
|
||||
|
||||
/* Forward declaration */
|
||||
struct ux500_charger;
|
||||
|
||||
struct ux500_charger_ops {
|
||||
int (*enable) (struct ux500_charger *, int, int, int);
|
||||
int (*kick_wd) (struct ux500_charger *);
|
||||
int (*update_curr) (struct ux500_charger *, int);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ux500_charger - power supply ux500 charger sub class
|
||||
* @psy power supply base class
|
||||
* @ops ux500 charger operations
|
||||
* @max_out_volt maximum output charger voltage in mV
|
||||
* @max_out_curr maximum output charger current in mA
|
||||
*/
|
||||
struct ux500_charger {
|
||||
struct power_supply psy;
|
||||
struct ux500_charger_ops ops;
|
||||
int max_out_volt;
|
||||
int max_out_curr;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -27,6 +27,8 @@
|
|||
#define MAX17042_BATTERY_FULL (100)
|
||||
#define MAX17042_DEFAULT_SNS_RESISTOR (10000)
|
||||
|
||||
#define MAX17042_CHARACTERIZATION_DATA_SIZE 48
|
||||
|
||||
enum max17042_register {
|
||||
MAX17042_STATUS = 0x00,
|
||||
MAX17042_VALRT_Th = 0x01,
|
||||
|
@ -40,11 +42,11 @@ enum max17042_register {
|
|||
MAX17042_VCELL = 0x09,
|
||||
MAX17042_Current = 0x0A,
|
||||
MAX17042_AvgCurrent = 0x0B,
|
||||
MAX17042_Qresidual = 0x0C,
|
||||
|
||||
MAX17042_SOC = 0x0D,
|
||||
MAX17042_AvSOC = 0x0E,
|
||||
MAX17042_RemCap = 0x0F,
|
||||
MAX17402_FullCAP = 0x10,
|
||||
MAX17042_FullCAP = 0x10,
|
||||
MAX17042_TTE = 0x11,
|
||||
MAX17042_V_empty = 0x12,
|
||||
|
||||
|
@ -62,14 +64,14 @@ enum max17042_register {
|
|||
MAX17042_AvCap = 0x1F,
|
||||
MAX17042_ManName = 0x20,
|
||||
MAX17042_DevName = 0x21,
|
||||
MAX17042_DevChem = 0x22,
|
||||
|
||||
MAX17042_FullCAPNom = 0x23,
|
||||
MAX17042_TempNom = 0x24,
|
||||
MAX17042_TempCold = 0x25,
|
||||
MAX17042_TempLim = 0x25,
|
||||
MAX17042_TempHot = 0x26,
|
||||
MAX17042_AIN = 0x27,
|
||||
MAX17042_LearnCFG = 0x28,
|
||||
MAX17042_SHFTCFG = 0x29,
|
||||
MAX17042_FilterCFG = 0x29,
|
||||
MAX17042_RelaxCFG = 0x2A,
|
||||
MAX17042_MiscCFG = 0x2B,
|
||||
MAX17042_TGAIN = 0x2C,
|
||||
|
@ -77,22 +79,41 @@ enum max17042_register {
|
|||
MAX17042_CGAIN = 0x2E,
|
||||
MAX17042_COFF = 0x2F,
|
||||
|
||||
MAX17042_Q_empty = 0x33,
|
||||
MAX17042_MaskSOC = 0x32,
|
||||
MAX17042_SOC_empty = 0x33,
|
||||
MAX17042_T_empty = 0x34,
|
||||
|
||||
MAX17042_FullCAP0 = 0x35,
|
||||
MAX17042_LAvg_empty = 0x36,
|
||||
MAX17042_FCTC = 0x37,
|
||||
MAX17042_RCOMP0 = 0x38,
|
||||
MAX17042_TempCo = 0x39,
|
||||
MAX17042_Rx = 0x3A,
|
||||
MAX17042_T_empty0 = 0x3B,
|
||||
MAX17042_EmptyTempCo = 0x3A,
|
||||
MAX17042_K_empty0 = 0x3B,
|
||||
MAX17042_TaskPeriod = 0x3C,
|
||||
MAX17042_FSTAT = 0x3D,
|
||||
|
||||
MAX17042_SHDNTIMER = 0x3F,
|
||||
|
||||
MAX17042_VFRemCap = 0x4A,
|
||||
MAX17042_dQacc = 0x45,
|
||||
MAX17042_dPacc = 0x46,
|
||||
|
||||
MAX17042_VFSOC0 = 0x48,
|
||||
|
||||
MAX17042_QH = 0x4D,
|
||||
MAX17042_QL = 0x4E,
|
||||
|
||||
MAX17042_VFSOC0Enable = 0x60,
|
||||
MAX17042_MLOCKReg1 = 0x62,
|
||||
MAX17042_MLOCKReg2 = 0x63,
|
||||
|
||||
MAX17042_MODELChrTbl = 0x80,
|
||||
|
||||
MAX17042_OCV = 0xEE,
|
||||
|
||||
MAX17042_OCVInternal = 0xFB,
|
||||
|
||||
MAX17042_VFSOC = 0xFF,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -105,10 +126,64 @@ struct max17042_reg_data {
|
|||
u16 data;
|
||||
};
|
||||
|
||||
struct max17042_config_data {
|
||||
/* External current sense resistor value in milli-ohms */
|
||||
u32 cur_sense_val;
|
||||
|
||||
/* A/D measurement */
|
||||
u16 tgain; /* 0x2C */
|
||||
u16 toff; /* 0x2D */
|
||||
u16 cgain; /* 0x2E */
|
||||
u16 coff; /* 0x2F */
|
||||
|
||||
/* Alert / Status */
|
||||
u16 valrt_thresh; /* 0x01 */
|
||||
u16 talrt_thresh; /* 0x02 */
|
||||
u16 soc_alrt_thresh; /* 0x03 */
|
||||
u16 config; /* 0x01D */
|
||||
u16 shdntimer; /* 0x03F */
|
||||
|
||||
/* App data */
|
||||
u16 design_cap; /* 0x18 */
|
||||
u16 ichgt_term; /* 0x1E */
|
||||
|
||||
/* MG3 config */
|
||||
u16 at_rate; /* 0x04 */
|
||||
u16 learn_cfg; /* 0x28 */
|
||||
u16 filter_cfg; /* 0x29 */
|
||||
u16 relax_cfg; /* 0x2A */
|
||||
u16 misc_cfg; /* 0x2B */
|
||||
u16 masksoc; /* 0x32 */
|
||||
|
||||
/* MG3 save and restore */
|
||||
u16 fullcap; /* 0x10 */
|
||||
u16 fullcapnom; /* 0x23 */
|
||||
u16 socempty; /* 0x33 */
|
||||
u16 lavg_empty; /* 0x36 */
|
||||
u16 dqacc; /* 0x45 */
|
||||
u16 dpacc; /* 0x46 */
|
||||
|
||||
/* Cell technology from power_supply.h */
|
||||
u16 cell_technology;
|
||||
|
||||
/* Cell Data */
|
||||
u16 vempty; /* 0x12 */
|
||||
u16 temp_nom; /* 0x24 */
|
||||
u16 temp_lim; /* 0x25 */
|
||||
u16 fctc; /* 0x37 */
|
||||
u16 rcomp0; /* 0x38 */
|
||||
u16 tcompc0; /* 0x39 */
|
||||
u16 empty_tempco; /* 0x3A */
|
||||
u16 kempty0; /* 0x3B */
|
||||
u16 cell_char_tbl[MAX17042_CHARACTERIZATION_DATA_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct max17042_platform_data {
|
||||
struct max17042_reg_data *init_data;
|
||||
struct max17042_config_data *config_data;
|
||||
int num_init_data; /* Number of enties in init_data array */
|
||||
bool enable_current_sense;
|
||||
bool enable_por_init; /* Use POR init from Maxim appnote */
|
||||
|
||||
/*
|
||||
* R_sns in micro-ohms.
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* Summit Microelectronics SMB347 Battery Charger Driver
|
||||
*
|
||||
* Copyright (C) 2011, Intel Corporation
|
||||
*
|
||||
* Authors: Bruce E. Robertson <bruce.e.robertson@intel.com>
|
||||
* Mika Westerberg <mika.westerberg@linux.intel.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#ifndef SMB347_CHARGER_H
|
||||
#define SMB347_CHARGER_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/power_supply.h>
|
||||
|
||||
enum {
|
||||
/* use the default compensation method */
|
||||
SMB347_SOFT_TEMP_COMPENSATE_DEFAULT = -1,
|
||||
|
||||
SMB347_SOFT_TEMP_COMPENSATE_NONE,
|
||||
SMB347_SOFT_TEMP_COMPENSATE_CURRENT,
|
||||
SMB347_SOFT_TEMP_COMPENSATE_VOLTAGE,
|
||||
};
|
||||
|
||||
/* Use default factory programmed value for hard/soft temperature limit */
|
||||
#define SMB347_TEMP_USE_DEFAULT -273
|
||||
|
||||
/*
|
||||
* Charging enable can be controlled by software (via i2c) by
|
||||
* smb347-charger driver or by EN pin (active low/high).
|
||||
*/
|
||||
enum smb347_chg_enable {
|
||||
SMB347_CHG_ENABLE_SW,
|
||||
SMB347_CHG_ENABLE_PIN_ACTIVE_LOW,
|
||||
SMB347_CHG_ENABLE_PIN_ACTIVE_HIGH,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct smb347_charger_platform_data - platform data for SMB347 charger
|
||||
* @battery_info: Information about the battery
|
||||
* @max_charge_current: maximum current (in uA) the battery can be charged
|
||||
* @max_charge_voltage: maximum voltage (in uV) the battery can be charged
|
||||
* @pre_charge_current: current (in uA) to use in pre-charging phase
|
||||
* @termination_current: current (in uA) used to determine when the
|
||||
* charging cycle terminates
|
||||
* @pre_to_fast_voltage: voltage (in uV) treshold used for transitioning to
|
||||
* pre-charge to fast charge mode
|
||||
* @mains_current_limit: maximum input current drawn from AC/DC input (in uA)
|
||||
* @usb_hc_current_limit: maximum input high current (in uA) drawn from USB
|
||||
* input
|
||||
* @chip_temp_threshold: die temperature where device starts limiting charge
|
||||
* current [%100 - %130] (in degree C)
|
||||
* @soft_cold_temp_limit: soft cold temperature limit [%0 - %15] (in degree C),
|
||||
* granularity is 5 deg C.
|
||||
* @soft_hot_temp_limit: soft hot temperature limit [%40 - %55] (in degree C),
|
||||
* granularity is 5 deg C.
|
||||
* @hard_cold_temp_limit: hard cold temperature limit [%-5 - %10] (in degree C),
|
||||
* granularity is 5 deg C.
|
||||
* @hard_hot_temp_limit: hard hot temperature limit [%50 - %65] (in degree C),
|
||||
* granularity is 5 deg C.
|
||||
* @suspend_on_hard_temp_limit: suspend charging when hard limit is hit
|
||||
* @soft_temp_limit_compensation: compensation method when soft temperature
|
||||
* limit is hit
|
||||
* @charge_current_compensation: current (in uA) for charging compensation
|
||||
* current when temperature hits soft limits
|
||||
* @use_mains: AC/DC input can be used
|
||||
* @use_usb: USB input can be used
|
||||
* @use_usb_otg: USB OTG output can be used (not implemented yet)
|
||||
* @irq_gpio: GPIO number used for interrupts (%-1 if not used)
|
||||
* @enable_control: how charging enable/disable is controlled
|
||||
* (driver/pin controls)
|
||||
*
|
||||
* @use_main, @use_usb, and @use_usb_otg are means to enable/disable
|
||||
* hardware support for these. This is useful when we want to have for
|
||||
* example OTG charging controlled via OTG transceiver driver and not by
|
||||
* the SMB347 hardware.
|
||||
*
|
||||
* Hard and soft temperature limit values are given as described in the
|
||||
* device data sheet and assuming NTC beta value is %3750. Even if this is
|
||||
* not the case, these values should be used. They can be mapped to the
|
||||
* corresponding NTC beta values with the help of table %2 in the data
|
||||
* sheet. So for example if NTC beta is %3375 and we want to program hard
|
||||
* hot limit to be %53 deg C, @hard_hot_temp_limit should be set to %50.
|
||||
*
|
||||
* If zero value is given in any of the current and voltage values, the
|
||||
* factory programmed default will be used. For soft/hard temperature
|
||||
* values, pass in %SMB347_TEMP_USE_DEFAULT instead.
|
||||
*/
|
||||
struct smb347_charger_platform_data {
|
||||
struct power_supply_info battery_info;
|
||||
unsigned int max_charge_current;
|
||||
unsigned int max_charge_voltage;
|
||||
unsigned int pre_charge_current;
|
||||
unsigned int termination_current;
|
||||
unsigned int pre_to_fast_voltage;
|
||||
unsigned int mains_current_limit;
|
||||
unsigned int usb_hc_current_limit;
|
||||
unsigned int chip_temp_threshold;
|
||||
int soft_cold_temp_limit;
|
||||
int soft_hot_temp_limit;
|
||||
int hard_cold_temp_limit;
|
||||
int hard_hot_temp_limit;
|
||||
bool suspend_on_hard_temp_limit;
|
||||
unsigned int soft_temp_limit_compensation;
|
||||
unsigned int charge_current_compensation;
|
||||
bool use_mains;
|
||||
bool use_usb;
|
||||
bool use_usb_otg;
|
||||
int irq_gpio;
|
||||
enum smb347_chg_enable enable_control;
|
||||
};
|
||||
|
||||
#endif /* SMB347_CHARGER_H */
|
Loading…
Reference in New Issue