1
0
Fork 0

max77818: fix power supply reg. issue causing kernal panic/add sep. max cur. adj

Extract powersupply config to static data structure.
Add support for setting max current separately for chgin/wcin.
pull/10/head
Steinar Bakkemo 2020-10-07 13:15:57 +02:00
parent 9a03c3cc7b
commit 0b65333af4
6 changed files with 705 additions and 587 deletions

View File

@ -50,15 +50,15 @@
static const struct regmap_config max77818_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_NONE,
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_NONE,
};
static const struct regmap_config max77818_regmap_config_fuelgauge = {
.reg_bits = 8,
.val_bits = 16,
.cache_type = REGCACHE_NONE,
.reg_bits = 8,
.val_bits = 16,
.cache_type = REGCACHE_NONE,
.val_format_endian = REGMAP_ENDIAN_NATIVE,
};
@ -68,51 +68,51 @@ static const struct regmap_config max77818_regmap_config_fuelgauge = {
******************************************************************************/
int max77818_read (struct regmap *regmap, u8 addr, u8 *val)
{
unsigned int buf = 0;
int rc = regmap_read(regmap, (unsigned int)addr, &buf);
unsigned int buf = 0;
int rc = regmap_read(regmap, (unsigned int)addr, &buf);
if (likely(!IS_ERR_VALUE(rc))) {
*val = (u8)buf;
}
return rc;
if (likely(!IS_ERR_VALUE(rc))) {
*val = (u8)buf;
}
return rc;
}
EXPORT_SYMBOL(max77818_read);
int max77818_write (struct regmap *regmap, u8 addr, u8 val)
{
unsigned int buf = (unsigned int)val;
return regmap_write(regmap, (unsigned int)addr, buf);
unsigned int buf = (unsigned int)val;
return regmap_write(regmap, (unsigned int)addr, buf);
}
EXPORT_SYMBOL(max77818_write);
int max77818_fg_read (struct regmap *regmap, u8 addr, u16 *val)
{
unsigned int buf = 0;
int rc = regmap_read(regmap, (unsigned int)addr, &buf);
unsigned int buf = 0;
int rc = regmap_read(regmap, (unsigned int)addr, &buf);
if (likely(!IS_ERR_VALUE(rc))) {
*val = buf;
}
return rc;
if (likely(!IS_ERR_VALUE(rc))) {
*val = buf;
}
return rc;
}
EXPORT_SYMBOL(max77818_fg_read);
int max77818_fg_write (struct regmap *regmap, u8 addr, u16 val)
{
unsigned int buf = (unsigned int)val;
return regmap_write(regmap, (unsigned int)addr, buf);
unsigned int buf = (unsigned int)val;
return regmap_write(regmap, (unsigned int)addr, buf);
}
EXPORT_SYMBOL(max77818_fg_write);
int max77818_bulk_read (struct regmap *regmap, u8 addr, u8 *dst, u16 len)
{
return regmap_bulk_read(regmap, (unsigned int)addr, dst, (size_t)len);
return regmap_bulk_read(regmap, (unsigned int)addr, dst, (size_t)len);
}
EXPORT_SYMBOL(max77818_bulk_read);
int max77818_bulk_write (struct regmap *regmap, u8 addr, const u8 *src, u16 len)
{
return regmap_bulk_write(regmap, (unsigned int)addr, src, (size_t)len);
return regmap_bulk_write(regmap, (unsigned int)addr, src, (size_t)len);
}
EXPORT_SYMBOL(max77818_bulk_write);
@ -120,20 +120,20 @@ EXPORT_SYMBOL(max77818_bulk_write);
* device
******************************************************************************/
static int max77818_add_devices (struct max77818_dev *me,
struct mfd_cell *cells, int n_devs)
struct mfd_cell *cells, int n_devs)
{
struct device *dev = me->dev;
int rc;
struct device *dev = me->dev;
int rc;
printk("[---- SBA ----] max77818_add_devices Enter:\n");
#if LINUX_VERSION_CODE < KERNEL_VERSION(3,6,0)
rc = mfd_add_devices(dev, -1, cells, n_devs, NULL, 0);
rc = mfd_add_devices(dev, -1, cells, n_devs, NULL, 0);
#else /* LINUX_VERSION_CODE ... */
rc = mfd_add_devices(dev, -1, cells, n_devs, NULL, 0, NULL);
rc = mfd_add_devices(dev, -1, cells, n_devs, NULL, 0, NULL);
#endif /* LINUX_VERSION_CODE ... */
return rc;
return rc;
}
/*******************************************************************************
@ -149,7 +149,7 @@ static int max77818_add_devices (struct max77818_dev *me,
/* Declare Interrupt */
static const struct regmap_irq max77818_intsrc_irqs[] = {
{ .reg_offset = 0, .mask = BIT_CHGR_INT, }, // CHGR_INT
{ .reg_offset = 0, .mask = BIT_FG_INT, }, // FG_INT
{ .reg_offset = 0, .mask = BIT_FG_INT, }, // FG_INT
{ .reg_offset = 0, .mask = BIT_SYS_INT, }, // SYS_INT
};
@ -166,7 +166,7 @@ static const struct regmap_irq max77818_sys_irqs[] = {
{ .reg_offset = 0, .mask = BIT_SYSUVLO_INT, }, // SYSUVLO_INT
{ .reg_offset = 0, .mask = BIT_SYSOVLO_INT, }, // SYSOVLO_INT
{ .reg_offset = 0, .mask = BIT_TSHDN_INT, }, // TSHDN_INT
{ .reg_offset = 0, .mask = BIT_TM_INT, }, // TM_INT
{ .reg_offset = 0, .mask = BIT_TM_INT, }, // TM_INT
};
static const struct regmap_irq_chip max77818_sys_irq_chip = {
@ -218,8 +218,8 @@ EXPORT_SYMBOL_GPL(max77818_map_chg_irq);
static int max77818_pmic_irq_int(struct max77818_dev *me)
{
struct device *dev = me->dev;
struct i2c_client *client = to_i2c_client(dev);
struct device *dev = me->dev;
struct i2c_client *client = to_i2c_client(dev);
int rc = 0;
printk("[---- SBA ----] max77818_pmic_irq_int Enter:\n");
@ -274,83 +274,91 @@ out:
static void *max77818_pmic_get_platdata (struct max77818_dev *pmic)
{
#ifdef CONFIG_OF
struct device *dev = pmic->dev;
struct device_node *np = dev->of_node;
struct i2c_client *client = to_i2c_client(dev);
struct max77818_pmic_platform_data *pdata;
int rc;
struct device *dev = pmic->dev;
struct device_node *np = dev->of_node;
struct i2c_client *client = to_i2c_client(dev);
struct max77818_pmic_platform_data *pdata;
int rc;
printk("[---- SBA ----] max77818_pmic_get_platdata Enter (CONFIG_OF):\n");
printk("[---- SBA ----] %s: Enter (CONFIG_OF):\n", __func__);
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (unlikely(!pdata)) {
pr_err("<%s> out of memory (%uB requested)\n", client->name,
(unsigned int) sizeof(*pdata));
pdata = ERR_PTR(-ENOMEM);
goto out;
}
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (unlikely(!pdata)) {
pr_err("<%s> out of memory (%uB requested)\n", client->name,
(unsigned int) sizeof(*pdata));
pdata = ERR_PTR(-ENOMEM);
goto out;
}
pmic->irq_gpio = of_get_named_gpio(np, "max77818,int-gpio", 0);
printk("[---- SBA ----] %s: Trying to read int-gpio property (if present)\n", __func__);
pmic->irq_gpio = of_get_named_gpio(np, "max77818,int-gpio", 0);
if (pmic->irq_gpio < 0) {
pdata->irq = irq_of_parse_and_map(np, 0);
} else {
unsigned gpio = (unsigned)pmic->irq_gpio;
if (pmic->irq_gpio < 0) {
printk("[---- SBA ----] %s: int-gpio not given or not configured, trying to parse standard irqparent/interrupts pattern\n", __func__);
pdata->irq = irq_of_parse_and_map(np, 0);
rc = gpio_request(gpio, DRIVER_NAME"-irq");
if (unlikely(IS_ERR_VALUE(rc))) {
pr_err("<%s> failed to request gpio %u [%d]\n", client->name, gpio,
rc);
pmic->irq_gpio = -1;
pdata = ERR_PTR(rc);
goto out;
}
printk("[---- SBA ----] %s: read interrupt gpio %d\n", __func__, pdata->irq);
} else {
printk("[---- SBA ----] %s: Read gpio num %d\n", __func__, (unsigned)pmic->irq_gpio);
unsigned gpio = (unsigned)pmic->irq_gpio;
gpio_direction_input(gpio);
pr_info("<%s> INTGPIO %u assigned\n", client->name, gpio);
printk("[---- SBA ----] %s: Trying to request given gpio\n", __func__);
rc = gpio_request(gpio, DRIVER_NAME"-irq");
if (unlikely(IS_ERR_VALUE(rc))) {
pr_err("<%s> failed to request gpio %u [%d]\n", client->name, gpio, rc);
pmic->irq_gpio = -1;
pdata = ERR_PTR(rc);
goto out;
}
/* override pdata irq */
pdata->irq = gpio_to_irq(gpio);
}
printk("[---- SBA ----] %s: Configuring given gpio as input\n", __func__);
gpio_direction_input(gpio);
pr_info("<%s> INTGPIO %u assigned\n", client->name, gpio);
pr_info("<%s> property:INTGPIO %d\n", client->name, pmic->irq_gpio);
pr_info("<%s> property:IRQ %d\n", client->name, pdata->irq);
/* override pdata irq */
pdata->irq = gpio_to_irq(gpio);
}
pr_info("<%s> property:INTGPIO %d\n", client->name, pmic->irq_gpio);
pr_info("<%s> property:IRQ %d\n", client->name, pdata->irq);
out:
return pdata;
return pdata;
#else /* CONFIG_OF */
printk("[---- SBA ----] max77818_pmic_get_platdata Enter (CONFIG_OF NOT DEFINED):\n");
return dev_get_platdata(pmic->dev) ?
dev_get_platdata(pmic->dev) : ERR_PTR(-EINVAL);
return dev_get_platdata(pmic->dev) ?
dev_get_platdata(pmic->dev) : ERR_PTR(-EINVAL);
#endif /* CONFIG_OF */
}
static struct mfd_cell max77818_devices[] = {
{ .name = MAX77818_REGULATOR_NAME, },
{ .name = MAX77818_REGULATOR_NAME, },
{ .name = MAX77818_CHARGER_NAME, },
{ .name = MAX77818_FUELGAUGE_NAME, },
};
static int max77818_pmic_setup (struct max77818_dev *me)
{
struct device *dev = me->dev;
struct i2c_client *client = to_i2c_client(dev);
struct max77818_pmic_platform_data *pdata;
int rc = 0;
u8 chip_id, chip_rev, val;
struct device *dev = me->dev;
struct i2c_client *client = to_i2c_client(dev);
struct max77818_pmic_platform_data *pdata;
int rc = 0;
u8 chip_id, chip_rev, val;
printk("[---- SBA ----] max77818_pmic_setup Enter:\n");
printk("[---- SBA ----] %s: Enter:\n", __func__);
me->pdata = max77818_pmic_get_platdata(me);
if (unlikely(IS_ERR(me->pdata))) {
rc = PTR_ERR(me->pdata);
me->pdata = NULL;
pr_err("<%s> platform data is missing [%d]\n", client->name, rc);
goto out;
}
printk("[---- SBA ----] %s: Getting platform data\n", __func__);
me->pdata = max77818_pmic_get_platdata(me);
if (unlikely(IS_ERR(me->pdata))) {
rc = PTR_ERR(me->pdata);
me->pdata = NULL;
pr_err("<%s> platform data is missing [%d]\n", client->name, rc);
goto out;
}
// IRQ init //
printk("[---- SBA ----] %s: Initiating IRQs\n", __func__);
pdata = me->pdata;
me->irq = pdata->irq;
rc = max77818_pmic_irq_int(me);
@ -361,28 +369,28 @@ static int max77818_pmic_setup (struct max77818_dev *me)
enable_irq(me->irq);
rc = max77818_add_devices(me, max77818_devices,
ARRAY_SIZE(max77818_devices));
if (unlikely(IS_ERR_VALUE(rc))) {
pr_err("<%s> failed to add sub-devices [%d]\n", client->name, rc);
goto err_add_devices;
}
rc = max77818_add_devices(me, max77818_devices,
ARRAY_SIZE(max77818_devices));
if (unlikely(IS_ERR_VALUE(rc))) {
pr_err("<%s> failed to add sub-devices [%d]\n", client->name, rc);
goto err_add_devices;
}
/* set device able to wake up system */
device_init_wakeup(dev, true);
if (likely(me->irq > 0)) {
enable_irq_wake((unsigned int)me->irq);
}
/* set device able to wake up system */
device_init_wakeup(dev, true);
if (likely(me->irq > 0)) {
enable_irq_wake((unsigned int)me->irq);
}
pr_info("<%s> driver core "DRIVER_VERSION" installed\n", client->name);
pr_info("<%s> driver core "DRIVER_VERSION" installed\n", client->name);
chip_id = 0;
chip_rev = 0;
chip_id = 0;
chip_rev = 0;
max77818_read(me->regmap_pmic, REG_PMICID, &chip_id );
max77818_read(me->regmap_pmic, REG_PMICREV, &chip_rev);
max77818_read(me->regmap_pmic, REG_PMICID, &chip_id );
max77818_read(me->regmap_pmic, REG_PMICREV, &chip_rev);
pr_info("<%s> CHIP ID %Xh REV %Xh\n", client->name, chip_id, chip_rev);
pr_info("<%s> CHIP ID %Xh REV %Xh\n", client->name, chip_id, chip_rev);
/* clear IRQ */
max77818_read(me->regmap_pmic, REG_INTSRC, &val);
@ -406,23 +414,23 @@ out:
static __always_inline void max77818_destroy (struct max77818_dev *me)
{
struct device *dev = me->dev;
struct device *dev = me->dev;
printk("[---- SBA ----] max77818_destroy Enter:\n");
mfd_remove_devices(me->dev);
if (likely(me->irq > 0)) {
regmap_del_irq_chip(me->irq, me->irqc_intsrc);
}
if (likely(me->irq > 0)) {
regmap_del_irq_chip(me->irq, me->irqc_intsrc);
}
if (likely(me->irq_gpio >= 0)) {
gpio_free((unsigned)me->irq_gpio);
}
if (likely(me->irq_gpio >= 0)) {
gpio_free((unsigned)me->irq_gpio);
}
if (likely(me->regmap_pmic)) {
regmap_exit(me->regmap_pmic);
}
if (likely(me->regmap_pmic)) {
regmap_exit(me->regmap_pmic);
}
if (likely(me->regmap_chg)) {
regmap_exit(me->regmap_chg);
@ -433,131 +441,144 @@ static __always_inline void max77818_destroy (struct max77818_dev *me)
}
#ifdef CONFIG_OF
if (likely(me->pdata)) {
devm_kfree(dev, me->pdata);
}
if (likely(me->pdata)) {
devm_kfree(dev, me->pdata);
}
#endif /* CONFIG_OF */
mutex_destroy(&me->lock);
devm_kfree(dev, me);
mutex_destroy(&me->lock);
devm_kfree(dev, me);
}
static int max77818_i2c_probe (struct i2c_client *client,
const struct i2c_device_id *id)
const struct i2c_device_id *id)
{
struct max77818_dev *me;
int rc;
struct max77818_dev *me;
int rc;
printk("[---- SBA ----] max77818_i2c_probe Enter:\n");
printk("[---- SBA ----] %s: Enter:\n", __func__);
pr_info("<%s> attached\n", client->name);
pr_info("<%s> attached\n", client->name);
me = devm_kzalloc(&client->dev, sizeof(*me), GFP_KERNEL);
if (unlikely(!me)) {
pr_err("<%s> out of memory (%uB requested)\n", client->name,
(unsigned int) sizeof(*me));
return -ENOMEM;
}
me = devm_kzalloc(&client->dev, sizeof(*me), GFP_KERNEL);
if (unlikely(!me)) {
pr_err("<%s> out of memory (%uB requested)\n", client->name,
(unsigned int) sizeof(*me));
return -ENOMEM;
}
i2c_set_clientdata(client, me);
i2c_set_clientdata(client, me);
mutex_init(&me->lock);
me->dev = &client->dev;
me->irq = -1;
me->irq_gpio = -1;
mutex_init(&me->lock);
me->dev = &client->dev;
me->irq = -1;
me->irq_gpio = -1;
printk("[---- SBA ----] %s: initiating i2c regmap:\n", __func__);
me->pmic = client;
me->regmap_pmic = devm_regmap_init_i2c(client, &max77818_regmap_config);
if (unlikely(IS_ERR(me->regmap_pmic))) {
rc = PTR_ERR(me->regmap_pmic);
me->regmap_pmic = NULL;
pr_err("<%s> failed to initialize i2c regmap pmic [%d]\n", client->name,
rc);
goto abort;
}
if (unlikely(IS_ERR(me->regmap_pmic))) {
rc = PTR_ERR(me->regmap_pmic);
me->regmap_pmic = NULL;
pr_err("<%s> failed to initialize i2c regmap pmic [%d]\n", client->name,
rc);
goto abort;
}
printk("[---- SBA ----] %s: Creating dummy temporary 'placeholder' for the charger in dev structure:\n", __func__);
me->chg = i2c_new_dummy(client->adapter, I2C_ADDR_CHARGER);
if (!me->chg) {
rc = -ENOMEM;
goto abort;
}
}
i2c_set_clientdata(me->chg, me);
printk("[---- SBA ----] %s: Initiating i2c regmap for dummy temporary 'placeholder' for the charger in dev structure:\n", __func__);
me->regmap_chg = devm_regmap_init_i2c(me->chg, &max77818_regmap_config);
if (unlikely(IS_ERR(me->regmap_chg))) {
rc = PTR_ERR(me->regmap_chg);
me->regmap_chg = NULL;
pr_err("<%s> failed to initialize i2c regmap chg [%d]\n", client->name,
rc);
goto abort;
}
if (unlikely(IS_ERR(me->regmap_chg))) {
rc = PTR_ERR(me->regmap_chg);
me->regmap_chg = NULL;
pr_err("<%s> failed to initialize i2c regmap chg [%d]\n", client->name,
rc);
goto abort;
}
printk("[---- SBA ----] %s: Creating dummy temporary 'placeholder' for the fuelgauge in dev structure:\n", __func__);
me->fuel= i2c_new_dummy(client->adapter, I2C_ADDR_FUEL_GAUGE);
if (!me->fuel) {
rc = -ENOMEM;
goto abort;
}
}
i2c_set_clientdata(me->fuel, me);
me->regmap_fuel= devm_regmap_init_i2c(me->fuel, &max77818_regmap_config_fuelgauge);
if (unlikely(IS_ERR(me->regmap_fuel))) {
rc = PTR_ERR(me->regmap_fuel);
me->regmap_fuel = NULL;
pr_err("<%s> failed to initialize i2c regmap fuelgauge [%d]\n", client->name,
rc);
goto abort;
}
printk("[---- SBA ----] %s: Initiating i2c regmap for dummy temporary 'placeholder' for the fulegauge in dev structure:\n", __func__);
me->regmap_fuel= devm_regmap_init_i2c(me->fuel, &max77818_regmap_config_fuelgauge);
if (unlikely(IS_ERR(me->regmap_fuel))) {
rc = PTR_ERR(me->regmap_fuel);
me->regmap_fuel = NULL;
pr_err("<%s> failed to initialize i2c regmap fuelgauge [%d]\n", client->name,
rc);
goto abort;
}
printk("[---- SBA ----] %s: Setting up IRQ regmaps and adding sub-devices\n", __func__);
rc = max77818_pmic_setup(me);
if (rc != 0) {
pr_err("<%s> failed to set up interrupt and add sub-device [%d]\n", client->name,
rc);
goto abort;
}
rc);
goto abort;
}
return 0;
return 0;
abort:
i2c_set_clientdata(client, NULL);
max77818_destroy(me);
return rc;
i2c_set_clientdata(client, NULL);
max77818_destroy(me);
return rc;
}
static int max77818_i2c_remove (struct i2c_client *client)
{
struct max77818_dev *me = i2c_get_clientdata(client);
struct max77818_dev *me = i2c_get_clientdata(client);
printk("[---- SBA ----] max77818_i2c_remove Enter:\n");
printk("[---- SBA ----] max77818_i2c_remove Enter:\n");
i2c_set_clientdata(client, NULL);
max77818_destroy(me);
i2c_set_clientdata(client, NULL);
max77818_destroy(me);
return 0;
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int max77818_suspend (struct device *dev)
{
struct max77818_dev *me = dev_get_drvdata(dev);
struct i2c_client *client = to_i2c_client(dev);
struct max77818_dev *me = dev_get_drvdata(dev);
struct i2c_client *client = to_i2c_client(dev);
__lock(me);
__lock(me);
pr_info("<%s> suspending\n", client->name);
pr_info("<%s> suspending\n", client->name);
__unlock(me);
return 0;
__unlock(me);
return 0;
}
static int max77818_resume (struct device *dev)
{
struct max77818_dev *me = dev_get_drvdata(dev);
struct i2c_client *client = to_i2c_client(dev);
struct max77818_dev *me = dev_get_drvdata(dev);
struct i2c_client *client = to_i2c_client(dev);
__lock(me);
__lock(me);
pr_info("<%s> resuming\n", client->name);
pr_info("<%s> resuming\n", client->name);
__unlock(me);
return 0;
__unlock(me);
return 0;
}
#endif /* CONFIG_PM_SLEEP */
@ -565,28 +586,28 @@ static SIMPLE_DEV_PM_OPS(max77818_pm, max77818_suspend, max77818_resume);
#ifdef CONFIG_OF
static struct of_device_id max77818_of_id[] = {
{ .compatible = "maxim,"MAX77818_NAME },
{ },
{ .compatible = "maxim,"MAX77818_NAME },
{ },
};
MODULE_DEVICE_TABLE(of, max77818_of_id);
#endif /* CONFIG_OF */
static const struct i2c_device_id max77818_i2c_id[] = {
{ MAX77818_NAME, 0 },
{ },
{ MAX77818_NAME, 0 },
{ },
};
MODULE_DEVICE_TABLE(i2c, max77818_i2c_id);
static struct i2c_driver max77818_i2c_driver = {
.driver.name = DRIVER_NAME,
.driver.owner = THIS_MODULE,
.driver.pm = &max77818_pm,
.driver.name = DRIVER_NAME,
.driver.owner = THIS_MODULE,
.driver.pm = &max77818_pm,
#ifdef CONFIG_OF
.driver.of_match_table = max77818_of_id,
.driver.of_match_table = max77818_of_id,
#endif /* CONFIG_OF */
.id_table = max77818_i2c_id,
.probe = max77818_i2c_probe,
.remove = max77818_i2c_remove,
.id_table = max77818_i2c_id,
.probe = max77818_i2c_probe,
.remove = max77818_i2c_remove,
};
static __init int max77818_init (void)
@ -595,7 +616,7 @@ static __init int max77818_init (void)
printk("[---- SBA ----] max77818_init Enter:\n");
rc = i2c_add_driver(&max77818_i2c_driver);
rc = i2c_add_driver(&max77818_i2c_driver);
if (rc != 0)
pr_err("Failed to register I2C driver: %d\n", rc);
@ -608,7 +629,7 @@ static __exit void max77818_exit (void)
printk("[---- SBA ----] max77818_exit Enter:\n");
i2c_del_driver(&max77818_i2c_driver);
i2c_del_driver(&max77818_i2c_driver);
}
module_exit(max77818_exit);

