summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorSyed Rafiuddin <srafiuddin@nvidia.com>2012-09-28 17:07:27 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 12:39:33 -0700
commitd4c993ab343b3f30db91284e063edd9b5aca426b (patch)
tree95d68fb6d1c739e05aab170621741ec4e5b8633a /drivers
parent03329c2ffc42cd184da8b6d9b078cdbffe4202e7 (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.c78
-rw-r--r--drivers/power/max77665-charger.c161
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>");