diff options
author | Syed Rafiuddin <srafiuddin@nvidia.com> | 2012-09-28 17:07:27 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 12:39:33 -0700 |
commit | d4c993ab343b3f30db91284e063edd9b5aca426b (patch) | |
tree | 95d68fb6d1c739e05aab170621741ec4e5b8633a /drivers | |
parent | 03329c2ffc42cd184da8b6d9b078cdbffe4202e7 (diff) |
driver: max77665: fix multiple issues in charger driver
- fix probe issue.
- differentiate between E1236 and E1587
- use late_initcall
- init charger values correctly
Change-Id: Iab11261dab084bd707dcd9d24d236d3c1b438b0e
Signed-off-by: Syed Rafiuddin <srafiuddin@nvidia.com>
Reviewed-on: http://git-master/r/135174
(cherry picked from commit 7360d8753133ef15cd59264fd02613c42cacbd93)
Signed-off-by: Gaurav Batra <gbatra@nvidia.com>
Reviewed-on: http://git-master/r/146695
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>
Rebase-Id: Rb164179f576d0100652db9ef1c2c9ae8adb0dca7
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/extcon/extcon-max77665.c | 78 | ||||
-rw-r--r-- | drivers/power/max77665-charger.c | 161 |
2 files changed, 121 insertions, 118 deletions
diff --git a/drivers/extcon/extcon-max77665.c b/drivers/extcon/extcon-max77665.c index cfbe6352857e..193b66dbb3a9 100644 --- a/drivers/extcon/extcon-max77665.c +++ b/drivers/extcon/extcon-max77665.c @@ -25,6 +25,7 @@ #include <linux/kobject.h> #include <linux/extcon.h> #include <linux/mfd/max77665.h> +#include <linux/max77665-charger.h> #define DEV_NAME "max77665-muic" @@ -85,13 +86,9 @@ enum max77665_muic_charger_type { MAX77665_CHARGER_TYPE_1A, }; -struct max77665_muic_platform_data { - int irq_base; -}; - struct max77665_muic { struct device *dev; - struct max77665_muic_platform_data *muic_pdata; + struct max77665_muic_platform_data *pdata; int irq; struct work_struct irq_work; @@ -126,19 +123,6 @@ static int max77665_read_reg(struct max77665_muic *muic, return 0; } -static int max77665_bulk_read(struct max77665_muic *muic, - uint8_t reg, int count, uint8_t *buf) -{ - int ret; - struct device *dev = muic->dev; - - ret = max77665_read(dev->parent, MAX77665_I2C_SLAVE_MUIC, reg, buf); - if (ret < 0) - return ret; - - return 0; -} - static int max77665_update_reg(struct max77665_muic *muic, uint8_t reg, uint8_t value, uint8_t mask) { @@ -258,7 +242,7 @@ static int max77665_muic_handle_charger_type(struct max77665_muic *muic, enum max77665_muic_charger_type charger_type) { uint8_t adc; - int ret; + int ret = 0; ret = max77665_read_reg(muic, MAX77665_MUIC_REG_STATUS1, &adc); if (ret) { @@ -309,7 +293,8 @@ static void max77665_muic_irq_work(struct work_struct *work) mutex_lock(&muic->mutex); - ret = max77665_bulk_read(muic, MAX77665_MUIC_REG_STATUS1, + ret = max77665_bulk_read(muic->dev->parent, MAX77665_I2C_SLAVE_MUIC, + MAX77665_MUIC_REG_STATUS1, 2, status); if (ret) { dev_err(muic->dev, "failed to read muic register\n"); @@ -326,7 +311,6 @@ static void max77665_muic_irq_work(struct work_struct *work) chg_type = status[1] & STATUS2_CHGTYP_MASK; chg_type >>= STATUS2_CHGTYP_SHIFT; - max77665_muic_handle_adc(muic, adc); max77665_muic_handle_charger_type(muic, chg_type); mutex_unlock(&muic->mutex); @@ -351,7 +335,8 @@ static void max77665_muic_detect_dev(struct max77665_muic *muic) int ret; uint8_t status[2], adc, chg_type; - ret = max77665_bulk_read(muic, MAX77665_MUIC_REG_STATUS1, + ret = max77665_bulk_read(muic->dev->parent, MAX77665_I2C_SLAVE_MUIC, + MAX77665_MUIC_REG_STATUS1, 2, status); if (ret) { dev_err(muic->dev, "failed to read muic register\n"); @@ -367,21 +352,13 @@ static void max77665_muic_detect_dev(struct max77665_muic *muic) chg_type = status[1] & STATUS2_CHGTYP_MASK; chg_type >>= STATUS2_CHGTYP_SHIFT; - max77665_muic_handle_adc(muic, adc); max77665_muic_handle_charger_type(muic, chg_type); } static int __devinit max77665_muic_probe(struct platform_device *pdev) { + int ret = 0; struct max77665_muic *muic; - struct max77665_muic_platform_data *pdata; - int ret; - - pdata = dev_get_platdata(pdev->dev.parent); - if (!pdata) { - dev_err(&pdev->dev, "no platform data available\n"); - return -ENODEV; - } muic = devm_kzalloc(&pdev->dev, sizeof(struct max77665_muic), GFP_KERNEL); @@ -391,39 +368,52 @@ static int __devinit max77665_muic_probe(struct platform_device *pdev) } muic->dev = &pdev->dev; + muic->pdata = pdev->dev.platform_data; + if (!muic->pdata) { + dev_err(&pdev->dev, "no platform data available\n"); + return -ENODEV; + } - platform_set_drvdata(pdev, muic); + dev_set_drvdata(&pdev->dev, muic); mutex_init(&muic->mutex); INIT_WORK(&muic->irq_work, max77665_muic_irq_work); - ret = request_threaded_irq(pdata->irq_base, NULL, - max77665_muic_irq_handler, - 0, "muic_irq", - muic); - if (ret) { - dev_err(&pdev->dev, - "failed: irq request error :%d)\n", ret); - return ret; + if (muic->pdata->irq_base) { + ret = request_threaded_irq(muic->pdata->irq_base + + MAX77665_IRQ_MUIC, NULL, + max77665_muic_irq_handler, + 0, "muic_irq", + muic); + if (ret) { + dev_err(&pdev->dev, + "failed: irq request error :%d)\n", ret); + return ret; + } } - /* External connector */ - muic->edev = devm_kzalloc(&pdev->dev, sizeof(struct extcon_dev), + muic->edev = kzalloc(sizeof(struct extcon_dev), GFP_KERNEL); if (!muic->edev) { dev_err(&pdev->dev, "failed to allocate memory for extcon\n"); - return -ENOMEM; + ret = -ENOMEM; + goto error; } muic->edev->name = DEV_NAME; muic->edev->supported_cable = max77665_extcon_cable; ret = extcon_dev_register(muic->edev, NULL); if (ret) { dev_err(&pdev->dev, "failed to register extcon device\n"); - return ret; + goto error1; } /* Initial device detection */ max77665_muic_detect_dev(muic); return 0; +error1: + kfree(muic->edev); +error: + free_irq(muic->pdata->irq_base + MAX77665_IRQ_MUIC, muic); + return ret; } static int __devexit max77665_muic_remove(struct platform_device *pdev) diff --git a/drivers/power/max77665-charger.c b/drivers/power/max77665-charger.c index b20e21e22271..cda63b0e2a9c 100644 --- a/drivers/power/max77665-charger.c +++ b/drivers/power/max77665-charger.c @@ -26,6 +26,10 @@ #include <linux/power_supply.h> #include <linux/mfd/max77665.h> #include <linux/max77665-charger.h> +#include <linux/power/max17042_battery.h> + +#define MAX_TEMP 70 +#define MIN_TEMP -70 /* fast charge current in mA */ static const uint32_t chg_cc[] = { @@ -68,22 +72,11 @@ struct max77665_charger { struct extcon_dev *edev; }; -struct max77665_charger_cable { - const char *extcon_name; - const char *name; - struct notifier_block nb; - struct max77665_charger *charger; - struct extcon_specific_cable_nb *extcon_dev; -}; - - static enum power_supply_property max77665_ac_props[] = { - POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_ONLINE, }; static enum power_supply_property max77665_usb_props[] = { - POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_ONLINE, }; @@ -242,6 +235,7 @@ static int max77665_charger_enable(struct max77665_charger *charger, static int max77665_charger_init(struct max77665_charger *charger) { int ret = 0; + uint8_t read_val; ret = max77665_enable_write(charger, true); if (ret < 0) { @@ -249,6 +243,13 @@ static int max77665_charger_init(struct max77665_charger *charger) goto error; } + ret = max77665_update_reg(charger, MAX77665_CHG_CNFG_01, 0xa4); + if (ret < 0) { + dev_err(charger->dev, "Failed in writing to register 0x%x\n", + MAX77665_CHG_CNFG_01); + goto error; + } + if (charger->plat_data->fast_chg_cc) { ret = convert_to_reg(chg_cc, ARRAY_SIZE(chg_cc), charger->plat_data->fast_chg_cc); @@ -269,9 +270,10 @@ static int max77665_charger_init(struct max77665_charger *charger) if (ret < 0) goto error; - ret = max77665_update_reg(charger, MAX77665_CHG_CNFG_04, ret+1); + ret = max77665_update_reg(charger, + MAX77665_CHG_CNFG_04, ret+1); if (ret < 0) { - dev_err(charger->dev, "Failed in writing to register 0x%x\n", + dev_err(charger->dev, "Failed writing to reg:0x%x\n", MAX77665_CHG_CNFG_04); goto error; } @@ -283,9 +285,10 @@ static int max77665_charger_init(struct max77665_charger *charger) if (ret < 0) goto error; - ret = max77665_update_reg(charger, MAX77665_CHG_CNFG_09, ret+5); + ret = max77665_update_reg(charger, + MAX77665_CHG_CNFG_09, (ret-1)*5); if (ret < 0) { - dev_err(charger->dev, "Failed in writing to register 0x%x\n", + dev_err(charger->dev, "Failed writing to reg:0x%x\n", MAX77665_CHG_CNFG_09); goto error; } @@ -299,61 +302,43 @@ error: return ret; } -static int charger_extcon_notifier(struct notifier_block *self, - unsigned long event, void *ptr) +static int max77665_enable_charger(struct max77665_charger *charger) { - int ret; - struct max77665_charger_cable *cable = - container_of(self, struct max77665_charger_cable, nb); + int ret = 0; - cable->charger->ac_online = 0; - cable->charger->usb_online = 0; + if (extcon_get_cable_state(charger->edev, "USB")) { - if (extcon_get_cable_state(cable->charger->edev, "0")) { - ret = max77665_charger_enable(cable->charger, CHARGER); + ret = max77665_charger_enable(charger, CHARGER); if (ret < 0) goto error; - cable->charger->usb_online = 1; - power_supply_changed(&cable->charger->usb); + charger->usb_online = 1; + power_supply_changed(&charger->usb); } - if (extcon_get_cable_state(cable->charger->edev, "1")) { - ret = max77665_charger_enable(cable->charger, OTG); + if (extcon_get_cable_state(charger->edev, "USB-Host")) { + ret = max77665_charger_enable(charger, OTG); if (ret < 0) goto error; } - if (extcon_get_cable_state(cable->charger->edev, "2")) { - ret = max77665_charger_enable(cable->charger, CHARGER); + if (extcon_get_cable_state(charger->edev, "TA")) { + ret = max77665_charger_enable(charger, CHARGER); if (ret < 0) goto error; - cable->charger->ac_online = 1; - power_supply_changed(&cable->charger->ac); + charger->ac_online = 1; + power_supply_changed(&charger->ac); } - + return 0; error: - return NOTIFY_DONE; + return ret; } -static int max77665_extcon_init(struct max77665_charger *charger, - struct max77665_charger_cable *cable) +static int charger_extcon_notifier(struct notifier_block *self, + unsigned long event, void *ptr) { - int ret = 0; - - cable->nb.notifier_call = charger_extcon_notifier; - - ret = extcon_register_interest(cable->extcon_dev, - cable->extcon_name, cable->name, &cable->nb); - if (ret < 0) { - dev_err(charger->dev, "Cannot register for %s(cable: %s).\n", - cable->extcon_name, cable->name); - - ret = -EINVAL; - } - - return ret; + return NOTIFY_DONE; } static __devinit int max77665_battery_probe(struct platform_device *pdev) @@ -362,13 +347,6 @@ static __devinit int max77665_battery_probe(struct platform_device *pdev) uint8_t j; uint32_t read_val; struct max77665_charger *charger; - struct max77665_charger_plat_data *pdata; - - pdata = dev_get_platdata(pdev->dev.parent); - if (!pdata) { - dev_err(&pdev->dev, "no platform data available\n"); - return -ENODEV; - } charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); if (!charger) { @@ -376,10 +354,11 @@ static __devinit int max77665_battery_probe(struct platform_device *pdev) return -ENOMEM; } - dev_set_drvdata(&pdev->dev, charger); - charger->dev = &pdev->dev; + charger->plat_data = pdev->dev.platform_data; + dev_set_drvdata(&pdev->dev, charger); + /* check for battery presence */ ret = max77665_read_reg(charger, MAX77665_CHG_DTLS_01, &read_val); if (ret < 0) { @@ -391,9 +370,15 @@ static __devinit int max77665_battery_probe(struct platform_device *pdev) return -ENODEV; } - charger->plat_data->fast_chg_cc = pdata->fast_chg_cc; - charger->plat_data->term_volt = pdata->term_volt; - charger->plat_data->curr_lim = pdata->curr_lim; + /* differentiate between E1236 and E1587*/ + ret = maxim_get_temp(); + if (ret == 0xff) { + dev_err(&pdev->dev, "failed in reading temperaure\n"); + return -ENODEV; + } else if ((ret < MIN_TEMP) || (ret > MAX_TEMP)) { + dev_err(&pdev->dev, "E1236 detected exiting driver....\n"); + return -ENODEV; + } charger->ac.name = "ac"; charger->ac.type = POWER_SUPPLY_TYPE_MAINS; @@ -419,14 +404,18 @@ static __devinit int max77665_battery_probe(struct platform_device *pdev) goto pwr_sply_error; } - for (j = 0 ; j < charger->num_cables ; j++) { + for (j = 0 ; j < charger->plat_data->num_cables; j++) { struct max77665_charger_cable *cable = &charger->plat_data->cables[j]; - ret = max77665_extcon_init(charger, cable); - if (ret < 0) { - dev_err(&pdev->dev, "Cannot initialize extcon"); - goto chrg_error; + cable->nb.notifier_call = charger_extcon_notifier; + ret = extcon_register_interest(&cable->extcon_dev, + "max77665-muic", cable->name, &cable->nb); + + if (ret < 0) { + dev_err(charger->dev, "Cannot register for cable: %s\n", + cable->name); + ret = -EINVAL; } } @@ -436,6 +425,23 @@ static __devinit int max77665_battery_probe(struct platform_device *pdev) goto chrg_error; } + charger->edev = extcon_get_extcon_dev("max77665-muic"); + if (!charger->edev) + return -ENODEV; + + ret = max77665_enable_charger(charger); + if (ret < 0) { + dev_err(charger->dev, "failed to initialize charger\n"); + goto chrg_error; + } + + ret = max77665_read_reg(charger, MAX77665_CHG_DTLS_01, &read_val); + if (ret < 0) { + dev_err(&pdev->dev, "error in reading register 0x%x\n", + MAX77665_CHG_DTLS_01); + return -ENODEV; + } + return 0; chrg_error: @@ -456,21 +462,28 @@ static int __devexit max77665_battery_remove(struct platform_device *pdev) return 0; } -static const struct platform_device_id max77665_battery_id[] = { - { "max77665-battery", 0 }, -}; - static struct platform_driver max77665_battery_driver = { .driver = { - .name = "max77665-battery", + .name = "max77665-charger", .owner = THIS_MODULE, }, .probe = max77665_battery_probe, .remove = __devexit_p(max77665_battery_remove), - .id_table = max77665_battery_id, + }; -module_platform_driver(max77665_battery_driver); +static int __init max77665_battery_init(void) +{ + return platform_driver_register(&max77665_battery_driver); +} + +static void __exit max77665_battery_exit(void) +{ + platform_driver_unregister(&max77665_battery_driver); +} + +late_initcall(max77665_battery_init); +module_exit(max77665_battery_exit); MODULE_DESCRIPTION("MAXIM MAX77665 battery charging driver"); MODULE_AUTHOR("Syed Rafiuddin <srafiuddin@nvidia.com>"); |