aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRupesh Kumar <rupesh.kumar@stericsson.com>2012-06-19 00:51:24 -0400
committerLee Jones <lee.jones@linaro.org>2013-03-06 23:35:39 -0500
commit789ca7b46877f29b2aaa94401319c50be35b184f (patch)
tree7e4ac3006175ad7c5c2a307a99b086bf0e60a630
parent4dcdf57773fd45b483fc7613b9e51b89a57d655c (diff)
pm2301-charger: Support for over voltage protection on the ab9540
Added support for main charger over voltage protection. Signed-off-by: Rupesh Kumar <rupesh.kumar@stericsson.com> Signed-off-by: Lee Jones <lee.jones@linaro.org> Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com> Tested-by: Michel JAOUEN <michel.jaouen@stericsson.com>
-rw-r--r--drivers/power/pm2301_charger.c50
-rw-r--r--drivers/power/pm2301_charger.h1
2 files changed, 37 insertions, 14 deletions
diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c
index b2f2d4188da9..b560fa5ac4e7 100644
--- a/drivers/power/pm2301_charger.c
+++ b/drivers/power/pm2301_charger.c
@@ -227,21 +227,14 @@ int pm2xxx_charger_die_therm_mngt(struct pm2xxx_charger *pm2, int val)
227 227
228static int pm2xxx_charger_ovv_mngt(struct pm2xxx_charger *pm2, int val) 228static int pm2xxx_charger_ovv_mngt(struct pm2xxx_charger *pm2, int val)
229{ 229{
230 int ret = 0; 230 dev_err(pm2->dev, "Overvoltage detected\n");
231 pm2->flags.ovv = true;
232 power_supply_changed(&pm2->ac_chg.psy);
231 233
232 pm2->failure_input_ovv++; 234 /* Schedule a new HW failure check */
233 if (pm2->failure_input_ovv < 4) { 235 queue_delayed_work(pm2->charger_wq, &pm2->check_hw_failure_work, 0);
234 ret = pm2xxx_charging_enable_mngt(pm2);
235 goto out;
236 } else {
237 pm2->failure_input_ovv = 0;
238 dev_err(pm2->dev, "Overvoltage detected\n");
239 pm2->flags.ovv = true;
240 power_supply_changed(&pm2->ac_chg.psy);
241 }
242 236
243out: 237 return 0;
244 return ret;
245} 238}
246 239
247static int pm2xxx_charger_wd_exp_mngt(struct pm2xxx_charger *pm2, int val) 240static int pm2xxx_charger_wd_exp_mngt(struct pm2xxx_charger *pm2, int val)
@@ -630,6 +623,8 @@ static int pm2xxx_charger_ac_get_property(struct power_supply *psy,
630 val->intval = POWER_SUPPLY_HEALTH_DEAD; 623 val->intval = POWER_SUPPLY_HEALTH_DEAD;
631 else if (pm2->flags.main_thermal_prot) 624 else if (pm2->flags.main_thermal_prot)
632 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; 625 val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
626 else if (pm2->flags.ovv)
627 val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
633 else 628 else
634 val->intval = POWER_SUPPLY_HEALTH_GOOD; 629 val->intval = POWER_SUPPLY_HEALTH_GOOD;
635 break; 630 break;
@@ -860,6 +855,30 @@ static void pm2xxx_charger_ac_work(struct work_struct *work)
860 sysfs_notify(&pm2->ac_chg.psy.dev->kobj, NULL, "present"); 855 sysfs_notify(&pm2->ac_chg.psy.dev->kobj, NULL, "present");
861}; 856};
862 857
858static void pm2xxx_charger_check_hw_failure_work(struct work_struct *work)
859{
860 u8 reg_value;
861
862 struct pm2xxx_charger *pm2 = container_of(work,
863 struct pm2xxx_charger, check_hw_failure_work.work);
864
865 if (pm2->flags.ovv) {
866 pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT4, &reg_value);
867
868 if (!(reg_value & (PM2XXX_INT4_S_ITVPWR1OVV |
869 PM2XXX_INT4_S_ITVPWR2OVV))) {
870 pm2->flags.ovv = false;
871 power_supply_changed(&pm2->ac_chg.psy);
872 }
873 }
874
875 /* If we still have a failure, schedule a new check */
876 if (pm2->flags.ovv) {
877 queue_delayed_work(pm2->charger_wq,
878 &pm2->check_hw_failure_work, round_jiffies(HZ));
879 }
880}
881
863static void pm2xxx_charger_check_main_thermal_prot_work( 882static void pm2xxx_charger_check_main_thermal_prot_work(
864 struct work_struct *work) 883 struct work_struct *work)
865{ 884{
@@ -983,6 +1002,10 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client,
983 INIT_WORK(&pm2->check_main_thermal_prot_work, 1002 INIT_WORK(&pm2->check_main_thermal_prot_work,
984 pm2xxx_charger_check_main_thermal_prot_work); 1003 pm2xxx_charger_check_main_thermal_prot_work);
985 1004
1005 /* Init work for HW failure check */
1006 INIT_DEFERRABLE_WORK(&pm2->check_hw_failure_work,
1007 pm2xxx_charger_check_hw_failure_work);
1008
986 /* 1009 /*
987 * VDD ADC supply needs to be enabled from this driver when there 1010 * VDD ADC supply needs to be enabled from this driver when there
988 * is a charger connected to avoid erroneous BTEMP_HIGH/LOW 1011 * is a charger connected to avoid erroneous BTEMP_HIGH/LOW
@@ -1123,4 +1146,3 @@ MODULE_LICENSE("GPL v2");
1123MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay"); 1146MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay");
1124MODULE_ALIAS("platform:pm2xxx-charger"); 1147MODULE_ALIAS("platform:pm2xxx-charger");
1125MODULE_DESCRIPTION("PM2xxx charger management driver"); 1148MODULE_DESCRIPTION("PM2xxx charger management driver");
1126
diff --git a/drivers/power/pm2301_charger.h b/drivers/power/pm2301_charger.h
index e6319cdbc94f..fad1f387f8f4 100644
--- a/drivers/power/pm2301_charger.h
+++ b/drivers/power/pm2301_charger.h
@@ -506,6 +506,7 @@ struct pm2xxx_charger {
506 struct delayed_work check_vbat_work; 506 struct delayed_work check_vbat_work;
507 struct work_struct ac_work; 507 struct work_struct ac_work;
508 struct work_struct check_main_thermal_prot_work; 508 struct work_struct check_main_thermal_prot_work;
509 struct delayed_work check_hw_failure_work;
509 struct ux500_charger ac_chg; 510 struct ux500_charger ac_chg;
510 struct pm2xxx_charger_event_flags flags; 511 struct pm2xxx_charger_event_flags flags;
511}; 512};