diff options
author | Rajkumar Kasirajan <rajkumar.kasirajan@stericsson.com> | 2012-05-30 07:02:37 -0400 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2013-03-06 23:26:47 -0500 |
commit | f04a9d8adf766c480353c0f2427e641251c9b059 (patch) | |
tree | 360a450f4d66089fc119bfb4a3e0f482a88973f4 | |
parent | 6dbe51c251a327e012439c4772097a13df43c5b8 (diff) |
mfd: ab8500-sysctrl: Update correct turn on status
In L9540, turn_on_status register is not updated correctly if
the device is rebooted with AC/USB charger connected. Due to
this, the device boots android instead of entering into charge
only mode. Read the AC/USB status register to detect the charger
presence and update the turn on status manually.
Signed-off-by: Rajkumar Kasirajan <rajkumar.kasirajan@stericsson.com>
Signed-off-by: Per Forlin <per.forlin@stericsson.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Rupesh KUMAR <rupesh.kumar@stericsson.com>
Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com>
Tested-by: Rupesh KUMAR <rupesh.kumar@stericsson.com>
Tested-by: Philippe LANGLAIS <philippe.langlais@stericsson.com>
Acked-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r-- | drivers/mfd/ab8500-core.c | 39 | ||||
-rw-r--r-- | drivers/mfd/ab8500-sysctrl.c | 2 | ||||
-rw-r--r-- | include/linux/mfd/abx500/ab8500.h | 2 |
3 files changed, 42 insertions, 1 deletions
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index 7c84ced2e01b..50e6f1e29727 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -111,6 +111,13 @@ | |||
111 | 111 | ||
112 | #define AB8500_TURN_ON_STATUS 0x00 | 112 | #define AB8500_TURN_ON_STATUS 0x00 |
113 | 113 | ||
114 | #define AB8500_CH_USBCH_STAT1_REG 0x02 | ||
115 | #define VBUS_DET_DBNC100 0x02 | ||
116 | #define VBUS_DET_DBNC1 0x01 | ||
117 | |||
118 | static DEFINE_SPINLOCK(on_stat_lock); | ||
119 | static u8 turn_on_stat_mask = 0xFF; | ||
120 | static u8 turn_on_stat_set; | ||
114 | static bool no_bm; /* No battery management */ | 121 | static bool no_bm; /* No battery management */ |
115 | module_param(no_bm, bool, S_IRUGO); | 122 | module_param(no_bm, bool, S_IRUGO); |
116 | 123 | ||
@@ -1171,6 +1178,15 @@ static ssize_t show_switch_off_status(struct device *dev, | |||
1171 | return sprintf(buf, "%#x\n", value); | 1178 | return sprintf(buf, "%#x\n", value); |
1172 | } | 1179 | } |
1173 | 1180 | ||
1181 | /* use mask and set to override the register turn_on_stat value */ | ||
1182 | void ab8500_override_turn_on_stat(u8 mask, u8 set) | ||
1183 | { | ||
1184 | spin_lock(&on_stat_lock); | ||
1185 | turn_on_stat_mask = mask; | ||
1186 | turn_on_stat_set = set; | ||
1187 | spin_unlock(&on_stat_lock); | ||
1188 | } | ||
1189 | |||
1174 | /* | 1190 | /* |
1175 | * ab8500 has turned on due to (TURN_ON_STATUS): | 1191 | * ab8500 has turned on due to (TURN_ON_STATUS): |
1176 | * 0x01 PORnVbat | 1192 | * 0x01 PORnVbat |
@@ -1194,6 +1210,20 @@ static ssize_t show_turn_on_status(struct device *dev, | |||
1194 | AB8500_TURN_ON_STATUS, &value); | 1210 | AB8500_TURN_ON_STATUS, &value); |
1195 | if (ret < 0) | 1211 | if (ret < 0) |
1196 | return ret; | 1212 | return ret; |
1213 | |||
1214 | /* | ||
1215 | * In L9540, turn_on_status register is not updated correctly if | ||
1216 | * the device is rebooted with AC/USB charger connected. Due to | ||
1217 | * this, the device boots android instead of entering into charge | ||
1218 | * only mode. Read the AC/USB status register to detect the charger | ||
1219 | * presence and update the turn on status manually. | ||
1220 | */ | ||
1221 | if (is_ab9540(ab8500)) { | ||
1222 | spin_lock(&on_stat_lock); | ||
1223 | value = (value & turn_on_stat_mask) | turn_on_stat_set; | ||
1224 | spin_unlock(&on_stat_lock); | ||
1225 | } | ||
1226 | |||
1197 | return sprintf(buf, "%#x\n", value); | 1227 | return sprintf(buf, "%#x\n", value); |
1198 | } | 1228 | } |
1199 | 1229 | ||
@@ -1399,6 +1429,15 @@ static int ab8500_probe(struct platform_device *pdev) | |||
1399 | 1429 | ||
1400 | if (plat && plat->init) | 1430 | if (plat && plat->init) |
1401 | plat->init(ab8500); | 1431 | plat->init(ab8500); |
1432 | if (is_ab9540(ab8500)) { | ||
1433 | ret = get_register_interruptible(ab8500, AB8500_CHARGER, | ||
1434 | AB8500_CH_USBCH_STAT1_REG, &value); | ||
1435 | if (ret < 0) | ||
1436 | return ret; | ||
1437 | if ((value & VBUS_DET_DBNC1) && (value & VBUS_DET_DBNC100)) | ||
1438 | ab8500_override_turn_on_stat(~AB8500_POW_KEY_1_ON, | ||
1439 | AB8500_VBUS_DET); | ||
1440 | } | ||
1402 | 1441 | ||
1403 | /* Clear and mask all interrupts */ | 1442 | /* Clear and mask all interrupts */ |
1404 | for (i = 0; i < ab8500->mask_size; i++) { | 1443 | for (i = 0; i < ab8500->mask_size; i++) { |
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c index 108fd86552f0..7c773797d267 100644 --- a/drivers/mfd/ab8500-sysctrl.c +++ b/drivers/mfd/ab8500-sysctrl.c | |||
@@ -21,7 +21,7 @@ void ab8500_power_off(void) | |||
21 | { | 21 | { |
22 | sigset_t old; | 22 | sigset_t old; |
23 | sigset_t all; | 23 | sigset_t all; |
24 | static char *pss[] = {"ab8500_ac", "ab8500_usb"}; | 24 | static char *pss[] = {"ab8500_ac", "pm2301", "ab8500_usb"}; |
25 | int i; | 25 | int i; |
26 | bool charger_present = false; | 26 | bool charger_present = false; |
27 | union power_supply_propval val; | 27 | union power_supply_propval val; |
diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h index 9db0bda446a0..fdd8be64feeb 100644 --- a/include/linux/mfd/abx500/ab8500.h +++ b/include/linux/mfd/abx500/ab8500.h | |||
@@ -512,6 +512,8 @@ static inline int is_ab9540_2p0_or_earlier(struct ab8500 *ab) | |||
512 | return (is_ab9540(ab) && (ab->chip_id < AB8500_CUT2P0)); | 512 | return (is_ab9540(ab) && (ab->chip_id < AB8500_CUT2P0)); |
513 | } | 513 | } |
514 | 514 | ||
515 | void ab8500_override_turn_on_stat(u8 mask, u8 set); | ||
516 | |||
515 | #ifdef CONFIG_AB8500_DEBUG | 517 | #ifdef CONFIG_AB8500_DEBUG |
516 | void ab8500_dump_all_banks(struct device *dev); | 518 | void ab8500_dump_all_banks(struct device *dev); |
517 | void ab8500_debug_register_interrupt(int line); | 519 | void ab8500_debug_register_interrupt(int line); |