File diff suppressed because it is too large Load Diff

View File

@ -71,17 +71,17 @@ static volatile bool probeDone = false;
struct mutex probeDoneLock;
struct max77818_chip {
struct device *dev;
struct max77818_dev *max77818;
struct device *dev;
struct max77818_dev *max77818;
struct regmap *regmap;
int fg_irq;
struct delayed_work work;
struct power_supply *battery;
struct power_supply *battery;
/* alert */
int alert_threshold;
/* State Of Connect */
int ac_online;
int usb_online;
@ -104,10 +104,10 @@ struct max77818_chip {
};
static int max77818_fg_get_property(struct power_supply *psy,
enum power_supply_property psp,
union power_supply_propval *val)
enum power_supply_property psp,
union power_supply_propval *val)
{
struct max77818_chip *chip = (struct max77818_chip*) psy->drv_data;
struct max77818_chip *chip = (struct max77818_chip*) psy->drv_data;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
@ -201,8 +201,8 @@ static bool max77818_fg_check_status(struct max77818_chip *max77818_fg)
if (data & BIT_dSOCi) {
max77818_fg_get_vcell(max77818_fg);
max77818_fg_get_soc(max77818_fg);
power_supply_changed(max77818_fg->battery);
pr_info("%s: 1% soc changed, SOC=%d, VCELL=%d\n",
power_supply_changed(max77818_fg->battery);
pr_info("%s: 1% soc changed, SOC=%d, VCELL=%d\n",
__func__, max77818_fg->soc, max77818_fg->vcell);
}
@ -218,24 +218,24 @@ static bool max77818_fg_check_status(struct max77818_chip *max77818_fg)
/* callback to be called during power supply registration to check if the probe routine has finished */
static int max77818_fg_property_is_writeable(struct power_supply *psy,
enum power_supply_property psp)
enum power_supply_property psp)
{
printk("[---- SBA ----] max77818-battery.property_is_writable called !\n");
printk("[---- SBA ----] max77818-battery.property_is_writable called !\n");
int probeIsDone = __sync_get(probeDone, probeDoneLock);
printk("[---- SBA ----] probeDone: %s", (probeIsDone ? "TRUE" : "FALSE"));
int probeIsDone = __sync_get(probeDone, probeDoneLock);
printk("[---- SBA ----] probeDone: %s", (probeIsDone ? "TRUE" : "FALSE"));
}
/* callback to be called when external power has changed */
static void max77818_fg_external_power_changed(struct power_supply *psy)
{
printk("[---- SBA ----] max77818-battery.external_power_changed called !\n");
printk("[---- SBA ----] max77818-battery.external_power_changed called !\n");
}
/* callbask to be called to set charged state */
static void max77818_fg_set_charged(struct power_supply *psy)
{
printk("[---- SBA ----] max77818-battery.set_charged called !\n");
printk("[---- SBA ----] max77818-battery.set_charged called !\n");
}
//static void max77818_fg_work(struct work_struct *work)
@ -346,7 +346,7 @@ static int max77818_fg_parse_dt(struct max77818_chip *fuelgauge, struct device_n
struct device_node *np = of_find_node_by_name(NULL, "fuelgauge");
struct max77818_fg_platform_data *pdata = fuelgauge->pdata;
*of_node = np;
*of_node = np;
int ret;
/* reset, irq gpio info */
@ -371,14 +371,14 @@ static int max77818_fg_probe(struct platform_device *pdev)
struct max77818_fg_platform_data *pdata = dev_get_platdata(max77818->dev);
struct max77818_chip *chip;
struct power_supply_desc psy_chg_desc;
struct power_supply_config psy_chg_config;
struct power_supply_desc psy_chg_desc;
struct power_supply_config psy_chg_config;
uint16_t version;
int ret = 0;
u8 val;
printk("[---- SBA ----] %s Enter:\n", __func__);
printk("[---- SBA ----] %s Enter:\n", __func__);
pr_info("%s: MAX77818 Fuelgauge Driver Loading\n", __func__);
@ -391,7 +391,7 @@ static int max77818_fg_probe(struct platform_device *pdev)
chip->regmap = max77818->regmap_fuel;
#if defined(CONFIG_OF)
ret = max77818_fg_parse_dt(chip, &psy_chg_config.of_node);
ret = max77818_fg_parse_dt(chip, &psy_chg_config.of_node);
if (ret < 0) {
pr_err("%s not found charger dt! ret[%d]\n",
__func__, ret);
@ -405,25 +405,25 @@ static int max77818_fg_probe(struct platform_device *pdev)
goto error;
}
platform_set_drvdata(pdev, chip);
platform_set_drvdata(pdev, chip);
psy_chg_config.drv_data = chip;
/* psy_chg_config.supplied_to ?? */
/* psy_chg_config.num_supplicants */
psy_chg_config.drv_data = chip;
/* psy_chg_config.supplied_to ?? */
/* psy_chg_config.num_supplicants */
psy_chg_desc.name = "max77818-battery";
psy_chg_desc.type = POWER_SUPPLY_TYPE_BATTERY;
psy_chg_desc.properties = max77818_fg_battery_props;
psy_chg_desc.num_properties = ARRAY_SIZE(max77818_fg_battery_props);
psy_chg_desc.get_property = max77818_fg_get_property;
/* psy_chg_desc.set_property = ?;*/
psy_chg_desc.property_is_writeable = max77818_fg_property_is_writeable;
psy_chg_desc.external_power_changed = max77818_fg_external_power_changed;
psy_chg_desc.set_charged = max77818_fg_set_charged;
psy_chg_desc.no_thermal = true;
psy_chg_desc.use_for_apm = false;
psy_chg_desc.name = "max77818-battery";
psy_chg_desc.type = POWER_SUPPLY_TYPE_BATTERY;
psy_chg_desc.properties = max77818_fg_battery_props;
psy_chg_desc.num_properties = ARRAY_SIZE(max77818_fg_battery_props);
psy_chg_desc.get_property = max77818_fg_get_property;
/* psy_chg_desc.set_property = ?;*/
psy_chg_desc.property_is_writeable = max77818_fg_property_is_writeable;
psy_chg_desc.external_power_changed = max77818_fg_external_power_changed;
psy_chg_desc.set_charged = max77818_fg_set_charged;
psy_chg_desc.no_thermal = true;
psy_chg_desc.use_for_apm = false;
chip->battery = power_supply_register(&pdev->dev, &psy_chg_desc, &psy_chg_config);
chip->battery = power_supply_register(&pdev->dev, &psy_chg_desc, &psy_chg_config);
if (ret) {
dev_err(&pdev->dev, "failed: power supply register\n");
goto error;
@ -435,7 +435,7 @@ static int max77818_fg_probe(struct platform_device *pdev)
if (chip->fg_irq > 0) {
// INIT_DELAYED_WORK(&chip->work, max77818_fg_work);
ret = request_threaded_irq(chip->fg_irq, NULL, max77818_fg_irq_thread,
IRQF_TRIGGER_FALLING, "fuelgauge-irq", chip);
IRQF_TRIGGER_FALLING, "fuelgauge-irq", chip);
if (ret) {
pr_err("%s: Failed to Reqeust IRQ\n", __func__);
goto error1;
@ -457,7 +457,7 @@ error2:
if (chip->fg_irq)
free_irq(chip->fg_irq, chip);
error1:
power_supply_unregister(chip->battery);
power_supply_unregister(chip->battery);
error:
kfree(chip);
return ret;
@ -467,7 +467,7 @@ static int max77818_fg_remove(struct platform_device *pdev)
{
struct max77818_chip *chip = platform_get_drvdata(pdev);
power_supply_unregister(chip->battery);
power_supply_unregister(chip->battery);
cancel_delayed_work(&chip->work);
kfree(chip);
return 0;

View File

@ -350,7 +350,7 @@ const static struct regulator_desc max77818_safeout_desc[] =
};
#ifdef CONFIG_OF
static struct max77818_regulator_platform_data
static struct max77818_regulator_platform_data
*max77818_regulator_parse_dt(struct device *dev)
{
struct device_node *np = of_find_node_by_name(NULL, "regulator");
@ -375,6 +375,7 @@ static struct max77818_regulator_platform_data
pdata->num_regulators = of_get_child_count(np);
}
printk("[---- SBA ----] %s: Allocating array of %d rdata structures\n", __func__, pdata->num_regulators);
rdata = devm_kzalloc(dev, sizeof(*rdata) *
pdata->num_regulators, GFP_KERNEL);
@ -412,12 +413,12 @@ out:
static int max77818_regulator_probe(struct platform_device *pdev)
{
struct max77818_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max77818_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max77818_regulator_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct regulator_dev **rdev;
struct max77818_data *max77818;
struct regmap *regmap;
#if LINUX_VERSION_CODE > KERNEL_VERSION(3,6,0)
#if LINUX_VERSION_CODE > KERNEL_VERSION(3,6,0)
struct regulator_config config;
#endif
int i, ret, size;

View File

@ -28,7 +28,9 @@ struct max77818_charger_platform_data {
int topoff_timer;
int restart_threshold;
int termination_voltage;
int input_current_limit;
int vsys_min;
int input_current_limit_chgin;
int input_current_limit_wcin;
};
#endif /* !__MAX77818_CHARGER_H__ */

View File

@ -69,9 +69,9 @@ enum {
MAX77818_CHG_IRQ_CHG_I,
MAX77818_CHG_IRQ_WCIN_I,
MAX77818_CHG_IRQ_CHGIN_I,
MAX77818_CHG_IRQ_AICL_I,
MAX77818_CHG_IRQ_AICL_I,
MAX77818_NUM_OF_INTS,
MAX77818_NUM_OF_INTS,
};
enum{
@ -86,7 +86,7 @@ enum{
CHG_IRQ_CHG_I,
CHG_IRQ_WCIN_I,
CHG_IRQ_CHGIN_I,
CHG_IRQ_AICL_I,
CHG_IRQ_AICL_I,
FG_IRQ_ALERT = 0,
};
@ -99,59 +99,59 @@ enum{
#undef __CONST_FFS
#define __CONST_FFS(_x) \
((_x) & 0x0F ? ((_x) & 0x03 ? ((_x) & 0x01 ? 0 : 1) :\
((_x) & 0x04 ? 2 : 3)) :\
((_x) & 0x30 ? ((_x) & 0x10 ? 4 : 5) :\
((_x) & 0x40 ? 6 : 7)))
((_x) & 0x0F ? ((_x) & 0x03 ? ((_x) & 0x01 ? 0 : 1) :\
((_x) & 0x04 ? 2 : 3)) :\
((_x) & 0x30 ? ((_x) & 0x10 ? 4 : 5) :\
((_x) & 0x40 ? 6 : 7)))
#undef FFS
#define FFS(_x) \
((_x) ? __CONST_FFS(_x) : 0)
((_x) ? __CONST_FFS(_x) : 0)
#undef BIT_RSVD
#define BIT_RSVD 0
#undef BITS
#define BITS(_end, _start) \
((BIT(_end) - BIT(_start)) + BIT(_end))
((BIT(_end) - BIT(_start)) + BIT(_end))
#undef __BITS_GET
#define __BITS_GET(_word, _mask, _shift) \
(((_word) & (_mask)) >> (_shift))
(((_word) & (_mask)) >> (_shift))
#undef BITS_GET
#define BITS_GET(_word, _bit) \
__BITS_GET(_word, _bit, FFS(_bit))
__BITS_GET(_word, _bit, FFS(_bit))
#undef __BITS_SET
#define __BITS_SET(_word, _mask, _shift, _val) \
(((_word) & ~(_mask)) | (((_val) << (_shift)) & (_mask)))
(((_word) & ~(_mask)) | (((_val) << (_shift)) & (_mask)))
#undef BITS_SET
#define BITS_SET(_word, _bit, _val) \
__BITS_SET(_word, _bit, FFS(_bit), _val)
__BITS_SET(_word, _bit, FFS(_bit), _val)
#undef BITS_MATCH
#define BITS_MATCH(_word, _bit) \
(((_word) & (_bit)) == (_bit))
(((_word) & (_bit)) == (_bit))
/*******************************************************************************
* Sub Modules Support
******************************************************************************/
enum {
MAX77818_DEV_REGULATOR = 0,
MAX77818_DEV_CHARGER,
MAX77818_DEV_FUELGAUGE,
/***/
MAX77818_DEV_NUM_OF_DEVICES,
MAX77818_DEV_REGULATOR = 0,
MAX77818_DEV_CHARGER,
MAX77818_DEV_FUELGAUGE,
/***/
MAX77818_DEV_NUM_OF_DEVICES,
};
struct max77818_dev {
void *pdata;
struct mutex lock;
struct device *dev;
int irq;
int irq_gpio;
@ -162,7 +162,7 @@ struct max77818_dev {
struct i2c_client *pmic; /* 0xCC , CLOGIC/SAFELDOS */
struct i2c_client *chg; /* 0xD2, CHARGER */
struct i2c_client *fuel; /* 0x6C, FUEL GAUGE */
struct regmap *regmap_pmic; /* CLOGIC/SAFELDOS */
struct regmap *regmap_chg; /* CHARGER */
struct regmap *regmap_fuel; /* FUEL GAUGE */
@ -173,7 +173,7 @@ struct max77818_dev {
******************************************************************************/
struct max77818_pmic_platform_data {
int irq; /* system interrupt number for PMIC */
int irq; /* system interrupt number for PMIC */
};
@ -202,27 +202,27 @@ int max77818_map_irq(struct max77818_dev *max77818, int irq);
#undef log_fmt
#define log_fmt(format) \
DRIVER_NAME ": " format
DRIVER_NAME ": " format
#undef log_err
#define log_err(format, ...) \
printk(KERN_ERR log_fmt(format), ##__VA_ARGS__)
printk(KERN_ERR log_fmt(format), ##__VA_ARGS__)
#undef log_warn
#define log_warn(format, ...) \
printk(KERN_WARNING log_fmt(format), ##__VA_ARGS__)
printk(KERN_WARNING log_fmt(format), ##__VA_ARGS__)
#undef log_info
#define log_info(format, ...) \
if (likely(log_level >= 0)) {\
printk(KERN_INFO log_fmt(format), ##__VA_ARGS__);\
}
if (likely(log_level >= 0)) {\
printk(KERN_INFO log_fmt(format), ##__VA_ARGS__);\
}
#undef log_dbg
#define log_dbg(format, ...) \
if (likely(log_level >= 1)) {\
printk(KERN_DEFAULT log_fmt(format), ##__VA_ARGS__);\
}
if (likely(log_level >= 1)) {\
printk(KERN_DEFAULT log_fmt(format), ##__VA_ARGS__);\
}
#undef log_vdbg
#define log_vdbg(format, ...) \
if (likely(log_level >= 2)) {\
printk(KERN_DEFAULT log_fmt(format), ##__VA_ARGS__);\
}
if (likely(log_level >= 2)) {\
printk(KERN_DEFAULT log_fmt(format), ##__VA_ARGS__);\
}
#endif /* !__MAX77818_MFD_H__ */