diff options
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/Kconfig | 7 | ||||
-rw-r--r-- | drivers/power/Makefile | 1 | ||||
-rw-r--r-- | drivers/power/ab8500_btemp.c | 67 | ||||
-rw-r--r-- | drivers/power/ab8500_charger.c | 617 | ||||
-rw-r--r-- | drivers/power/ab8500_fg.c | 51 | ||||
-rw-r--r-- | drivers/power/abx500_chargalg.c | 43 | ||||
-rw-r--r-- | drivers/power/pm2301_charger.c | 1088 | ||||
-rw-r--r-- | drivers/power/pm2301_charger.h | 513 |
8 files changed, 2210 insertions, 177 deletions
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 1ae51551c9ff..1e4719790a94 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig | |||
@@ -352,6 +352,13 @@ config BATTERY_GOLDFISH | |||
352 | Say Y to enable support for the battery and AC power in the | 352 | Say Y to enable support for the battery and AC power in the |
353 | Goldfish emulator. | 353 | Goldfish emulator. |
354 | 354 | ||
355 | config CHARGER_PM2301 | ||
356 | bool "PM2301 Battery Charger Driver" | ||
357 | depends on AB8500_BM | ||
358 | help | ||
359 | Say Y to include support for PM2301 charger driver. | ||
360 | Depends on AB8500 battery management core. | ||
361 | |||
355 | source "drivers/power/reset/Kconfig" | 362 | source "drivers/power/reset/Kconfig" |
356 | 363 | ||
357 | endif # POWER_SUPPLY | 364 | endif # POWER_SUPPLY |
diff --git a/drivers/power/Makefile b/drivers/power/Makefile index a9f5c06ad41a..3f66436af45c 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile | |||
@@ -47,6 +47,7 @@ obj-$(CONFIG_CHARGER_LP8727) += lp8727_charger.o | |||
47 | obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o | 47 | obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o |
48 | obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o | 48 | obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o |
49 | obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o | 49 | obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o |
50 | obj-$(CONFIG_CHARGER_PM2301) += pm2301_charger.o | ||
50 | obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o | 51 | obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o |
51 | obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o | 52 | obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o |
52 | obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o | 53 | obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o |
diff --git a/drivers/power/ab8500_btemp.c b/drivers/power/ab8500_btemp.c index f3afebd4fac4..07689064996e 100644 --- a/drivers/power/ab8500_btemp.c +++ b/drivers/power/ab8500_btemp.c | |||
@@ -39,6 +39,9 @@ | |||
39 | #define BTEMP_BATCTRL_CURR_SRC_7UA 7 | 39 | #define BTEMP_BATCTRL_CURR_SRC_7UA 7 |
40 | #define BTEMP_BATCTRL_CURR_SRC_20UA 20 | 40 | #define BTEMP_BATCTRL_CURR_SRC_20UA 20 |
41 | 41 | ||
42 | #define BTEMP_BATCTRL_CURR_SRC_16UA 16 | ||
43 | #define BTEMP_BATCTRL_CURR_SRC_18UA 18 | ||
44 | |||
42 | #define to_ab8500_btemp_device_info(x) container_of((x), \ | 45 | #define to_ab8500_btemp_device_info(x) container_of((x), \ |
43 | struct ab8500_btemp, btemp_psy); | 46 | struct ab8500_btemp, btemp_psy); |
44 | 47 | ||
@@ -212,10 +215,18 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, | |||
212 | 215 | ||
213 | /* Only do this for batteries with internal NTC */ | 216 | /* Only do this for batteries with internal NTC */ |
214 | if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && enable) { | 217 | if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && enable) { |
215 | if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_7UA) | 218 | |
216 | curr = BAT_CTRL_7U_ENA; | 219 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) { |
217 | else | 220 | if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_16UA) |
218 | curr = BAT_CTRL_20U_ENA; | 221 | curr = BAT_CTRL_16U_ENA; |
222 | else | ||
223 | curr = BAT_CTRL_18U_ENA; | ||
224 | } else { | ||
225 | if (di->curr_source == BTEMP_BATCTRL_CURR_SRC_7UA) | ||
226 | curr = BAT_CTRL_7U_ENA; | ||
227 | else | ||
228 | curr = BAT_CTRL_20U_ENA; | ||
229 | } | ||
219 | 230 | ||
220 | dev_dbg(di->dev, "Set BATCTRL %duA\n", di->curr_source); | 231 | dev_dbg(di->dev, "Set BATCTRL %duA\n", di->curr_source); |
221 | 232 | ||
@@ -246,11 +257,22 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, | |||
246 | } else if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && !enable) { | 257 | } else if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && !enable) { |
247 | dev_dbg(di->dev, "Disable BATCTRL curr source\n"); | 258 | dev_dbg(di->dev, "Disable BATCTRL curr source\n"); |
248 | 259 | ||
249 | /* Write 0 to the curr bits */ | 260 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) { |
250 | ret = abx500_mask_and_set_register_interruptible(di->dev, | 261 | /* Write 0 to the curr bits */ |
251 | AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, | 262 | ret = abx500_mask_and_set_register_interruptible( |
252 | BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA, | 263 | di->dev, |
253 | ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA)); | 264 | AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, |
265 | BAT_CTRL_16U_ENA | BAT_CTRL_18U_ENA, | ||
266 | ~(BAT_CTRL_16U_ENA | BAT_CTRL_18U_ENA)); | ||
267 | } else { | ||
268 | /* Write 0 to the curr bits */ | ||
269 | ret = abx500_mask_and_set_register_interruptible( | ||
270 | di->dev, | ||
271 | AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, | ||
272 | BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA, | ||
273 | ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA)); | ||
274 | } | ||
275 | |||
254 | if (ret) { | 276 | if (ret) { |
255 | dev_err(di->dev, "%s failed disabling current source\n", | 277 | dev_err(di->dev, "%s failed disabling current source\n", |
256 | __func__); | 278 | __func__); |
@@ -292,11 +314,20 @@ static int ab8500_btemp_curr_source_enable(struct ab8500_btemp *di, | |||
292 | * if we got an error above | 314 | * if we got an error above |
293 | */ | 315 | */ |
294 | disable_curr_source: | 316 | disable_curr_source: |
295 | /* Write 0 to the curr bits */ | 317 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) { |
296 | ret = abx500_mask_and_set_register_interruptible(di->dev, | 318 | /* Write 0 to the curr bits */ |
319 | ret = abx500_mask_and_set_register_interruptible(di->dev, | ||
320 | AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, | ||
321 | BAT_CTRL_16U_ENA | BAT_CTRL_18U_ENA, | ||
322 | ~(BAT_CTRL_16U_ENA | BAT_CTRL_18U_ENA)); | ||
323 | } else { | ||
324 | /* Write 0 to the curr bits */ | ||
325 | ret = abx500_mask_and_set_register_interruptible(di->dev, | ||
297 | AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, | 326 | AB8500_CHARGER, AB8500_BAT_CTRL_CURRENT_SOURCE, |
298 | BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA, | 327 | BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA, |
299 | ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA)); | 328 | ~(BAT_CTRL_7U_ENA | BAT_CTRL_20U_ENA)); |
329 | } | ||
330 | |||
300 | if (ret) { | 331 | if (ret) { |
301 | dev_err(di->dev, "%s failed disabling current source\n", | 332 | dev_err(di->dev, "%s failed disabling current source\n", |
302 | __func__); | 333 | __func__); |
@@ -510,8 +541,11 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) | |||
510 | { | 541 | { |
511 | int res; | 542 | int res; |
512 | u8 i; | 543 | u8 i; |
544 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) | ||
545 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_16UA; | ||
546 | else | ||
547 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA; | ||
513 | 548 | ||
514 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_7UA; | ||
515 | di->bm->batt_id = BATTERY_UNKNOWN; | 549 | di->bm->batt_id = BATTERY_UNKNOWN; |
516 | 550 | ||
517 | res = ab8500_btemp_get_batctrl_res(di); | 551 | res = ab8500_btemp_get_batctrl_res(di); |
@@ -549,8 +583,13 @@ static int ab8500_btemp_id(struct ab8500_btemp *di) | |||
549 | */ | 583 | */ |
550 | if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && | 584 | if (di->bm->adc_therm == ABx500_ADC_THERM_BATCTRL && |
551 | di->bm->batt_id == 1) { | 585 | di->bm->batt_id == 1) { |
552 | dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n"); | 586 | if (is_ab9540(di->parent) || is_ab8505(di->parent)) { |
553 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA; | 587 | dev_dbg(di->dev, "Set BATCTRL current source to 16uA\n"); |
588 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_16UA; | ||
589 | } else { | ||
590 | dev_dbg(di->dev, "Set BATCTRL current source to 20uA\n"); | ||
591 | di->curr_source = BTEMP_BATCTRL_CURR_SRC_20UA; | ||
592 | } | ||
554 | } | 593 | } |
555 | 594 | ||
556 | return di->bm->batt_id; | 595 | return di->bm->batt_id; |
diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c index d5a8bdadb49a..24b30b7ea5ca 100644 --- a/drivers/power/ab8500_charger.c +++ b/drivers/power/ab8500_charger.c | |||
@@ -55,6 +55,7 @@ | |||
55 | 55 | ||
56 | #define MAIN_CH_INPUT_CURR_SHIFT 4 | 56 | #define MAIN_CH_INPUT_CURR_SHIFT 4 |
57 | #define VBUS_IN_CURR_LIM_SHIFT 4 | 57 | #define VBUS_IN_CURR_LIM_SHIFT 4 |
58 | #define AUTO_VBUS_IN_CURR_LIM_SHIFT 4 | ||
58 | 59 | ||
59 | #define LED_INDICATOR_PWM_ENA 0x01 | 60 | #define LED_INDICATOR_PWM_ENA 0x01 |
60 | #define LED_INDICATOR_PWM_DIS 0x00 | 61 | #define LED_INDICATOR_PWM_DIS 0x00 |
@@ -88,11 +89,14 @@ | |||
88 | /* Step up/down delay in us */ | 89 | /* Step up/down delay in us */ |
89 | #define STEP_UDELAY 1000 | 90 | #define STEP_UDELAY 1000 |
90 | 91 | ||
91 | /* Wait for enumeration before charging in ms */ | ||
92 | #define WAIT_FOR_USB_ENUMERATION 5 * 1000 | ||
93 | |||
94 | #define CHARGER_STATUS_POLL 10 /* in ms */ | 92 | #define CHARGER_STATUS_POLL 10 /* in ms */ |
95 | 93 | ||
94 | #define CHG_WD_INTERVAL (60 * HZ) | ||
95 | |||
96 | #define AB8500_SW_CONTROL_FALLBACK 0x03 | ||
97 | /* Wait for enumeration before charing in us */ | ||
98 | #define WAIT_ACA_RID_ENUMERATION (5 * 1000) | ||
99 | |||
96 | /* UsbLineStatus register - usb types */ | 100 | /* UsbLineStatus register - usb types */ |
97 | enum ab8500_charger_link_status { | 101 | enum ab8500_charger_link_status { |
98 | USB_STAT_NOT_CONFIGURED, | 102 | USB_STAT_NOT_CONFIGURED, |
@@ -181,12 +185,14 @@ struct ab8500_charger_event_flags { | |||
181 | bool usbchargernotok; | 185 | bool usbchargernotok; |
182 | bool chgwdexp; | 186 | bool chgwdexp; |
183 | bool vbus_collapse; | 187 | bool vbus_collapse; |
188 | bool vbus_drop_end; | ||
184 | }; | 189 | }; |
185 | 190 | ||
186 | struct ab8500_charger_usb_state { | 191 | struct ab8500_charger_usb_state { |
187 | bool usb_changed; | ||
188 | int usb_current; | 192 | int usb_current; |
193 | int usb_current_tmp; | ||
189 | enum ab8500_usb_state state; | 194 | enum ab8500_usb_state state; |
195 | enum ab8500_usb_state state_tmp; | ||
190 | spinlock_t usb_lock; | 196 | spinlock_t usb_lock; |
191 | }; | 197 | }; |
192 | 198 | ||
@@ -207,6 +213,11 @@ struct ab8500_charger_usb_state { | |||
207 | * @usb_device_is_unrecognised USB device is unrecognised by the hardware | 213 | * @usb_device_is_unrecognised USB device is unrecognised by the hardware |
208 | * @autopower Indicate if we should have automatic pwron after pwrloss | 214 | * @autopower Indicate if we should have automatic pwron after pwrloss |
209 | * @autopower_cfg platform specific power config support for "pwron after pwrloss" | 215 | * @autopower_cfg platform specific power config support for "pwron after pwrloss" |
216 | * @invalid_charger_detect_state State when forcing AB to use invalid charger | ||
217 | * @is_usb_host: Indicate if last detected USB type is host | ||
218 | * @is_aca_rid: Incicate if accessory is ACA type | ||
219 | * @current_stepping_sessions: | ||
220 | * Counter for current stepping sessions | ||
210 | * @parent: Pointer to the struct ab8500 | 221 | * @parent: Pointer to the struct ab8500 |
211 | * @gpadc: Pointer to the struct gpadc | 222 | * @gpadc: Pointer to the struct gpadc |
212 | * @bm: Platform specific battery management information | 223 | * @bm: Platform specific battery management information |
@@ -218,12 +229,13 @@ struct ab8500_charger_usb_state { | |||
218 | * @usb: Structure that holds the USB charger properties | 229 | * @usb: Structure that holds the USB charger properties |
219 | * @regu: Pointer to the struct regulator | 230 | * @regu: Pointer to the struct regulator |
220 | * @charger_wq: Work queue for the IRQs and checking HW state | 231 | * @charger_wq: Work queue for the IRQs and checking HW state |
232 | * @usb_ipt_crnt_lock: Lock to protect VBUS input current setting from mutuals | ||
233 | * @pm_lock: Lock to prevent system to suspend | ||
221 | * @check_vbat_work Work for checking vbat threshold to adjust vbus current | 234 | * @check_vbat_work Work for checking vbat threshold to adjust vbus current |
222 | * @check_hw_failure_work: Work for checking HW state | 235 | * @check_hw_failure_work: Work for checking HW state |
223 | * @check_usbchgnotok_work: Work for checking USB charger not ok status | 236 | * @check_usbchgnotok_work: Work for checking USB charger not ok status |
224 | * @kick_wd_work: Work for kicking the charger watchdog in case | 237 | * @kick_wd_work: Work for kicking the charger watchdog in case |
225 | * of ABB rev 1.* due to the watchog logic bug | 238 | * of ABB rev 1.* due to the watchog logic bug |
226 | * @attach_work: Work for checking the usb enumeration | ||
227 | * @ac_charger_attached_work: Work for checking if AC charger is still | 239 | * @ac_charger_attached_work: Work for checking if AC charger is still |
228 | * connected | 240 | * connected |
229 | * @usb_charger_attached_work: Work for checking if USB charger is still | 241 | * @usb_charger_attached_work: Work for checking if USB charger is still |
@@ -232,6 +244,8 @@ struct ab8500_charger_usb_state { | |||
232 | * @detect_usb_type_work: Work for detecting the USB type connected | 244 | * @detect_usb_type_work: Work for detecting the USB type connected |
233 | * @usb_link_status_work: Work for checking the new USB link status | 245 | * @usb_link_status_work: Work for checking the new USB link status |
234 | * @usb_state_changed_work: Work for checking USB state | 246 | * @usb_state_changed_work: Work for checking USB state |
247 | * @attach_work: Work for detecting USB type | ||
248 | * @vbus_drop_end_work: Work for detecting VBUS drop end | ||
235 | * @check_main_thermal_prot_work: | 249 | * @check_main_thermal_prot_work: |
236 | * Work for checking Main thermal status | 250 | * Work for checking Main thermal status |
237 | * @check_usb_thermal_prot_work: | 251 | * @check_usb_thermal_prot_work: |
@@ -251,6 +265,10 @@ struct ab8500_charger { | |||
251 | bool usb_device_is_unrecognised; | 265 | bool usb_device_is_unrecognised; |
252 | bool autopower; | 266 | bool autopower; |
253 | bool autopower_cfg; | 267 | bool autopower_cfg; |
268 | int invalid_charger_detect_state; | ||
269 | bool is_usb_host; | ||
270 | int is_aca_rid; | ||
271 | atomic_t current_stepping_sessions; | ||
254 | struct ab8500 *parent; | 272 | struct ab8500 *parent; |
255 | struct ab8500_gpadc *gpadc; | 273 | struct ab8500_gpadc *gpadc; |
256 | struct abx500_bm_data *bm; | 274 | struct abx500_bm_data *bm; |
@@ -262,17 +280,19 @@ struct ab8500_charger { | |||
262 | struct ab8500_charger_info usb; | 280 | struct ab8500_charger_info usb; |
263 | struct regulator *regu; | 281 | struct regulator *regu; |
264 | struct workqueue_struct *charger_wq; | 282 | struct workqueue_struct *charger_wq; |
283 | struct mutex usb_ipt_crnt_lock; | ||
265 | struct delayed_work check_vbat_work; | 284 | struct delayed_work check_vbat_work; |
266 | struct delayed_work check_hw_failure_work; | 285 | struct delayed_work check_hw_failure_work; |
267 | struct delayed_work check_usbchgnotok_work; | 286 | struct delayed_work check_usbchgnotok_work; |
268 | struct delayed_work kick_wd_work; | 287 | struct delayed_work kick_wd_work; |
288 | struct delayed_work usb_state_changed_work; | ||
269 | struct delayed_work attach_work; | 289 | struct delayed_work attach_work; |
270 | struct delayed_work ac_charger_attached_work; | 290 | struct delayed_work ac_charger_attached_work; |
271 | struct delayed_work usb_charger_attached_work; | 291 | struct delayed_work usb_charger_attached_work; |
292 | struct delayed_work vbus_drop_end_work; | ||
272 | struct work_struct ac_work; | 293 | struct work_struct ac_work; |
273 | struct work_struct detect_usb_type_work; | 294 | struct work_struct detect_usb_type_work; |
274 | struct work_struct usb_link_status_work; | 295 | struct work_struct usb_link_status_work; |
275 | struct work_struct usb_state_changed_work; | ||
276 | struct work_struct check_main_thermal_prot_work; | 296 | struct work_struct check_main_thermal_prot_work; |
277 | struct work_struct check_usb_thermal_prot_work; | 297 | struct work_struct check_usb_thermal_prot_work; |
278 | struct usb_phy *usb_phy; | 298 | struct usb_phy *usb_phy; |
@@ -308,42 +328,58 @@ static enum power_supply_property ab8500_charger_usb_props[] = { | |||
308 | static void ab8500_enable_disable_sw_fallback(struct ab8500_charger *di, | 328 | static void ab8500_enable_disable_sw_fallback(struct ab8500_charger *di, |
309 | bool fallback) | 329 | bool fallback) |
310 | { | 330 | { |
331 | u8 val; | ||
311 | u8 reg; | 332 | u8 reg; |
333 | u8 bank; | ||
334 | u8 bit; | ||
312 | int ret; | 335 | int ret; |
313 | 336 | ||
314 | dev_dbg(di->dev, "SW Fallback: %d\n", fallback); | 337 | dev_dbg(di->dev, "SW Fallback: %d\n", fallback); |
315 | 338 | ||
339 | if (is_ab8500(di->parent)) { | ||
340 | bank = 0x15; | ||
341 | reg = 0x0; | ||
342 | bit = 3; | ||
343 | } else { | ||
344 | bank = AB8500_SYS_CTRL1_BLOCK; | ||
345 | reg = AB8500_SW_CONTROL_FALLBACK; | ||
346 | bit = 0; | ||
347 | } | ||
348 | |||
316 | /* read the register containing fallback bit */ | 349 | /* read the register containing fallback bit */ |
317 | ret = abx500_get_register_interruptible(di->dev, 0x15, 0x00, ®); | 350 | ret = abx500_get_register_interruptible(di->dev, bank, reg, &val); |
318 | if (ret) { | 351 | if (ret < 0) { |
319 | dev_err(di->dev, "%d write failed\n", __LINE__); | 352 | dev_err(di->dev, "%d read failed\n", __LINE__); |
320 | return; | 353 | return; |
321 | } | 354 | } |
322 | 355 | ||
323 | /* enable the OPT emulation registers */ | 356 | if (is_ab8500(di->parent)) { |
324 | ret = abx500_set_register_interruptible(di->dev, 0x11, 0x00, 0x2); | 357 | /* enable the OPT emulation registers */ |
325 | if (ret) { | 358 | ret = abx500_set_register_interruptible(di->dev, 0x11, 0x00, 0x2); |
326 | dev_err(di->dev, "%d write failed\n", __LINE__); | 359 | if (ret) { |
327 | return; | 360 | dev_err(di->dev, "%d write failed\n", __LINE__); |
361 | goto disable_otp; | ||
362 | } | ||
328 | } | 363 | } |
329 | 364 | ||
330 | if (fallback) | 365 | if (fallback) |
331 | reg |= 0x8; | 366 | val |= (1 << bit); |
332 | else | 367 | else |
333 | reg &= ~0x8; | 368 | val &= ~(1 << bit); |
334 | 369 | ||
335 | /* write back the changed fallback bit value to register */ | 370 | /* write back the changed fallback bit value to register */ |
336 | ret = abx500_set_register_interruptible(di->dev, 0x15, 0x00, reg); | 371 | ret = abx500_set_register_interruptible(di->dev, bank, reg, val); |
337 | if (ret) { | 372 | if (ret) { |
338 | dev_err(di->dev, "%d write failed\n", __LINE__); | 373 | dev_err(di->dev, "%d write failed\n", __LINE__); |
339 | return; | ||
340 | } | 374 | } |
341 | 375 | ||
342 | /* disable the set OTP registers again */ | 376 | disable_otp: |
343 | ret = abx500_set_register_interruptible(di->dev, 0x11, 0x00, 0x0); | 377 | if (is_ab8500(di->parent)) { |
344 | if (ret) { | 378 | /* disable the set OTP registers again */ |
345 | dev_err(di->dev, "%d write failed\n", __LINE__); | 379 | ret = abx500_set_register_interruptible(di->dev, 0x11, 0x00, 0x0); |
346 | return; | 380 | if (ret) { |
381 | dev_err(di->dev, "%d write failed\n", __LINE__); | ||
382 | } | ||
347 | } | 383 | } |
348 | } | 384 | } |
349 | 385 | ||
@@ -546,6 +582,7 @@ static int ab8500_charger_usb_cv(struct ab8500_charger *di) | |||
546 | /** | 582 | /** |
547 | * ab8500_charger_detect_chargers() - Detect the connected chargers | 583 | * ab8500_charger_detect_chargers() - Detect the connected chargers |
548 | * @di: pointer to the ab8500_charger structure | 584 | * @di: pointer to the ab8500_charger structure |
585 | * @probe: if probe, don't delay and wait for HW | ||
549 | * | 586 | * |
550 | * Returns the type of charger connected. | 587 | * Returns the type of charger connected. |
551 | * For USB it will not mean we can actually charge from it | 588 | * For USB it will not mean we can actually charge from it |
@@ -559,7 +596,7 @@ static int ab8500_charger_usb_cv(struct ab8500_charger *di) | |||
559 | * USB_PW_CONN if the USB power supply is connected | 596 | * USB_PW_CONN if the USB power supply is connected |
560 | * AC_PW_CONN + USB_PW_CONN if USB and AC power supplies are both connected | 597 | * AC_PW_CONN + USB_PW_CONN if USB and AC power supplies are both connected |
561 | */ | 598 | */ |
562 | static int ab8500_charger_detect_chargers(struct ab8500_charger *di) | 599 | static int ab8500_charger_detect_chargers(struct ab8500_charger *di, bool probe) |
563 | { | 600 | { |
564 | int result = NO_PW_CONN; | 601 | int result = NO_PW_CONN; |
565 | int ret; | 602 | int ret; |
@@ -577,13 +614,25 @@ static int ab8500_charger_detect_chargers(struct ab8500_charger *di) | |||
577 | result = AC_PW_CONN; | 614 | result = AC_PW_CONN; |
578 | 615 | ||
579 | /* Check for USB charger */ | 616 | /* Check for USB charger */ |
617 | |||
618 | if (!probe) { | ||
619 | /* | ||
620 | * AB8500 says VBUS_DET_DBNC1 & VBUS_DET_DBNC100 | ||
621 | * when disconnecting ACA even though no | ||
622 | * charger was connected. Try waiting a little | ||
623 | * longer than the 100 ms of VBUS_DET_DBNC100... | ||
624 | */ | ||
625 | msleep(110); | ||
626 | } | ||
580 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | 627 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, |
581 | AB8500_CH_USBCH_STAT1_REG, &val); | 628 | AB8500_CH_USBCH_STAT1_REG, &val); |
582 | if (ret < 0) { | 629 | if (ret < 0) { |
583 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); | 630 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); |
584 | return ret; | 631 | return ret; |
585 | } | 632 | } |
586 | 633 | dev_dbg(di->dev, | |
634 | "%s AB8500_CH_USBCH_STAT1_REG %x\n", __func__, | ||
635 | val); | ||
587 | if ((val & VBUS_DET_DBNC1) && (val & VBUS_DET_DBNC100)) | 636 | if ((val & VBUS_DET_DBNC1) && (val & VBUS_DET_DBNC100)) |
588 | result |= USB_PW_CONN; | 637 | result |= USB_PW_CONN; |
589 | 638 | ||
@@ -606,33 +655,47 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
606 | 655 | ||
607 | di->usb_device_is_unrecognised = false; | 656 | di->usb_device_is_unrecognised = false; |
608 | 657 | ||
658 | /* | ||
659 | * Platform only supports USB 2.0. | ||
660 | * This means that charging current from USB source | ||
661 | * is maximum 500 mA. Every occurence of USB_STAT_*_HOST_* | ||
662 | * should set USB_CH_IP_CUR_LVL_0P5. | ||
663 | */ | ||
664 | |||
609 | switch (link_status) { | 665 | switch (link_status) { |
610 | case USB_STAT_STD_HOST_NC: | 666 | case USB_STAT_STD_HOST_NC: |
611 | case USB_STAT_STD_HOST_C_NS: | 667 | case USB_STAT_STD_HOST_C_NS: |
612 | case USB_STAT_STD_HOST_C_S: | 668 | case USB_STAT_STD_HOST_C_S: |
613 | dev_dbg(di->dev, "USB Type - Standard host is " | 669 | dev_dbg(di->dev, "USB Type - Standard host is " |
614 | "detected through USB driver\n"); | 670 | "detected through USB driver\n"); |
615 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P09; | 671 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; |
672 | di->is_usb_host = true; | ||
673 | di->is_aca_rid = 0; | ||
616 | break; | 674 | break; |
617 | case USB_STAT_HOST_CHG_HS_CHIRP: | 675 | case USB_STAT_HOST_CHG_HS_CHIRP: |
618 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 676 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; |
619 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, | 677 | di->is_usb_host = true; |
620 | di->max_usb_in_curr); | 678 | di->is_aca_rid = 0; |
621 | break; | 679 | break; |
622 | case USB_STAT_HOST_CHG_HS: | 680 | case USB_STAT_HOST_CHG_HS: |
681 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | ||
682 | di->is_usb_host = true; | ||
683 | di->is_aca_rid = 0; | ||
684 | break; | ||
623 | case USB_STAT_ACA_RID_C_HS: | 685 | case USB_STAT_ACA_RID_C_HS: |
624 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P9; | 686 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P9; |
625 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, | 687 | di->is_usb_host = false; |
626 | di->max_usb_in_curr); | 688 | di->is_aca_rid = 0; |
627 | break; | 689 | break; |
628 | case USB_STAT_ACA_RID_A: | 690 | case USB_STAT_ACA_RID_A: |
629 | /* | 691 | /* |
630 | * Dedicated charger level minus maximum current accessory | 692 | * Dedicated charger level minus maximum current accessory |
631 | * can consume (300mA). Closest level is 1100mA | 693 | * can consume (900mA). Closest level is 500mA |
632 | */ | 694 | */ |
633 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P1; | 695 | dev_dbg(di->dev, "USB_STAT_ACA_RID_A detected\n"); |
634 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, | 696 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; |
635 | di->max_usb_in_curr); | 697 | di->is_usb_host = false; |
698 | di->is_aca_rid = 1; | ||
636 | break; | 699 | break; |
637 | case USB_STAT_ACA_RID_B: | 700 | case USB_STAT_ACA_RID_B: |
638 | /* | 701 | /* |
@@ -642,14 +705,24 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
642 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P3; | 705 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P3; |
643 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, | 706 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, |
644 | di->max_usb_in_curr); | 707 | di->max_usb_in_curr); |
708 | di->is_usb_host = false; | ||
709 | di->is_aca_rid = 1; | ||
645 | break; | 710 | break; |
646 | case USB_STAT_HOST_CHG_NM: | 711 | case USB_STAT_HOST_CHG_NM: |
712 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | ||
713 | di->is_usb_host = true; | ||
714 | di->is_aca_rid = 0; | ||
715 | break; | ||
647 | case USB_STAT_DEDICATED_CHG: | 716 | case USB_STAT_DEDICATED_CHG: |
648 | case USB_STAT_ACA_RID_C_NM: | 717 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; |
718 | di->is_usb_host = false; | ||
719 | di->is_aca_rid = 0; | ||
720 | break; | ||
649 | case USB_STAT_ACA_RID_C_HS_CHIRP: | 721 | case USB_STAT_ACA_RID_C_HS_CHIRP: |
722 | case USB_STAT_ACA_RID_C_NM: | ||
650 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; | 723 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_1P5; |
651 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, | 724 | di->is_usb_host = false; |
652 | di->max_usb_in_curr); | 725 | di->is_aca_rid = 1; |
653 | break; | 726 | break; |
654 | case USB_STAT_NOT_CONFIGURED: | 727 | case USB_STAT_NOT_CONFIGURED: |
655 | if (di->vbus_detected) { | 728 | if (di->vbus_detected) { |
@@ -659,7 +732,6 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
659 | break; | 732 | break; |
660 | } | 733 | } |
661 | case USB_STAT_HM_IDGND: | 734 | case USB_STAT_HM_IDGND: |
662 | case USB_STAT_NOT_VALID_LINK: | ||
663 | dev_err(di->dev, "USB Type - Charging not allowed\n"); | 735 | dev_err(di->dev, "USB Type - Charging not allowed\n"); |
664 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; | 736 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P05; |
665 | ret = -ENXIO; | 737 | ret = -ENXIO; |
@@ -688,6 +760,9 @@ static int ab8500_charger_max_usb_curr(struct ab8500_charger *di, | |||
688 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | 760 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; |
689 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, | 761 | dev_dbg(di->dev, "USB Type - 0x%02x MaxCurr: %d", link_status, |
690 | di->max_usb_in_curr); | 762 | di->max_usb_in_curr); |
763 | case USB_STAT_NOT_VALID_LINK: | ||
764 | dev_err(di->dev, "USB Type invalid - try charging anyway\n"); | ||
765 | di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5; | ||
691 | break; | 766 | break; |
692 | 767 | ||
693 | default: | 768 | default: |
@@ -764,6 +839,8 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) | |||
764 | ret = abx500_get_register_interruptible(di->dev, | 839 | ret = abx500_get_register_interruptible(di->dev, |
765 | AB8500_INTERRUPT, AB8500_IT_SOURCE21_REG, | 840 | AB8500_INTERRUPT, AB8500_IT_SOURCE21_REG, |
766 | &val); | 841 | &val); |
842 | dev_dbg(di->dev, "%s AB8500_IT_SOURCE21_REG %x\n", | ||
843 | __func__, val); | ||
767 | if (ret < 0) { | 844 | if (ret < 0) { |
768 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); | 845 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); |
769 | return ret; | 846 | return ret; |
@@ -779,6 +856,8 @@ static int ab8500_charger_detect_usb_type(struct ab8500_charger *di) | |||
779 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); | 856 | dev_err(di->dev, "%s ab8500 read failed\n", __func__); |
780 | return ret; | 857 | return ret; |
781 | } | 858 | } |
859 | dev_dbg(di->dev, "%s AB8500_USB_LINE_STAT_REG %x\n", __func__, | ||
860 | val); | ||
782 | /* | 861 | /* |
783 | * Until the IT source register is read the UsbLineStatus | 862 | * Until the IT source register is read the UsbLineStatus |
784 | * register is not updated, hence doing the same | 863 | * register is not updated, hence doing the same |
@@ -1038,69 +1117,125 @@ static int ab8500_charger_get_usb_cur(struct ab8500_charger *di) | |||
1038 | static int ab8500_charger_set_current(struct ab8500_charger *di, | 1117 | static int ab8500_charger_set_current(struct ab8500_charger *di, |
1039 | int ich, int reg) | 1118 | int ich, int reg) |
1040 | { | 1119 | { |
1041 | int ret, i; | 1120 | int ret = 0; |
1042 | int curr_index, prev_curr_index, shift_value; | 1121 | int auto_curr_index, curr_index, prev_curr_index, shift_value, i; |
1043 | u8 reg_value; | 1122 | u8 reg_value; |
1123 | u32 step_udelay; | ||
1124 | bool no_stepping = false; | ||
1125 | |||
1126 | atomic_inc(&di->current_stepping_sessions); | ||
1127 | |||
1128 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | ||
1129 | reg, ®_value); | ||
1130 | if (ret < 0) { | ||
1131 | dev_err(di->dev, "%s read failed\n", __func__); | ||
1132 | goto exit_set_current; | ||
1133 | } | ||
1044 | 1134 | ||
1045 | switch (reg) { | 1135 | switch (reg) { |
1046 | case AB8500_MCH_IPT_CURLVL_REG: | 1136 | case AB8500_MCH_IPT_CURLVL_REG: |
1047 | shift_value = MAIN_CH_INPUT_CURR_SHIFT; | 1137 | shift_value = MAIN_CH_INPUT_CURR_SHIFT; |
1138 | prev_curr_index = (reg_value >> shift_value); | ||
1048 | curr_index = ab8500_current_to_regval(ich); | 1139 | curr_index = ab8500_current_to_regval(ich); |
1140 | step_udelay = STEP_UDELAY; | ||
1141 | if (!di->ac.charger_connected) | ||
1142 | no_stepping = true; | ||
1049 | break; | 1143 | break; |
1050 | case AB8500_USBCH_IPT_CRNTLVL_REG: | 1144 | case AB8500_USBCH_IPT_CRNTLVL_REG: |
1051 | shift_value = VBUS_IN_CURR_LIM_SHIFT; | 1145 | shift_value = VBUS_IN_CURR_LIM_SHIFT; |
1146 | prev_curr_index = (reg_value >> shift_value); | ||
1052 | curr_index = ab8500_vbus_in_curr_to_regval(ich); | 1147 | curr_index = ab8500_vbus_in_curr_to_regval(ich); |
1148 | step_udelay = STEP_UDELAY * 100; | ||
1149 | |||
1150 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | ||
1151 | AB8500_CH_USBCH_STAT2_REG, ®_value); | ||
1152 | if (ret < 0) { | ||
1153 | dev_err(di->dev, "%s read failed\n", __func__); | ||
1154 | goto exit_set_current; | ||
1155 | } | ||
1156 | auto_curr_index = | ||
1157 | reg_value >> AUTO_VBUS_IN_CURR_LIM_SHIFT; | ||
1158 | |||
1159 | dev_dbg(di->dev, "%s Auto VBUS curr is %d mA\n", | ||
1160 | __func__, | ||
1161 | ab8500_charger_vbus_in_curr_map[auto_curr_index]); | ||
1162 | |||
1163 | prev_curr_index = min(prev_curr_index, auto_curr_index); | ||
1164 | |||
1165 | if (!di->usb.charger_connected) | ||
1166 | no_stepping = true; | ||
1053 | break; | 1167 | break; |
1054 | case AB8500_CH_OPT_CRNTLVL_REG: | 1168 | case AB8500_CH_OPT_CRNTLVL_REG: |
1055 | shift_value = 0; | 1169 | shift_value = 0; |
1170 | prev_curr_index = (reg_value >> shift_value); | ||
1056 | curr_index = ab8500_current_to_regval(ich); | 1171 | curr_index = ab8500_current_to_regval(ich); |
1172 | step_udelay = STEP_UDELAY; | ||
1173 | if (curr_index && (curr_index - prev_curr_index) > 1) | ||
1174 | step_udelay *= 100; | ||
1175 | |||
1176 | if (!di->usb.charger_connected && !di->ac.charger_connected) | ||
1177 | no_stepping = true; | ||
1178 | |||
1057 | break; | 1179 | break; |
1058 | default: | 1180 | default: |
1059 | dev_err(di->dev, "%s current register not valid\n", __func__); | 1181 | dev_err(di->dev, "%s current register not valid\n", __func__); |
1060 | return -ENXIO; | 1182 | ret = -ENXIO; |
1183 | goto exit_set_current; | ||
1061 | } | 1184 | } |
1062 | 1185 | ||
1063 | if (curr_index < 0) { | 1186 | if (curr_index < 0) { |
1064 | dev_err(di->dev, "requested current limit out-of-range\n"); | 1187 | dev_err(di->dev, "requested current limit out-of-range\n"); |
1065 | return -ENXIO; | 1188 | ret = -ENXIO; |
1066 | } | 1189 | goto exit_set_current; |
1067 | |||
1068 | ret = abx500_get_register_interruptible(di->dev, AB8500_CHARGER, | ||
1069 | reg, ®_value); | ||
1070 | if (ret < 0) { | ||
1071 | dev_err(di->dev, "%s read failed\n", __func__); | ||
1072 | return ret; | ||
1073 | } | 1190 | } |
1074 | prev_curr_index = (reg_value >> shift_value); | ||
1075 | 1191 | ||
1076 | /* only update current if it's been changed */ | 1192 | /* only update current if it's been changed */ |
1077 | if (prev_curr_index == curr_index) | 1193 | if (prev_curr_index == curr_index) { |
1078 | return 0; | 1194 | dev_dbg(di->dev, "%s current not changed for reg: 0x%02x\n", |
1195 | __func__, reg); | ||
1196 | ret = 0; | ||
1197 | goto exit_set_current; | ||
1198 | } | ||
1079 | 1199 | ||
1080 | dev_dbg(di->dev, "%s set charger current: %d mA for reg: 0x%02x\n", | 1200 | dev_dbg(di->dev, "%s set charger current: %d mA for reg: 0x%02x\n", |
1081 | __func__, ich, reg); | 1201 | __func__, ich, reg); |
1082 | 1202 | ||
1083 | if (prev_curr_index > curr_index) { | 1203 | if (no_stepping) { |
1204 | ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, | ||
1205 | reg, (u8)curr_index << shift_value); | ||
1206 | if (ret) | ||
1207 | dev_err(di->dev, "%s write failed\n", __func__); | ||
1208 | } else if (prev_curr_index > curr_index) { | ||
1084 | for (i = prev_curr_index - 1; i >= curr_index; i--) { | 1209 | for (i = prev_curr_index - 1; i >= curr_index; i--) { |
1210 | dev_dbg(di->dev, "curr change_1 to: %x for 0x%02x\n", | ||
1211 | (u8) i << shift_value, reg); | ||
1085 | ret = abx500_set_register_interruptible(di->dev, | 1212 | ret = abx500_set_register_interruptible(di->dev, |
1086 | AB8500_CHARGER, reg, (u8) i << shift_value); | 1213 | AB8500_CHARGER, reg, (u8)i << shift_value); |
1087 | if (ret) { | 1214 | if (ret) { |
1088 | dev_err(di->dev, "%s write failed\n", __func__); | 1215 | dev_err(di->dev, "%s write failed\n", __func__); |
1089 | return ret; | 1216 | goto exit_set_current; |
1090 | } | 1217 | } |
1091 | usleep_range(STEP_UDELAY, STEP_UDELAY * 2); | 1218 | if (i != curr_index) |
1219 | usleep_range(step_udelay, step_udelay * 2); | ||
1092 | } | 1220 | } |
1093 | } else { | 1221 | } else { |
1094 | for (i = prev_curr_index + 1; i <= curr_index; i++) { | 1222 | for (i = prev_curr_index + 1; i <= curr_index; i++) { |
1223 | dev_dbg(di->dev, "curr change_2 to: %x for 0x%02x\n", | ||
1224 | (u8)i << shift_value, reg); | ||
1095 | ret = abx500_set_register_interruptible(di->dev, | 1225 | ret = abx500_set_register_interruptible(di->dev, |
1096 | AB8500_CHARGER, reg, (u8) i << shift_value); | 1226 | AB8500_CHARGER, reg, (u8)i << shift_value); |
1097 | if (ret) { | 1227 | if (ret) { |
1098 | dev_err(di->dev, "%s write failed\n", __func__); | 1228 | dev_err(di->dev, "%s write failed\n", __func__); |
1099 | return ret; | 1229 | goto exit_set_current; |
1100 | } | 1230 | } |
1101 | usleep_range(STEP_UDELAY, STEP_UDELAY * 2); | 1231 | if (i != curr_index) |
1232 | usleep_range(step_udelay, step_udelay * 2); | ||
1102 | } | 1233 | } |
1103 | } | 1234 | } |
1235 | |||
1236 | exit_set_current: | ||
1237 | atomic_dec(&di->current_stepping_sessions); | ||
1238 | |||
1104 | return ret; | 1239 | return ret; |
1105 | } | 1240 | } |
1106 | 1241 | ||
@@ -1116,6 +1251,7 @@ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di, | |||
1116 | int ich_in) | 1251 | int ich_in) |
1117 | { | 1252 | { |
1118 | int min_value; | 1253 | int min_value; |
1254 | int ret; | ||
1119 | 1255 | ||
1120 | /* We should always use to lowest current limit */ | 1256 | /* We should always use to lowest current limit */ |
1121 | min_value = min(di->bm->chg_params->usb_curr_max, ich_in); | 1257 | min_value = min(di->bm->chg_params->usb_curr_max, ich_in); |
@@ -1133,8 +1269,14 @@ static int ab8500_charger_set_vbus_in_curr(struct ab8500_charger *di, | |||
1133 | break; | 1269 | break; |
1134 | } | 1270 | } |
1135 | 1271 | ||
1136 | return ab8500_charger_set_current(di, min_value, | 1272 | dev_info(di->dev, "VBUS input current limit set to %d mA\n", min_value); |
1273 | |||
1274 | mutex_lock(&di->usb_ipt_crnt_lock); | ||
1275 | ret = ab8500_charger_set_current(di, min_value, | ||
1137 | AB8500_USBCH_IPT_CRNTLVL_REG); | 1276 | AB8500_USBCH_IPT_CRNTLVL_REG); |
1277 | mutex_unlock(&di->usb_ipt_crnt_lock); | ||
1278 | |||
1279 | return ret; | ||
1138 | } | 1280 | } |
1139 | 1281 | ||
1140 | /** | 1282 | /** |
@@ -1445,25 +1587,13 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, | |||
1445 | dev_err(di->dev, "%s write failed\n", __func__); | 1587 | dev_err(di->dev, "%s write failed\n", __func__); |
1446 | return ret; | 1588 | return ret; |
1447 | } | 1589 | } |
1448 | /* USBChInputCurr: current that can be drawn from the usb */ | ||
1449 | ret = ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); | ||
1450 | if (ret) { | ||
1451 | dev_err(di->dev, "setting USBChInputCurr failed\n"); | ||
1452 | return ret; | ||
1453 | } | ||
1454 | /* ChOutputCurentLevel: protected output current */ | ||
1455 | ret = ab8500_charger_set_output_curr(di, ich_out); | ||
1456 | if (ret) { | ||
1457 | dev_err(di->dev, "%s " | ||
1458 | "Failed to set ChOutputCurentLevel\n", | ||
1459 | __func__); | ||
1460 | return ret; | ||
1461 | } | ||
1462 | /* Check if VBAT overshoot control should be enabled */ | 1590 | /* Check if VBAT overshoot control should be enabled */ |
1463 | if (!di->bm->enable_overshoot) | 1591 | if (!di->bm->enable_overshoot) |
1464 | overshoot = USB_CHG_NO_OVERSHOOT_ENA_N; | 1592 | overshoot = USB_CHG_NO_OVERSHOOT_ENA_N; |
1465 | 1593 | ||
1466 | /* Enable USB Charger */ | 1594 | /* Enable USB Charger */ |
1595 | dev_dbg(di->dev, | ||
1596 | "Enabling USB with write to AB8500_USBCH_CTRL1_REG\n"); | ||
1467 | ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, | 1597 | ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, |
1468 | AB8500_USBCH_CTRL1_REG, USB_CH_ENA | overshoot); | 1598 | AB8500_USBCH_CTRL1_REG, USB_CH_ENA | overshoot); |
1469 | if (ret) { | 1599 | if (ret) { |
@@ -1476,11 +1606,29 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, | |||
1476 | if (ret < 0) | 1606 | if (ret < 0) |
1477 | dev_err(di->dev, "failed to enable LED\n"); | 1607 | dev_err(di->dev, "failed to enable LED\n"); |
1478 | 1608 | ||
1609 | di->usb.charger_online = 1; | ||
1610 | |||
1611 | /* USBChInputCurr: current that can be drawn from the usb */ | ||
1612 | ret = ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); | ||
1613 | if (ret) { | ||
1614 | dev_err(di->dev, "setting USBChInputCurr failed\n"); | ||
1615 | return ret; | ||
1616 | } | ||
1617 | |||
1618 | /* ChOutputCurentLevel: protected output current */ | ||
1619 | ret = ab8500_charger_set_output_curr(di, ich_out); | ||
1620 | if (ret) { | ||
1621 | dev_err(di->dev, "%s " | ||
1622 | "Failed to set ChOutputCurentLevel\n", | ||
1623 | __func__); | ||
1624 | return ret; | ||
1625 | } | ||
1626 | |||
1479 | queue_delayed_work(di->charger_wq, &di->check_vbat_work, HZ); | 1627 | queue_delayed_work(di->charger_wq, &di->check_vbat_work, HZ); |
1480 | 1628 | ||
1481 | di->usb.charger_online = 1; | ||
1482 | } else { | 1629 | } else { |
1483 | /* Disable USB charging */ | 1630 | /* Disable USB charging */ |
1631 | dev_dbg(di->dev, "%s Disabled USB charging\n", __func__); | ||
1484 | ret = abx500_set_register_interruptible(di->dev, | 1632 | ret = abx500_set_register_interruptible(di->dev, |
1485 | AB8500_CHARGER, | 1633 | AB8500_CHARGER, |
1486 | AB8500_USBCH_CTRL1_REG, 0); | 1634 | AB8500_USBCH_CTRL1_REG, 0); |
@@ -1493,7 +1641,21 @@ static int ab8500_charger_usb_en(struct ux500_charger *charger, | |||
1493 | ret = ab8500_charger_led_en(di, false); | 1641 | ret = ab8500_charger_led_en(di, false); |
1494 | if (ret < 0) | 1642 | if (ret < 0) |
1495 | dev_err(di->dev, "failed to disable LED\n"); | 1643 | dev_err(di->dev, "failed to disable LED\n"); |
1644 | /* USBChInputCurr: current that can be drawn from the usb */ | ||
1645 | ret = ab8500_charger_set_vbus_in_curr(di, 0); | ||
1646 | if (ret) { | ||
1647 | dev_err(di->dev, "setting USBChInputCurr failed\n"); | ||
1648 | return ret; | ||
1649 | } | ||
1496 | 1650 | ||
1651 | /* ChOutputCurentLevel: protected output current */ | ||
1652 | ret = ab8500_charger_set_output_curr(di, 0); | ||
1653 | if (ret) { | ||
1654 | dev_err(di->dev, "%s " | ||
1655 | "Failed to reset ChOutputCurentLevel\n", | ||
1656 | __func__); | ||
1657 | return ret; | ||
1658 | } | ||
1497 | di->usb.charger_online = 0; | 1659 | di->usb.charger_online = 0; |
1498 | di->usb.wd_expired = false; | 1660 | di->usb.wd_expired = false; |
1499 | 1661 | ||
@@ -1776,7 +1938,7 @@ static void ab8500_charger_ac_work(struct work_struct *work) | |||
1776 | * synchronously, we have the check if the main charger is | 1938 | * synchronously, we have the check if the main charger is |
1777 | * connected by reading the status register | 1939 | * connected by reading the status register |
1778 | */ | 1940 | */ |
1779 | ret = ab8500_charger_detect_chargers(di); | 1941 | ret = ab8500_charger_detect_chargers(di, false); |
1780 | if (ret < 0) | 1942 | if (ret < 0) |
1781 | return; | 1943 | return; |
1782 | 1944 | ||
@@ -1887,16 +2049,18 @@ static void ab8500_charger_detect_usb_type_work(struct work_struct *work) | |||
1887 | * synchronously, we have the check if is | 2049 | * synchronously, we have the check if is |
1888 | * connected by reading the status register | 2050 | * connected by reading the status register |
1889 | */ | 2051 | */ |
1890 | ret = ab8500_charger_detect_chargers(di); | 2052 | ret = ab8500_charger_detect_chargers(di, false); |
1891 | if (ret < 0) | 2053 | if (ret < 0) |
1892 | return; | 2054 | return; |
1893 | 2055 | ||
1894 | if (!(ret & USB_PW_CONN)) { | 2056 | if (!(ret & USB_PW_CONN)) { |
1895 | di->vbus_detected = 0; | 2057 | dev_dbg(di->dev, "%s di->vbus_detected = false\n", __func__); |
2058 | di->vbus_detected = false; | ||
1896 | ab8500_charger_set_usb_connected(di, false); | 2059 | ab8500_charger_set_usb_connected(di, false); |
1897 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2060 | ab8500_power_supply_changed(di, &di->usb_chg.psy); |
1898 | } else { | 2061 | } else { |
1899 | di->vbus_detected = 1; | 2062 | dev_dbg(di->dev, "%s di->vbus_detected = true\n", __func__); |
2063 | di->vbus_detected = true; | ||
1900 | 2064 | ||
1901 | if (is_ab8500_1p1_or_earlier(di->parent)) { | 2065 | if (is_ab8500_1p1_or_earlier(di->parent)) { |
1902 | ret = ab8500_charger_detect_usb_type(di); | 2066 | ret = ab8500_charger_detect_usb_type(di); |
@@ -1906,7 +2070,8 @@ static void ab8500_charger_detect_usb_type_work(struct work_struct *work) | |||
1906 | &di->usb_chg.psy); | 2070 | &di->usb_chg.psy); |
1907 | } | 2071 | } |
1908 | } else { | 2072 | } else { |
1909 | /* For ABB cut2.0 and onwards we have an IRQ, | 2073 | /* |
2074 | * For ABB cut2.0 and onwards we have an IRQ, | ||
1910 | * USB_LINK_STATUS that will be triggered when the USB | 2075 | * USB_LINK_STATUS that will be triggered when the USB |
1911 | * link status changes. The exception is USB connected | 2076 | * link status changes. The exception is USB connected |
1912 | * during startup. Then we don't get a | 2077 | * during startup. Then we don't get a |
@@ -1927,7 +2092,7 @@ static void ab8500_charger_detect_usb_type_work(struct work_struct *work) | |||
1927 | } | 2092 | } |
1928 | 2093 | ||
1929 | /** | 2094 | /** |
1930 | * ab8500_charger_usb_link_attach_work() - delayd work to detect USB type | 2095 | * ab8500_charger_usb_link_attach_work() - work to detect USB type |
1931 | * @work: pointer to the work_struct structure | 2096 | * @work: pointer to the work_struct structure |
1932 | * | 2097 | * |
1933 | * Detect the type of USB plugged | 2098 | * Detect the type of USB plugged |
@@ -1957,7 +2122,9 @@ static void ab8500_charger_usb_link_attach_work(struct work_struct *work) | |||
1957 | */ | 2122 | */ |
1958 | static void ab8500_charger_usb_link_status_work(struct work_struct *work) | 2123 | static void ab8500_charger_usb_link_status_work(struct work_struct *work) |
1959 | { | 2124 | { |
2125 | int detected_chargers; | ||
1960 | int ret; | 2126 | int ret; |
2127 | u8 val; | ||
1961 | 2128 | ||
1962 | struct ab8500_charger *di = container_of(work, | 2129 | struct ab8500_charger *di = container_of(work, |
1963 | struct ab8500_charger, usb_link_status_work); | 2130 | struct ab8500_charger, usb_link_status_work); |
@@ -1967,37 +2134,95 @@ static void ab8500_charger_usb_link_status_work(struct work_struct *work) | |||
1967 | * synchronously, we have the check if is | 2134 | * synchronously, we have the check if is |
1968 | * connected by reading the status register | 2135 | * connected by reading the status register |
1969 | */ | 2136 | */ |
1970 | ret = ab8500_charger_detect_chargers(di); | 2137 | detected_chargers = ab8500_charger_detect_chargers(di, false); |
1971 | if (ret < 0) | 2138 | if (detected_chargers < 0) |
1972 | return; | 2139 | return; |
1973 | 2140 | ||
1974 | if (!(ret & USB_PW_CONN)) { | 2141 | /* |
1975 | di->vbus_detected = 0; | 2142 | * Some chargers that breaks the USB spec is |
2143 | * identified as invalid by AB8500 and it refuse | ||
2144 | * to start the charging process. but by jumping | ||
2145 | * thru a few hoops it can be forced to start. | ||
2146 | */ | ||
2147 | ret = abx500_get_register_interruptible(di->dev, AB8500_USB, | ||
2148 | AB8500_USB_LINE_STAT_REG, &val); | ||
2149 | if (ret >= 0) | ||
2150 | dev_dbg(di->dev, "UsbLineStatus register = 0x%02x\n", val); | ||
2151 | else | ||
2152 | dev_dbg(di->dev, "Error reading USB link status\n"); | ||
2153 | |||
2154 | if (detected_chargers & USB_PW_CONN) { | ||
2155 | if (((val & AB8500_USB_LINK_STATUS) >> 3) == USB_STAT_NOT_VALID_LINK && | ||
2156 | di->invalid_charger_detect_state == 0) { | ||
2157 | dev_dbg(di->dev, "Invalid charger detected, state= 0\n"); | ||
2158 | /*Enable charger*/ | ||
2159 | abx500_mask_and_set_register_interruptible(di->dev, | ||
2160 | AB8500_CHARGER, AB8500_USBCH_CTRL1_REG, 0x01, 0x01); | ||
2161 | /*Enable charger detection*/ | ||
2162 | abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, | ||
2163 | AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x01); | ||
2164 | di->invalid_charger_detect_state = 1; | ||
2165 | /*exit and wait for new link status interrupt.*/ | ||
2166 | return; | ||
2167 | |||
2168 | } | ||
2169 | if (di->invalid_charger_detect_state == 1) { | ||
2170 | dev_dbg(di->dev, "Invalid charger detected, state= 1\n"); | ||
2171 | /*Stop charger detection*/ | ||
2172 | abx500_mask_and_set_register_interruptible(di->dev, AB8500_USB, | ||
2173 | AB8500_MCH_IPT_CURLVL_REG, 0x01, 0x00); | ||
2174 | /*Check link status*/ | ||
2175 | ret = abx500_get_register_interruptible(di->dev, AB8500_USB, | ||
2176 | AB8500_USB_LINE_STAT_REG, &val); | ||
2177 | dev_dbg(di->dev, "USB link status= 0x%02x\n", | ||
2178 | (val & AB8500_USB_LINK_STATUS) >> 3); | ||
2179 | di->invalid_charger_detect_state = 2; | ||
2180 | } | ||
2181 | } else { | ||
2182 | di->invalid_charger_detect_state = 0; | ||
2183 | } | ||
2184 | |||
2185 | if (!(detected_chargers & USB_PW_CONN)) { | ||
2186 | di->vbus_detected = false; | ||
1976 | ab8500_charger_set_usb_connected(di, false); | 2187 | ab8500_charger_set_usb_connected(di, false); |
1977 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2188 | ab8500_power_supply_changed(di, &di->usb_chg.psy); |
1978 | return; | 2189 | return; |
1979 | } | 2190 | } |
1980 | 2191 | ||
1981 | di->vbus_detected = 1; | 2192 | dev_dbg(di->dev,"%s di->vbus_detected = true\n",__func__); |
2193 | di->vbus_detected = true; | ||
1982 | ret = ab8500_charger_read_usb_type(di); | 2194 | ret = ab8500_charger_read_usb_type(di); |
1983 | if (!ret) { | 2195 | if (ret) { |
1984 | if (di->usb_device_is_unrecognised) { | 2196 | if (ret == -ENXIO) { |
1985 | dev_dbg(di->dev, | 2197 | /* No valid charger type detected */ |
1986 | "Potential Legacy Charger device. " | 2198 | ab8500_charger_set_usb_connected(di, false); |
1987 | "Delay work for %d msec for USB enum " | 2199 | ab8500_power_supply_changed(di, &di->usb_chg.psy); |
1988 | "to finish", | ||
1989 | WAIT_FOR_USB_ENUMERATION); | ||
1990 | queue_delayed_work(di->charger_wq, | ||
1991 | &di->attach_work, | ||
1992 | msecs_to_jiffies(WAIT_FOR_USB_ENUMERATION)); | ||
1993 | } else { | ||
1994 | queue_delayed_work(di->charger_wq, | ||
1995 | &di->attach_work, 0); | ||
1996 | } | 2200 | } |
1997 | } else if (ret == -ENXIO) { | 2201 | return; |
1998 | /* No valid charger type detected */ | 2202 | } |
1999 | ab8500_charger_set_usb_connected(di, false); | 2203 | |
2000 | ab8500_power_supply_changed(di, &di->usb_chg.psy); | 2204 | if (di->usb_device_is_unrecognised) { |
2205 | dev_dbg(di->dev, | ||
2206 | "Potential Legacy Charger device. " | ||
2207 | "Delay work for %d msec for USB enum " | ||
2208 | "to finish", | ||
2209 | WAIT_ACA_RID_ENUMERATION); | ||
2210 | queue_delayed_work(di->charger_wq, | ||
2211 | &di->attach_work, | ||
2212 | msecs_to_jiffies(WAIT_ACA_RID_ENUMERATION)); | ||
2213 | } else if (di->is_aca_rid == 1) { | ||
2214 | /* Only wait once */ | ||
2215 | di->is_aca_rid++; | ||
2216 | dev_dbg(di->dev, | ||
2217 | "%s Wait %d msec for USB enum to finish", | ||
2218 | __func__, WAIT_ACA_RID_ENUMERATION); | ||
2219 | queue_delayed_work(di->charger_wq, | ||
2220 | &di->attach_work, | ||
2221 | msecs_to_jiffies(WAIT_ACA_RID_ENUMERATION)); | ||
2222 | } else { | ||
2223 | queue_delayed_work(di->charger_wq, | ||
2224 | &di->attach_work, | ||
2225 | 0); | ||
2001 | } | 2226 | } |
2002 | } | 2227 | } |
2003 | 2228 | ||
@@ -2007,24 +2232,20 @@ static void ab8500_charger_usb_state_changed_work(struct work_struct *work) | |||
2007 | unsigned long flags; | 2232 | unsigned long flags; |
2008 | 2233 | ||
2009 | struct ab8500_charger *di = container_of(work, | 2234 | struct ab8500_charger *di = container_of(work, |
2010 | struct ab8500_charger, usb_state_changed_work); | 2235 | struct ab8500_charger, usb_state_changed_work.work); |
2011 | 2236 | ||
2012 | if (!di->vbus_detected) | 2237 | if (!di->vbus_detected) { |
2238 | dev_dbg(di->dev, | ||
2239 | "%s !di->vbus_detected\n", | ||
2240 | __func__); | ||
2013 | return; | 2241 | return; |
2242 | } | ||
2014 | 2243 | ||
2015 | spin_lock_irqsave(&di->usb_state.usb_lock, flags); | 2244 | spin_lock_irqsave(&di->usb_state.usb_lock, flags); |
2016 | di->usb_state.usb_changed = false; | 2245 | di->usb_state.state = di->usb_state.state_tmp; |
2246 | di->usb_state.usb_current = di->usb_state.usb_current_tmp; | ||
2017 | spin_unlock_irqrestore(&di->usb_state.usb_lock, flags); | 2247 | spin_unlock_irqrestore(&di->usb_state.usb_lock, flags); |
2018 | 2248 | ||
2019 | /* | ||
2020 | * wait for some time until you get updates from the usb stack | ||
2021 | * and negotiations are completed | ||
2022 | */ | ||
2023 | msleep(250); | ||
2024 | |||
2025 | if (di->usb_state.usb_changed) | ||
2026 | return; | ||
2027 | |||
2028 | dev_dbg(di->dev, "%s USB state: 0x%02x mA: %d\n", | 2249 | dev_dbg(di->dev, "%s USB state: 0x%02x mA: %d\n", |
2029 | __func__, di->usb_state.state, di->usb_state.usb_current); | 2250 | __func__, di->usb_state.state, di->usb_state.usb_current); |
2030 | 2251 | ||
@@ -2266,6 +2487,21 @@ static irqreturn_t ab8500_charger_mainchthprotf_handler(int irq, void *_di) | |||
2266 | return IRQ_HANDLED; | 2487 | return IRQ_HANDLED; |
2267 | } | 2488 | } |
2268 | 2489 | ||
2490 | static void ab8500_charger_vbus_drop_end_work(struct work_struct *work) | ||
2491 | { | ||
2492 | struct ab8500_charger *di = container_of(work, | ||
2493 | struct ab8500_charger, vbus_drop_end_work.work); | ||
2494 | |||
2495 | di->flags.vbus_drop_end = false; | ||
2496 | |||
2497 | /* Reset the drop counter */ | ||
2498 | abx500_set_register_interruptible(di->dev, | ||
2499 | AB8500_CHARGER, AB8500_CHARGER_CTRL, 0x01); | ||
2500 | |||
2501 | if (di->usb.charger_connected) | ||
2502 | ab8500_charger_set_vbus_in_curr(di, di->max_usb_in_curr); | ||
2503 | } | ||
2504 | |||
2269 | /** | 2505 | /** |
2270 | * ab8500_charger_vbusdetf_handler() - VBUS falling detected | 2506 | * ab8500_charger_vbusdetf_handler() - VBUS falling detected |
2271 | * @irq: interrupt number | 2507 | * @irq: interrupt number |
@@ -2277,6 +2513,7 @@ static irqreturn_t ab8500_charger_vbusdetf_handler(int irq, void *_di) | |||
2277 | { | 2513 | { |
2278 | struct ab8500_charger *di = _di; | 2514 | struct ab8500_charger *di = _di; |
2279 | 2515 | ||
2516 | di->vbus_detected = false; | ||
2280 | dev_dbg(di->dev, "VBUS falling detected\n"); | 2517 | dev_dbg(di->dev, "VBUS falling detected\n"); |
2281 | queue_work(di->charger_wq, &di->detect_usb_type_work); | 2518 | queue_work(di->charger_wq, &di->detect_usb_type_work); |
2282 | 2519 | ||
@@ -2296,6 +2533,7 @@ static irqreturn_t ab8500_charger_vbusdetr_handler(int irq, void *_di) | |||
2296 | 2533 | ||
2297 | di->vbus_detected = true; | 2534 | di->vbus_detected = true; |
2298 | dev_dbg(di->dev, "VBUS rising detected\n"); | 2535 | dev_dbg(di->dev, "VBUS rising detected\n"); |
2536 | |||
2299 | queue_work(di->charger_wq, &di->detect_usb_type_work); | 2537 | queue_work(di->charger_wq, &di->detect_usb_type_work); |
2300 | 2538 | ||
2301 | return IRQ_HANDLED; | 2539 | return IRQ_HANDLED; |
@@ -2404,6 +2642,25 @@ static irqreturn_t ab8500_charger_chwdexp_handler(int irq, void *_di) | |||
2404 | } | 2642 | } |
2405 | 2643 | ||
2406 | /** | 2644 | /** |
2645 | * ab8500_charger_vbuschdropend_handler() - VBUS drop removed | ||
2646 | * @irq: interrupt number | ||
2647 | * @_di: pointer to the ab8500_charger structure | ||
2648 | * | ||
2649 | * Returns IRQ status(IRQ_HANDLED) | ||
2650 | */ | ||
2651 | static irqreturn_t ab8500_charger_vbuschdropend_handler(int irq, void *_di) | ||
2652 | { | ||
2653 | struct ab8500_charger *di = _di; | ||
2654 | |||
2655 | dev_dbg(di->dev, "VBUS charger drop ended\n"); | ||
2656 | di->flags.vbus_drop_end = true; | ||
2657 | queue_delayed_work(di->charger_wq, &di->vbus_drop_end_work, | ||
2658 | round_jiffies(30 * HZ)); | ||
2659 | |||
2660 | return IRQ_HANDLED; | ||
2661 | } | ||
2662 | |||
2663 | /** | ||
2407 | * ab8500_charger_vbusovv_handler() - VBUS overvoltage detected | 2664 | * ab8500_charger_vbusovv_handler() - VBUS overvoltage detected |
2408 | * @irq: interrupt number | 2665 | * @irq: interrupt number |
2409 | * @_di: pointer to the ab8500_charger structure | 2666 | * @_di: pointer to the ab8500_charger structure |
@@ -2601,13 +2858,23 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | |||
2601 | } | 2858 | } |
2602 | } | 2859 | } |
2603 | 2860 | ||
2604 | /* VBUS OVV set to 6.3V and enable automatic current limitiation */ | 2861 | if (is_ab9540_2p0(di->parent) || is_ab8505_2p0(di->parent)) |
2605 | ret = abx500_set_register_interruptible(di->dev, | 2862 | ret = abx500_mask_and_set_register_interruptible(di->dev, |
2606 | AB8500_CHARGER, | 2863 | AB8500_CHARGER, |
2607 | AB8500_USBCH_CTRL2_REG, | 2864 | AB8500_USBCH_CTRL2_REG, |
2608 | VBUS_OVV_SELECT_6P3V | VBUS_AUTO_IN_CURR_LIM_ENA); | 2865 | VBUS_AUTO_IN_CURR_LIM_ENA, |
2866 | VBUS_AUTO_IN_CURR_LIM_ENA); | ||
2867 | else | ||
2868 | /* | ||
2869 | * VBUS OVV set to 6.3V and enable automatic current limitation | ||
2870 | */ | ||
2871 | ret = abx500_set_register_interruptible(di->dev, | ||
2872 | AB8500_CHARGER, | ||
2873 | AB8500_USBCH_CTRL2_REG, | ||
2874 | VBUS_OVV_SELECT_6P3V | VBUS_AUTO_IN_CURR_LIM_ENA); | ||
2609 | if (ret) { | 2875 | if (ret) { |
2610 | dev_err(di->dev, "failed to set VBUS OVV\n"); | 2876 | dev_err(di->dev, |
2877 | "failed to set automatic current limitation\n"); | ||
2611 | goto out; | 2878 | goto out; |
2612 | } | 2879 | } |
2613 | 2880 | ||
@@ -2663,6 +2930,20 @@ static int ab8500_charger_init_hw_registers(struct ab8500_charger *di) | |||
2663 | goto out; | 2930 | goto out; |
2664 | } | 2931 | } |
2665 | 2932 | ||
2933 | /* Set charger watchdog timeout */ | ||
2934 | ret = abx500_set_register_interruptible(di->dev, AB8500_CHARGER, | ||
2935 | AB8500_CH_WD_TIMER_REG, WD_TIMER); | ||
2936 | if (ret) { | ||
2937 | dev_err(di->dev, "failed to set charger watchdog timeout\n"); | ||
2938 | goto out; | ||
2939 | } | ||
2940 | |||
2941 | ret = ab8500_charger_led_en(di, false); | ||
2942 | if (ret < 0) { | ||
2943 | dev_err(di->dev, "failed to disable LED\n"); | ||
2944 | goto out; | ||
2945 | } | ||
2946 | |||
2666 | /* Backup battery voltage and current */ | 2947 | /* Backup battery voltage and current */ |
2667 | ret = abx500_set_register_interruptible(di->dev, | 2948 | ret = abx500_set_register_interruptible(di->dev, |
2668 | AB8500_RTC, | 2949 | AB8500_RTC, |
@@ -2702,6 +2983,7 @@ static struct ab8500_charger_interrupts ab8500_charger_irq[] = { | |||
2702 | {"USB_CHARGER_NOT_OKR", ab8500_charger_usbchargernotokr_handler}, | 2983 | {"USB_CHARGER_NOT_OKR", ab8500_charger_usbchargernotokr_handler}, |
2703 | {"VBUS_OVV", ab8500_charger_vbusovv_handler}, | 2984 | {"VBUS_OVV", ab8500_charger_vbusovv_handler}, |
2704 | {"CH_WD_EXP", ab8500_charger_chwdexp_handler}, | 2985 | {"CH_WD_EXP", ab8500_charger_chwdexp_handler}, |
2986 | {"VBUS_CH_DROP_END", ab8500_charger_vbuschdropend_handler}, | ||
2705 | }; | 2987 | }; |
2706 | 2988 | ||
2707 | static int ab8500_charger_usb_notifier_call(struct notifier_block *nb, | 2989 | static int ab8500_charger_usb_notifier_call(struct notifier_block *nb, |
@@ -2712,6 +2994,9 @@ static int ab8500_charger_usb_notifier_call(struct notifier_block *nb, | |||
2712 | enum ab8500_usb_state bm_usb_state; | 2994 | enum ab8500_usb_state bm_usb_state; |
2713 | unsigned mA = *((unsigned *)power); | 2995 | unsigned mA = *((unsigned *)power); |
2714 | 2996 | ||
2997 | if (!di) | ||
2998 | return NOTIFY_DONE; | ||
2999 | |||
2715 | if (event != USB_EVENT_VBUS) { | 3000 | if (event != USB_EVENT_VBUS) { |
2716 | dev_dbg(di->dev, "not a standard host, returning\n"); | 3001 | dev_dbg(di->dev, "not a standard host, returning\n"); |
2717 | return NOTIFY_DONE; | 3002 | return NOTIFY_DONE; |
@@ -2735,13 +3020,15 @@ static int ab8500_charger_usb_notifier_call(struct notifier_block *nb, | |||
2735 | __func__, bm_usb_state, mA); | 3020 | __func__, bm_usb_state, mA); |
2736 | 3021 | ||
2737 | spin_lock(&di->usb_state.usb_lock); | 3022 | spin_lock(&di->usb_state.usb_lock); |
2738 | di->usb_state.usb_changed = true; | 3023 | di->usb_state.state_tmp = bm_usb_state; |
3024 | di->usb_state.usb_current_tmp = mA; | ||
2739 | spin_unlock(&di->usb_state.usb_lock); | 3025 | spin_unlock(&di->usb_state.usb_lock); |
2740 | 3026 | ||
2741 | di->usb_state.state = bm_usb_state; | 3027 | /* |
2742 | di->usb_state.usb_current = mA; | 3028 | * wait for some time until you get updates from the usb stack |
2743 | 3029 | * and negotiations are completed | |
2744 | queue_work(di->charger_wq, &di->usb_state_changed_work); | 3030 | */ |
3031 | queue_delayed_work(di->charger_wq, &di->usb_state_changed_work, HZ/2); | ||
2745 | 3032 | ||
2746 | return NOTIFY_OK; | 3033 | return NOTIFY_OK; |
2747 | } | 3034 | } |
@@ -2781,6 +3068,9 @@ static int ab8500_charger_resume(struct platform_device *pdev) | |||
2781 | &di->check_hw_failure_work, 0); | 3068 | &di->check_hw_failure_work, 0); |
2782 | } | 3069 | } |
2783 | 3070 | ||
3071 | if (di->flags.vbus_drop_end) | ||
3072 | queue_delayed_work(di->charger_wq, &di->vbus_drop_end_work, 0); | ||
3073 | |||
2784 | return 0; | 3074 | return 0; |
2785 | } | 3075 | } |
2786 | 3076 | ||
@@ -2793,6 +3083,23 @@ static int ab8500_charger_suspend(struct platform_device *pdev, | |||
2793 | if (delayed_work_pending(&di->check_hw_failure_work)) | 3083 | if (delayed_work_pending(&di->check_hw_failure_work)) |
2794 | cancel_delayed_work(&di->check_hw_failure_work); | 3084 | cancel_delayed_work(&di->check_hw_failure_work); |
2795 | 3085 | ||
3086 | if (delayed_work_pending(&di->vbus_drop_end_work)) | ||
3087 | cancel_delayed_work(&di->vbus_drop_end_work); | ||
3088 | |||
3089 | flush_delayed_work(&di->attach_work); | ||
3090 | flush_delayed_work(&di->usb_charger_attached_work); | ||
3091 | flush_delayed_work(&di->ac_charger_attached_work); | ||
3092 | flush_delayed_work(&di->check_usbchgnotok_work); | ||
3093 | flush_delayed_work(&di->check_vbat_work); | ||
3094 | flush_delayed_work(&di->kick_wd_work); | ||
3095 | |||
3096 | flush_work(&di->usb_link_status_work); | ||
3097 | flush_work(&di->ac_work); | ||
3098 | flush_work(&di->detect_usb_type_work); | ||
3099 | |||
3100 | if (atomic_read(&di->current_stepping_sessions)) | ||
3101 | return -EAGAIN; | ||
3102 | |||
2796 | return 0; | 3103 | return 0; |
2797 | } | 3104 | } |
2798 | #else | 3105 | #else |
@@ -2830,8 +3137,12 @@ static int ab8500_charger_remove(struct platform_device *pdev) | |||
2830 | destroy_workqueue(di->charger_wq); | 3137 | destroy_workqueue(di->charger_wq); |
2831 | 3138 | ||
2832 | flush_scheduled_work(); | 3139 | flush_scheduled_work(); |
2833 | power_supply_unregister(&di->usb_chg.psy); | 3140 | if(di->usb_chg.enabled) |
2834 | power_supply_unregister(&di->ac_chg.psy); | 3141 | power_supply_unregister(&di->usb_chg.psy); |
3142 | #if !defined(CONFIG_CHARGER_PM2301) | ||
3143 | if(di->ac_chg.enabled) | ||
3144 | power_supply_unregister(&di->ac_chg.psy); | ||
3145 | #endif | ||
2835 | platform_set_drvdata(pdev, NULL); | 3146 | platform_set_drvdata(pdev, NULL); |
2836 | 3147 | ||
2837 | return 0; | 3148 | return 0; |
@@ -2879,8 +3190,10 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
2879 | 3190 | ||
2880 | /* initialize lock */ | 3191 | /* initialize lock */ |
2881 | spin_lock_init(&di->usb_state.usb_lock); | 3192 | spin_lock_init(&di->usb_state.usb_lock); |
3193 | mutex_init(&di->usb_ipt_crnt_lock); | ||
2882 | 3194 | ||
2883 | di->autopower = false; | 3195 | di->autopower = false; |
3196 | di->invalid_charger_detect_state = 0; | ||
2884 | 3197 | ||
2885 | /* AC supply */ | 3198 | /* AC supply */ |
2886 | /* power_supply base class */ | 3199 | /* power_supply base class */ |
@@ -2899,6 +3212,9 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
2899 | ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; | 3212 | ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; |
2900 | di->ac_chg.max_out_curr = ab8500_charger_current_map[ | 3213 | di->ac_chg.max_out_curr = ab8500_charger_current_map[ |
2901 | ARRAY_SIZE(ab8500_charger_current_map) - 1]; | 3214 | ARRAY_SIZE(ab8500_charger_current_map) - 1]; |
3215 | di->ac_chg.wdt_refresh = CHG_WD_INTERVAL; | ||
3216 | di->ac_chg.enabled = di->bm->ac_enabled; | ||
3217 | di->ac_chg.external = false; | ||
2902 | 3218 | ||
2903 | /* USB supply */ | 3219 | /* USB supply */ |
2904 | /* power_supply base class */ | 3220 | /* power_supply base class */ |
@@ -2917,7 +3233,9 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
2917 | ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; | 3233 | ARRAY_SIZE(ab8500_charger_voltage_map) - 1]; |
2918 | di->usb_chg.max_out_curr = ab8500_charger_current_map[ | 3234 | di->usb_chg.max_out_curr = ab8500_charger_current_map[ |
2919 | ARRAY_SIZE(ab8500_charger_current_map) - 1]; | 3235 | ARRAY_SIZE(ab8500_charger_current_map) - 1]; |
2920 | 3236 | di->usb_chg.wdt_refresh = CHG_WD_INTERVAL; | |
3237 | di->usb_chg.enabled = di->bm->usb_enabled; | ||
3238 | di->usb_chg.external = false; | ||
2921 | 3239 | ||
2922 | /* Create a work queue for the charger */ | 3240 | /* Create a work queue for the charger */ |
2923 | di->charger_wq = | 3241 | di->charger_wq = |
@@ -2958,6 +3276,12 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
2958 | INIT_DELAYED_WORK(&di->attach_work, | 3276 | INIT_DELAYED_WORK(&di->attach_work, |
2959 | ab8500_charger_usb_link_attach_work); | 3277 | ab8500_charger_usb_link_attach_work); |
2960 | 3278 | ||
3279 | INIT_DELAYED_WORK(&di->usb_state_changed_work, | ||
3280 | ab8500_charger_usb_state_changed_work); | ||
3281 | |||
3282 | INIT_DELAYED_WORK(&di->vbus_drop_end_work, | ||
3283 | ab8500_charger_vbus_drop_end_work); | ||
3284 | |||
2961 | /* Init work for charger detection */ | 3285 | /* Init work for charger detection */ |
2962 | INIT_WORK(&di->usb_link_status_work, | 3286 | INIT_WORK(&di->usb_link_status_work, |
2963 | ab8500_charger_usb_link_status_work); | 3287 | ab8500_charger_usb_link_status_work); |
@@ -2965,9 +3289,6 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
2965 | INIT_WORK(&di->detect_usb_type_work, | 3289 | INIT_WORK(&di->detect_usb_type_work, |
2966 | ab8500_charger_detect_usb_type_work); | 3290 | ab8500_charger_detect_usb_type_work); |
2967 | 3291 | ||
2968 | INIT_WORK(&di->usb_state_changed_work, | ||
2969 | ab8500_charger_usb_state_changed_work); | ||
2970 | |||
2971 | /* Init work for checking HW status */ | 3292 | /* Init work for checking HW status */ |
2972 | INIT_WORK(&di->check_main_thermal_prot_work, | 3293 | INIT_WORK(&di->check_main_thermal_prot_work, |
2973 | ab8500_charger_check_main_thermal_prot_work); | 3294 | ab8500_charger_check_main_thermal_prot_work); |
@@ -2995,17 +3316,21 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
2995 | } | 3316 | } |
2996 | 3317 | ||
2997 | /* Register AC charger class */ | 3318 | /* Register AC charger class */ |
2998 | ret = power_supply_register(di->dev, &di->ac_chg.psy); | 3319 | if(di->ac_chg.enabled) { |
2999 | if (ret) { | 3320 | ret = power_supply_register(di->dev, &di->ac_chg.psy); |
3000 | dev_err(di->dev, "failed to register AC charger\n"); | 3321 | if (ret) { |
3001 | goto free_charger_wq; | 3322 | dev_err(di->dev, "failed to register AC charger\n"); |
3323 | goto free_charger_wq; | ||
3324 | } | ||
3002 | } | 3325 | } |
3003 | 3326 | ||
3004 | /* Register USB charger class */ | 3327 | /* Register USB charger class */ |
3005 | ret = power_supply_register(di->dev, &di->usb_chg.psy); | 3328 | if(di->usb_chg.enabled) { |
3006 | if (ret) { | 3329 | ret = power_supply_register(di->dev, &di->usb_chg.psy); |
3007 | dev_err(di->dev, "failed to register USB charger\n"); | 3330 | if (ret) { |
3008 | goto free_ac; | 3331 | dev_err(di->dev, "failed to register USB charger\n"); |
3332 | goto free_ac; | ||
3333 | } | ||
3009 | } | 3334 | } |
3010 | 3335 | ||
3011 | di->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2); | 3336 | di->usb_phy = usb_get_phy(USB_PHY_TYPE_USB2); |
@@ -3022,7 +3347,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
3022 | } | 3347 | } |
3023 | 3348 | ||
3024 | /* Identify the connected charger types during startup */ | 3349 | /* Identify the connected charger types during startup */ |
3025 | charger_status = ab8500_charger_detect_chargers(di); | 3350 | charger_status = ab8500_charger_detect_chargers(di, true); |
3026 | if (charger_status & AC_PW_CONN) { | 3351 | if (charger_status & AC_PW_CONN) { |
3027 | di->ac.charger_connected = 1; | 3352 | di->ac.charger_connected = 1; |
3028 | di->ac_conn = true; | 3353 | di->ac_conn = true; |
@@ -3057,7 +3382,7 @@ static int ab8500_charger_probe(struct platform_device *pdev) | |||
3057 | 3382 | ||
3058 | mutex_lock(&di->charger_attached_mutex); | 3383 | mutex_lock(&di->charger_attached_mutex); |
3059 | 3384 | ||
3060 | ch_stat = ab8500_charger_detect_chargers(di); | 3385 | ch_stat = ab8500_charger_detect_chargers(di, false); |
3061 | 3386 | ||
3062 | if ((ch_stat & AC_PW_CONN) == AC_PW_CONN) { | 3387 | if ((ch_stat & AC_PW_CONN) == AC_PW_CONN) { |
3063 | queue_delayed_work(di->charger_wq, | 3388 | queue_delayed_work(di->charger_wq, |
@@ -3085,9 +3410,11 @@ free_irq: | |||
3085 | put_usb_phy: | 3410 | put_usb_phy: |
3086 | usb_put_phy(di->usb_phy); | 3411 | usb_put_phy(di->usb_phy); |
3087 | free_usb: | 3412 | free_usb: |
3088 | power_supply_unregister(&di->usb_chg.psy); | 3413 | if(di->usb_chg.enabled) |
3414 | power_supply_unregister(&di->usb_chg.psy); | ||
3089 | free_ac: | 3415 | free_ac: |
3090 | power_supply_unregister(&di->ac_chg.psy); | 3416 | if(di->ac_chg.enabled) |
3417 | power_supply_unregister(&di->ac_chg.psy); | ||
3091 | free_charger_wq: | 3418 | free_charger_wq: |
3092 | destroy_workqueue(di->charger_wq); | 3419 | destroy_workqueue(di->charger_wq); |
3093 | return ret; | 3420 | return ret; |
diff --git a/drivers/power/ab8500_fg.c b/drivers/power/ab8500_fg.c index cd03549b6227..25dae4c4b0ef 100644 --- a/drivers/power/ab8500_fg.c +++ b/drivers/power/ab8500_fg.c | |||
@@ -43,7 +43,7 @@ | |||
43 | 43 | ||
44 | #define NBR_AVG_SAMPLES 20 | 44 | #define NBR_AVG_SAMPLES 20 |
45 | 45 | ||
46 | #define LOW_BAT_CHECK_INTERVAL (2 * HZ) | 46 | #define LOW_BAT_CHECK_INTERVAL (HZ / 16) /* 62.5 ms */ |
47 | 47 | ||
48 | #define VALID_CAPACITY_SEC (45 * 60) /* 45 minutes */ | 48 | #define VALID_CAPACITY_SEC (45 * 60) /* 45 minutes */ |
49 | #define BATT_OK_MIN 2360 /* mV */ | 49 | #define BATT_OK_MIN 2360 /* mV */ |
@@ -169,6 +169,7 @@ struct inst_curr_result_list { | |||
169 | * @recovery_cnt: Counter for recovery mode | 169 | * @recovery_cnt: Counter for recovery mode |
170 | * @high_curr_cnt: Counter for high current mode | 170 | * @high_curr_cnt: Counter for high current mode |
171 | * @init_cnt: Counter for init mode | 171 | * @init_cnt: Counter for init mode |
172 | * @low_bat_cnt Counter for number of consecutive low battery measures | ||
172 | * @nbr_cceoc_irq_cnt Counter for number of CCEOC irqs received since enabled | 173 | * @nbr_cceoc_irq_cnt Counter for number of CCEOC irqs received since enabled |
173 | * @recovery_needed: Indicate if recovery is needed | 174 | * @recovery_needed: Indicate if recovery is needed |
174 | * @high_curr_mode: Indicate if we're in high current mode | 175 | * @high_curr_mode: Indicate if we're in high current mode |
@@ -210,6 +211,7 @@ struct ab8500_fg { | |||
210 | int recovery_cnt; | 211 | int recovery_cnt; |
211 | int high_curr_cnt; | 212 | int high_curr_cnt; |
212 | int init_cnt; | 213 | int init_cnt; |
214 | int low_bat_cnt; | ||
213 | int nbr_cceoc_irq_cnt; | 215 | int nbr_cceoc_irq_cnt; |
214 | bool recovery_needed; | 216 | bool recovery_needed; |
215 | bool high_curr_mode; | 217 | bool high_curr_mode; |
@@ -1639,7 +1641,7 @@ static void ab8500_fg_algorithm_discharging(struct ab8500_fg *di) | |||
1639 | 1641 | ||
1640 | if (di->recovery_needed) { | 1642 | if (di->recovery_needed) { |
1641 | ab8500_fg_discharge_state_to(di, | 1643 | ab8500_fg_discharge_state_to(di, |
1642 | AB8500_FG_DISCHARGE_RECOVERY); | 1644 | AB8500_FG_DISCHARGE_INIT_RECOVERY); |
1643 | 1645 | ||
1644 | queue_delayed_work(di->fg_wq, | 1646 | queue_delayed_work(di->fg_wq, |
1645 | &di->fg_periodic_work, 0); | 1647 | &di->fg_periodic_work, 0); |
@@ -1879,25 +1881,29 @@ static void ab8500_fg_low_bat_work(struct work_struct *work) | |||
1879 | 1881 | ||
1880 | /* Check if LOW_BAT still fulfilled */ | 1882 | /* Check if LOW_BAT still fulfilled */ |
1881 | if (vbat < di->bm->fg_params->lowbat_threshold) { | 1883 | if (vbat < di->bm->fg_params->lowbat_threshold) { |
1882 | di->flags.low_bat = true; | 1884 | /* Is it time to shut down? */ |
1883 | dev_warn(di->dev, "Battery voltage still LOW\n"); | 1885 | if (di->low_bat_cnt < 1) { |
1884 | 1886 | di->flags.low_bat = true; | |
1885 | /* | 1887 | dev_warn(di->dev, "Shut down pending...\n"); |
1886 | * We need to re-schedule this check to be able to detect | 1888 | } else { |
1887 | * if the voltage increases again during charging | 1889 | /* |
1888 | */ | 1890 | * Else we need to re-schedule this check to be able to detect |
1889 | queue_delayed_work(di->fg_wq, &di->fg_low_bat_work, | 1891 | * if the voltage increases again during charging or |
1890 | round_jiffies(LOW_BAT_CHECK_INTERVAL)); | 1892 | * due to decreasing load. |
1893 | */ | ||
1894 | di->low_bat_cnt--; | ||
1895 | dev_warn(di->dev, "Battery voltage still LOW\n"); | ||
1896 | queue_delayed_work(di->fg_wq, &di->fg_low_bat_work, | ||
1897 | round_jiffies(LOW_BAT_CHECK_INTERVAL)); | ||
1898 | } | ||
1891 | } else { | 1899 | } else { |
1892 | di->flags.low_bat = false; | 1900 | di->flags.low_bat_delay = false; |
1901 | di->low_bat_cnt = 10; | ||
1893 | dev_warn(di->dev, "Battery voltage OK again\n"); | 1902 | dev_warn(di->dev, "Battery voltage OK again\n"); |
1894 | } | 1903 | } |
1895 | 1904 | ||
1896 | /* This is needed to dispatch LOW_BAT */ | 1905 | /* This is needed to dispatch LOW_BAT */ |
1897 | ab8500_fg_check_capacity_limits(di, false); | 1906 | ab8500_fg_check_capacity_limits(di, false); |
1898 | |||
1899 | /* Set this flag to check if LOW_BAT IRQ still occurs */ | ||
1900 | di->flags.low_bat_delay = false; | ||
1901 | } | 1907 | } |
1902 | 1908 | ||
1903 | /** | 1909 | /** |
@@ -2056,6 +2062,7 @@ static irqreturn_t ab8500_fg_lowbatf_handler(int irq, void *_di) | |||
2056 | { | 2062 | { |
2057 | struct ab8500_fg *di = _di; | 2063 | struct ab8500_fg *di = _di; |
2058 | 2064 | ||
2065 | /* Initiate handling in ab8500_fg_low_bat_work() if not already initiated. */ | ||
2059 | if (!di->flags.low_bat_delay) { | 2066 | if (!di->flags.low_bat_delay) { |
2060 | dev_warn(di->dev, "Battery voltage is below LOW threshold\n"); | 2067 | dev_warn(di->dev, "Battery voltage is below LOW threshold\n"); |
2061 | di->flags.low_bat_delay = true; | 2068 | di->flags.low_bat_delay = true; |
@@ -2243,7 +2250,8 @@ static int ab8500_fg_get_ext_psy_data(struct device *dev, void *data) | |||
2243 | case POWER_SUPPLY_PROP_TECHNOLOGY: | 2250 | case POWER_SUPPLY_PROP_TECHNOLOGY: |
2244 | switch (ext->type) { | 2251 | switch (ext->type) { |
2245 | case POWER_SUPPLY_TYPE_BATTERY: | 2252 | case POWER_SUPPLY_TYPE_BATTERY: |
2246 | if (!di->flags.batt_id_received) { | 2253 | if (!di->flags.batt_id_received && |
2254 | di->bm->batt_id != BATTERY_UNKNOWN) { | ||
2247 | const struct abx500_battery_type *b; | 2255 | const struct abx500_battery_type *b; |
2248 | 2256 | ||
2249 | b = &(di->bm->bat_type[di->bm->batt_id]); | 2257 | b = &(di->bm->bat_type[di->bm->batt_id]); |
@@ -2563,6 +2571,11 @@ static int ab8500_fg_suspend(struct platform_device *pdev, | |||
2563 | struct ab8500_fg *di = platform_get_drvdata(pdev); | 2571 | struct ab8500_fg *di = platform_get_drvdata(pdev); |
2564 | 2572 | ||
2565 | flush_delayed_work(&di->fg_periodic_work); | 2573 | flush_delayed_work(&di->fg_periodic_work); |
2574 | flush_work(&di->fg_work); | ||
2575 | flush_work(&di->fg_acc_cur_work); | ||
2576 | flush_delayed_work(&di->fg_reinit_work); | ||
2577 | flush_delayed_work(&di->fg_low_bat_work); | ||
2578 | flush_delayed_work(&di->fg_check_hw_failure_work); | ||
2566 | 2579 | ||
2567 | /* | 2580 | /* |
2568 | * If the FG is enabled we will disable it before going to suspend | 2581 | * If the FG is enabled we will disable it before going to suspend |
@@ -2698,6 +2711,12 @@ static int ab8500_fg_probe(struct platform_device *pdev) | |||
2698 | INIT_DEFERRABLE_WORK(&di->fg_check_hw_failure_work, | 2711 | INIT_DEFERRABLE_WORK(&di->fg_check_hw_failure_work, |
2699 | ab8500_fg_check_hw_failure_work); | 2712 | ab8500_fg_check_hw_failure_work); |
2700 | 2713 | ||
2714 | /* Reset battery low voltage flag */ | ||
2715 | di->flags.low_bat = false; | ||
2716 | |||
2717 | /* Initialize low battery counter */ | ||
2718 | di->low_bat_cnt = 10; | ||
2719 | |||
2701 | /* Initialize OVV, and other registers */ | 2720 | /* Initialize OVV, and other registers */ |
2702 | ret = ab8500_fg_init_hw_registers(di); | 2721 | ret = ab8500_fg_init_hw_registers(di); |
2703 | if (ret) { | 2722 | if (ret) { |
diff --git a/drivers/power/abx500_chargalg.c b/drivers/power/abx500_chargalg.c index 78b623572b52..f043c0851a76 100644 --- a/drivers/power/abx500_chargalg.c +++ b/drivers/power/abx500_chargalg.c | |||
@@ -445,8 +445,18 @@ static int abx500_chargalg_kick_watchdog(struct abx500_chargalg *di) | |||
445 | { | 445 | { |
446 | /* Check if charger exists and kick watchdog if charging */ | 446 | /* Check if charger exists and kick watchdog if charging */ |
447 | if (di->ac_chg && di->ac_chg->ops.kick_wd && | 447 | if (di->ac_chg && di->ac_chg->ops.kick_wd && |
448 | di->chg_info.online_chg & AC_CHG) | 448 | di->chg_info.online_chg & AC_CHG) { |
449 | /* | ||
450 | * If AB charger watchdog expired, pm2xxx charging | ||
451 | * gets disabled. To be safe, kick both AB charger watchdog | ||
452 | * and pm2xxx watchdog. | ||
453 | */ | ||
454 | if (di->ac_chg->external && | ||
455 | di->usb_chg && di->usb_chg->ops.kick_wd) | ||
456 | di->usb_chg->ops.kick_wd(di->usb_chg); | ||
457 | |||
449 | return di->ac_chg->ops.kick_wd(di->ac_chg); | 458 | return di->ac_chg->ops.kick_wd(di->ac_chg); |
459 | } | ||
450 | else if (di->usb_chg && di->usb_chg->ops.kick_wd && | 460 | else if (di->usb_chg && di->usb_chg->ops.kick_wd && |
451 | di->chg_info.online_chg & USB_CHG) | 461 | di->chg_info.online_chg & USB_CHG) |
452 | return di->usb_chg->ops.kick_wd(di->usb_chg); | 462 | return di->usb_chg->ops.kick_wd(di->usb_chg); |
@@ -603,6 +613,8 @@ static void abx500_chargalg_hold_charging(struct abx500_chargalg *di) | |||
603 | static void abx500_chargalg_start_charging(struct abx500_chargalg *di, | 613 | static void abx500_chargalg_start_charging(struct abx500_chargalg *di, |
604 | int vset, int iset) | 614 | int vset, int iset) |
605 | { | 615 | { |
616 | bool start_chargalg_wd = true; | ||
617 | |||
606 | switch (di->chg_info.charger_type) { | 618 | switch (di->chg_info.charger_type) { |
607 | case AC_CHG: | 619 | case AC_CHG: |
608 | dev_dbg(di->dev, | 620 | dev_dbg(di->dev, |
@@ -620,8 +632,12 @@ static void abx500_chargalg_start_charging(struct abx500_chargalg *di, | |||
620 | 632 | ||
621 | default: | 633 | default: |
622 | dev_err(di->dev, "Unknown charger to charge from\n"); | 634 | dev_err(di->dev, "Unknown charger to charge from\n"); |
635 | start_chargalg_wd = false; | ||
623 | break; | 636 | break; |
624 | } | 637 | } |
638 | |||
639 | if (start_chargalg_wd && !delayed_work_pending(&di->chargalg_wd_work)) | ||
640 | queue_delayed_work(di->chargalg_wq, &di->chargalg_wd_work, 0); | ||
625 | } | 641 | } |
626 | 642 | ||
627 | /** | 643 | /** |
@@ -1622,6 +1638,9 @@ static int abx500_chargalg_get_property(struct power_supply *psy, | |||
1622 | val->intval = POWER_SUPPLY_HEALTH_COLD; | 1638 | val->intval = POWER_SUPPLY_HEALTH_COLD; |
1623 | else | 1639 | else |
1624 | val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; | 1640 | val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; |
1641 | } else if (di->charge_state == STATE_SAFETY_TIMER_EXPIRED || | ||
1642 | di->charge_state == STATE_SAFETY_TIMER_EXPIRED_INIT) { | ||
1643 | val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; | ||
1625 | } else { | 1644 | } else { |
1626 | val->intval = POWER_SUPPLY_HEALTH_GOOD; | 1645 | val->intval = POWER_SUPPLY_HEALTH_GOOD; |
1627 | } | 1646 | } |
@@ -1635,6 +1654,25 @@ static int abx500_chargalg_get_property(struct power_supply *psy, | |||
1635 | /* Exposure to the sysfs interface */ | 1654 | /* Exposure to the sysfs interface */ |
1636 | 1655 | ||
1637 | /** | 1656 | /** |
1657 | * abx500_chargalg_sysfs_show() - sysfs show operations | ||
1658 | * @kobj: pointer to the struct kobject | ||
1659 | * @attr: pointer to the struct attribute | ||
1660 | * @buf: buffer that holds the parameter to send to userspace | ||
1661 | * | ||
1662 | * Returns a buffer to be displayed in user space | ||
1663 | */ | ||
1664 | static ssize_t abx500_chargalg_sysfs_show(struct kobject *kobj, | ||
1665 | struct attribute *attr, char *buf) | ||
1666 | { | ||
1667 | struct abx500_chargalg *di = container_of(kobj, | ||
1668 | struct abx500_chargalg, chargalg_kobject); | ||
1669 | |||
1670 | return sprintf(buf, "%d\n", | ||
1671 | di->susp_status.ac_suspended && | ||
1672 | di->susp_status.usb_suspended); | ||
1673 | } | ||
1674 | |||
1675 | /** | ||
1638 | * abx500_chargalg_sysfs_charger() - sysfs store operations | 1676 | * abx500_chargalg_sysfs_charger() - sysfs store operations |
1639 | * @kobj: pointer to the struct kobject | 1677 | * @kobj: pointer to the struct kobject |
1640 | * @attr: pointer to the struct attribute | 1678 | * @attr: pointer to the struct attribute |
@@ -1702,7 +1740,7 @@ static ssize_t abx500_chargalg_sysfs_charger(struct kobject *kobj, | |||
1702 | static struct attribute abx500_chargalg_en_charger = \ | 1740 | static struct attribute abx500_chargalg_en_charger = \ |
1703 | { | 1741 | { |
1704 | .name = "chargalg", | 1742 | .name = "chargalg", |
1705 | .mode = S_IWUGO, | 1743 | .mode = S_IRUGO | S_IWUSR, |
1706 | }; | 1744 | }; |
1707 | 1745 | ||
1708 | static struct attribute *abx500_chargalg_chg[] = { | 1746 | static struct attribute *abx500_chargalg_chg[] = { |
@@ -1711,6 +1749,7 @@ static struct attribute *abx500_chargalg_chg[] = { | |||
1711 | }; | 1749 | }; |
1712 | 1750 | ||
1713 | static const struct sysfs_ops abx500_chargalg_sysfs_ops = { | 1751 | static const struct sysfs_ops abx500_chargalg_sysfs_ops = { |
1752 | .show = abx500_chargalg_sysfs_show, | ||
1714 | .store = abx500_chargalg_sysfs_charger, | 1753 | .store = abx500_chargalg_sysfs_charger, |
1715 | }; | 1754 | }; |
1716 | 1755 | ||
diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c new file mode 100644 index 000000000000..ed48d75bb786 --- /dev/null +++ b/drivers/power/pm2301_charger.c | |||
@@ -0,0 +1,1088 @@ | |||
1 | /* | ||
2 | * Copyright 2012 ST Ericsson. | ||
3 | * | ||
4 | * Power supply driver for ST Ericsson pm2xxx_charger charger | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/slab.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | #include <linux/power_supply.h> | ||
19 | #include <linux/completion.h> | ||
20 | #include <linux/regulator/consumer.h> | ||
21 | #include <linux/err.h> | ||
22 | #include <linux/i2c.h> | ||
23 | #include <linux/workqueue.h> | ||
24 | #include <linux/kobject.h> | ||
25 | #include <linux/mfd/abx500.h> | ||
26 | #include <linux/mfd/abx500/ab8500.h> | ||
27 | #include <linux/mfd/abx500/ab8500-bm.h> | ||
28 | #include <linux/mfd/abx500/ab8500-gpadc.h> | ||
29 | #include <linux/mfd/abx500/ux500_chargalg.h> | ||
30 | #include <linux/pm2301_charger.h> | ||
31 | #include <linux/gpio.h> | ||
32 | |||
33 | #include "pm2301_charger.h" | ||
34 | |||
35 | #define to_pm2xxx_charger_ac_device_info(x) container_of((x), \ | ||
36 | struct pm2xxx_charger, ac_chg) | ||
37 | |||
38 | static int pm2xxx_interrupt_registers[] = { | ||
39 | PM2XXX_REG_INT1, | ||
40 | PM2XXX_REG_INT2, | ||
41 | PM2XXX_REG_INT3, | ||
42 | PM2XXX_REG_INT4, | ||
43 | PM2XXX_REG_INT5, | ||
44 | PM2XXX_REG_INT6, | ||
45 | }; | ||
46 | |||
47 | static enum power_supply_property pm2xxx_charger_ac_props[] = { | ||
48 | POWER_SUPPLY_PROP_HEALTH, | ||
49 | POWER_SUPPLY_PROP_PRESENT, | ||
50 | POWER_SUPPLY_PROP_ONLINE, | ||
51 | POWER_SUPPLY_PROP_VOLTAGE_AVG, | ||
52 | }; | ||
53 | |||
54 | static int pm2xxx_charger_voltage_map[] = { | ||
55 | 3500, | ||
56 | 3525, | ||
57 | 3550, | ||
58 | 3575, | ||
59 | 3600, | ||
60 | 3625, | ||
61 | 3650, | ||
62 | 3675, | ||
63 | 3700, | ||
64 | 3725, | ||
65 | 3750, | ||
66 | 3775, | ||
67 | 3800, | ||
68 | 3825, | ||
69 | 3850, | ||
70 | 3875, | ||
71 | 3900, | ||
72 | 3925, | ||
73 | 3950, | ||
74 | 3975, | ||
75 | 4000, | ||
76 | 4025, | ||
77 | 4050, | ||
78 | 4075, | ||
79 | 4100, | ||
80 | 4125, | ||
81 | 4150, | ||
82 | 4175, | ||
83 | 4200, | ||
84 | 4225, | ||
85 | 4250, | ||
86 | 4275, | ||
87 | 4300, | ||
88 | }; | ||
89 | |||
90 | static int pm2xxx_charger_current_map[] = { | ||
91 | 200, | ||
92 | 200, | ||
93 | 400, | ||
94 | 600, | ||
95 | 800, | ||
96 | 1000, | ||
97 | 1200, | ||
98 | 1400, | ||
99 | 1600, | ||
100 | 1800, | ||
101 | 2000, | ||
102 | 2200, | ||
103 | 2400, | ||
104 | 2600, | ||
105 | 2800, | ||
106 | 3000, | ||
107 | }; | ||
108 | |||
109 | static const struct i2c_device_id pm2xxx_ident[] = { | ||
110 | { "pm2301", 0 }, | ||
111 | { } | ||
112 | }; | ||
113 | |||
114 | static void set_lpn_pin(struct pm2xxx_charger *pm2) | ||
115 | { | ||
116 | if (pm2->ac.charger_connected) | ||
117 | return; | ||
118 | gpio_set_value(pm2->lpn_pin, 1); | ||
119 | |||
120 | return; | ||
121 | } | ||
122 | |||
123 | static void clear_lpn_pin(struct pm2xxx_charger *pm2) | ||
124 | { | ||
125 | if (pm2->ac.charger_connected) | ||
126 | return; | ||
127 | gpio_set_value(pm2->lpn_pin, 0); | ||
128 | |||
129 | return; | ||
130 | } | ||
131 | |||
132 | static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) | ||
133 | { | ||
134 | int ret; | ||
135 | /* | ||
136 | * When AC adaptor is unplugged, the host | ||
137 | * must put LPN high to be able to | ||
138 | * communicate by I2C with PM2301 | ||
139 | * and receive I2C "acknowledge" from PM2301. | ||
140 | */ | ||
141 | mutex_lock(&pm2->lock); | ||
142 | set_lpn_pin(pm2); | ||
143 | |||
144 | ret = i2c_smbus_read_i2c_block_data(pm2->config.pm2xxx_i2c, reg, | ||
145 | 1, val); | ||
146 | if (ret < 0) | ||
147 | dev_err(pm2->dev, "Error reading register at 0x%x\n", reg); | ||
148 | else | ||
149 | ret = 0; | ||
150 | clear_lpn_pin(pm2); | ||
151 | mutex_unlock(&pm2->lock); | ||
152 | |||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) | ||
157 | { | ||
158 | int ret; | ||
159 | /* | ||
160 | * When AC adaptor is unplugged, the host | ||
161 | * must put LPN high to be able to | ||
162 | * communicate by I2C with PM2301 | ||
163 | * and receive I2C "acknowledge" from PM2301. | ||
164 | */ | ||
165 | mutex_lock(&pm2->lock); | ||
166 | set_lpn_pin(pm2); | ||
167 | |||
168 | ret = i2c_smbus_write_i2c_block_data(pm2->config.pm2xxx_i2c, reg, | ||
169 | 1, &val); | ||
170 | if (ret < 0) | ||
171 | dev_err(pm2->dev, "Error writing register at 0x%x\n", reg); | ||
172 | else | ||
173 | ret = 0; | ||
174 | clear_lpn_pin(pm2); | ||
175 | mutex_unlock(&pm2->lock); | ||
176 | |||
177 | return ret; | ||
178 | } | ||
179 | |||
180 | static int pm2xxx_charging_enable_mngt(struct pm2xxx_charger *pm2) | ||
181 | { | ||
182 | int ret; | ||
183 | |||
184 | /* Enable charging */ | ||
185 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG2, | ||
186 | (PM2XXX_CH_AUTO_RESUME_EN | PM2XXX_CHARGER_ENA)); | ||
187 | |||
188 | return ret; | ||
189 | } | ||
190 | |||
191 | static int pm2xxx_charging_disable_mngt(struct pm2xxx_charger *pm2) | ||
192 | { | ||
193 | int ret; | ||
194 | |||
195 | /* Disable charging */ | ||
196 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG2, | ||
197 | (PM2XXX_CH_AUTO_RESUME_DIS | PM2XXX_CHARGER_DIS)); | ||
198 | |||
199 | return ret; | ||
200 | } | ||
201 | |||
202 | static int pm2xxx_charger_batt_therm_mngt(struct pm2xxx_charger *pm2, int val) | ||
203 | { | ||
204 | queue_work(pm2->charger_wq, &pm2->check_main_thermal_prot_work); | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | |||
210 | int pm2xxx_charger_die_therm_mngt(struct pm2xxx_charger *pm2, int val) | ||
211 | { | ||
212 | queue_work(pm2->charger_wq, &pm2->check_main_thermal_prot_work); | ||
213 | |||
214 | return 0; | ||
215 | } | ||
216 | |||
217 | static int pm2xxx_charger_ovv_mngt(struct pm2xxx_charger *pm2, int val) | ||
218 | { | ||
219 | int ret = 0; | ||
220 | |||
221 | pm2->failure_input_ovv++; | ||
222 | if (pm2->failure_input_ovv < 4) { | ||
223 | ret = pm2xxx_charging_enable_mngt(pm2); | ||
224 | goto out; | ||
225 | } else { | ||
226 | pm2->failure_input_ovv = 0; | ||
227 | dev_err(pm2->dev, "Overvoltage detected\n"); | ||
228 | pm2->flags.ovv = true; | ||
229 | power_supply_changed(&pm2->ac_chg.psy); | ||
230 | } | ||
231 | |||
232 | out: | ||
233 | return ret; | ||
234 | } | ||
235 | |||
236 | static int pm2xxx_charger_wd_exp_mngt(struct pm2xxx_charger *pm2, int val) | ||
237 | { | ||
238 | dev_dbg(pm2->dev , "20 minutes watchdog occured\n"); | ||
239 | |||
240 | pm2->ac.wd_expired = true; | ||
241 | power_supply_changed(&pm2->ac_chg.psy); | ||
242 | |||
243 | return 0; | ||
244 | } | ||
245 | |||
246 | static int pm2xxx_charger_vbat_lsig_mngt(struct pm2xxx_charger *pm2, int val) | ||
247 | { | ||
248 | switch (val) { | ||
249 | case PM2XXX_INT1_ITVBATLOWR: | ||
250 | dev_dbg(pm2->dev, "VBAT grows above VBAT_LOW level\n"); | ||
251 | break; | ||
252 | |||
253 | case PM2XXX_INT1_ITVBATLOWF: | ||
254 | dev_dbg(pm2->dev, "VBAT drops below VBAT_LOW level\n"); | ||
255 | break; | ||
256 | |||
257 | default: | ||
258 | dev_err(pm2->dev, "Unknown VBAT level\n"); | ||
259 | } | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static int pm2xxx_charger_bat_disc_mngt(struct pm2xxx_charger *pm2, int val) | ||
265 | { | ||
266 | dev_dbg(pm2->dev, "battery disconnected\n"); | ||
267 | |||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static int pm2xxx_charger_detection(struct pm2xxx_charger *pm2, u8 *val) | ||
272 | { | ||
273 | int ret; | ||
274 | |||
275 | ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT2, val); | ||
276 | |||
277 | if (ret < 0) { | ||
278 | dev_err(pm2->dev, "Charger detection failed\n"); | ||
279 | goto out; | ||
280 | } | ||
281 | |||
282 | *val &= (PM2XXX_INT2_S_ITVPWR1PLUG | PM2XXX_INT2_S_ITVPWR2PLUG); | ||
283 | |||
284 | out: | ||
285 | return ret; | ||
286 | } | ||
287 | |||
288 | static int pm2xxx_charger_itv_pwr_plug_mngt(struct pm2xxx_charger *pm2, int val) | ||
289 | { | ||
290 | |||
291 | int ret; | ||
292 | u8 read_val; | ||
293 | |||
294 | /* | ||
295 | * Since we can't be sure that the events are received | ||
296 | * synchronously, we have the check if the main charger is | ||
297 | * connected by reading the interrupt source register. | ||
298 | */ | ||
299 | ret = pm2xxx_charger_detection(pm2, &read_val); | ||
300 | |||
301 | if ((ret == 0) && read_val) { | ||
302 | pm2->ac.charger_connected = 1; | ||
303 | pm2->ac_conn = true; | ||
304 | queue_work(pm2->charger_wq, &pm2->ac_work); | ||
305 | } | ||
306 | |||
307 | |||
308 | return ret; | ||
309 | } | ||
310 | |||
311 | static int pm2xxx_charger_itv_pwr_unplug_mngt(struct pm2xxx_charger *pm2, | ||
312 | int val) | ||
313 | { | ||
314 | pm2->ac.charger_connected = 0; | ||
315 | queue_work(pm2->charger_wq, &pm2->ac_work); | ||
316 | |||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | static int pm2_int_reg0(void *pm2_data, int val) | ||
321 | { | ||
322 | struct pm2xxx_charger *pm2 = pm2_data; | ||
323 | int ret = 0; | ||
324 | |||
325 | if (val & (PM2XXX_INT1_ITVBATLOWR | PM2XXX_INT1_ITVBATLOWF)) { | ||
326 | ret = pm2xxx_charger_vbat_lsig_mngt(pm2, val & | ||
327 | (PM2XXX_INT1_ITVBATLOWR | PM2XXX_INT1_ITVBATLOWF)); | ||
328 | } | ||
329 | |||
330 | if (val & PM2XXX_INT1_ITVBATDISCONNECT) { | ||
331 | ret = pm2xxx_charger_bat_disc_mngt(pm2, | ||
332 | PM2XXX_INT1_ITVBATDISCONNECT); | ||
333 | } | ||
334 | |||
335 | return ret; | ||
336 | } | ||
337 | |||
338 | static int pm2_int_reg1(void *pm2_data, int val) | ||
339 | { | ||
340 | struct pm2xxx_charger *pm2 = pm2_data; | ||
341 | int ret = 0; | ||
342 | |||
343 | if (val & (PM2XXX_INT2_ITVPWR1PLUG | PM2XXX_INT2_ITVPWR2PLUG)) { | ||
344 | dev_dbg(pm2->dev , "Main charger plugged\n"); | ||
345 | ret = pm2xxx_charger_itv_pwr_plug_mngt(pm2, val & | ||
346 | (PM2XXX_INT2_ITVPWR1PLUG | PM2XXX_INT2_ITVPWR2PLUG)); | ||
347 | } | ||
348 | |||
349 | if (val & | ||
350 | (PM2XXX_INT2_ITVPWR1UNPLUG | PM2XXX_INT2_ITVPWR2UNPLUG)) { | ||
351 | dev_dbg(pm2->dev , "Main charger unplugged\n"); | ||
352 | ret = pm2xxx_charger_itv_pwr_unplug_mngt(pm2, val & | ||
353 | (PM2XXX_INT2_ITVPWR1UNPLUG | | ||
354 | PM2XXX_INT2_ITVPWR2UNPLUG)); | ||
355 | } | ||
356 | |||
357 | return ret; | ||
358 | } | ||
359 | |||
360 | static int pm2_int_reg2(void *pm2_data, int val) | ||
361 | { | ||
362 | struct pm2xxx_charger *pm2 = pm2_data; | ||
363 | int ret = 0; | ||
364 | |||
365 | if (val & PM2XXX_INT3_ITAUTOTIMEOUTWD) | ||
366 | ret = pm2xxx_charger_wd_exp_mngt(pm2, val); | ||
367 | |||
368 | if (val & (PM2XXX_INT3_ITCHPRECHARGEWD | | ||
369 | PM2XXX_INT3_ITCHCCWD | PM2XXX_INT3_ITCHCVWD)) { | ||
370 | dev_dbg(pm2->dev, | ||
371 | "Watchdog occured for precharge, CC and CV charge\n"); | ||
372 | } | ||
373 | |||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | static int pm2_int_reg3(void *pm2_data, int val) | ||
378 | { | ||
379 | struct pm2xxx_charger *pm2 = pm2_data; | ||
380 | int ret = 0; | ||
381 | |||
382 | if (val & (PM2XXX_INT4_ITCHARGINGON)) { | ||
383 | dev_dbg(pm2->dev , | ||
384 | "chargind operation has started\n"); | ||
385 | } | ||
386 | |||
387 | if (val & (PM2XXX_INT4_ITVRESUME)) { | ||
388 | dev_dbg(pm2->dev, | ||
389 | "battery discharged down to VResume threshold\n"); | ||
390 | } | ||
391 | |||
392 | if (val & (PM2XXX_INT4_ITBATTFULL)) { | ||
393 | dev_dbg(pm2->dev , "battery fully detected\n"); | ||
394 | } | ||
395 | |||
396 | if (val & (PM2XXX_INT4_ITCVPHASE)) { | ||
397 | dev_dbg(pm2->dev, "CV phase enter with 0.5C charging\n"); | ||
398 | } | ||
399 | |||
400 | if (val & (PM2XXX_INT4_ITVPWR2OVV | PM2XXX_INT4_ITVPWR1OVV)) { | ||
401 | pm2->failure_case = VPWR_OVV; | ||
402 | ret = pm2xxx_charger_ovv_mngt(pm2, val & | ||
403 | (PM2XXX_INT4_ITVPWR2OVV | PM2XXX_INT4_ITVPWR1OVV)); | ||
404 | dev_dbg(pm2->dev, "VPWR/VSYSTEM overvoltage detected\n"); | ||
405 | } | ||
406 | |||
407 | if (val & (PM2XXX_INT4_S_ITBATTEMPCOLD | | ||
408 | PM2XXX_INT4_S_ITBATTEMPHOT)) { | ||
409 | ret = pm2xxx_charger_batt_therm_mngt(pm2, val & | ||
410 | (PM2XXX_INT4_S_ITBATTEMPCOLD | | ||
411 | PM2XXX_INT4_S_ITBATTEMPHOT)); | ||
412 | dev_dbg(pm2->dev, "BTEMP is too Low/High\n"); | ||
413 | } | ||
414 | |||
415 | return ret; | ||
416 | } | ||
417 | |||
418 | static int pm2_int_reg4(void *pm2_data, int val) | ||
419 | { | ||
420 | struct pm2xxx_charger *pm2 = pm2_data; | ||
421 | int ret = 0; | ||
422 | |||
423 | if (val & PM2XXX_INT5_ITVSYSTEMOVV) { | ||
424 | pm2->failure_case = VSYSTEM_OVV; | ||
425 | ret = pm2xxx_charger_ovv_mngt(pm2, val & | ||
426 | PM2XXX_INT5_ITVSYSTEMOVV); | ||
427 | dev_dbg(pm2->dev, "VSYSTEM overvoltage detected\n"); | ||
428 | } | ||
429 | |||
430 | if (val & (PM2XXX_INT5_ITTHERMALWARNINGFALL | | ||
431 | PM2XXX_INT5_ITTHERMALWARNINGRISE | | ||
432 | PM2XXX_INT5_ITTHERMALSHUTDOWNFALL | | ||
433 | PM2XXX_INT5_ITTHERMALSHUTDOWNRISE)) { | ||
434 | dev_dbg(pm2->dev, "BTEMP die temperature is too Low/High\n"); | ||
435 | ret = pm2xxx_charger_die_therm_mngt(pm2, val & | ||
436 | (PM2XXX_INT5_ITTHERMALWARNINGFALL | | ||
437 | PM2XXX_INT5_ITTHERMALWARNINGRISE | | ||
438 | PM2XXX_INT5_ITTHERMALSHUTDOWNFALL | | ||
439 | PM2XXX_INT5_ITTHERMALSHUTDOWNRISE)); | ||
440 | } | ||
441 | |||
442 | return ret; | ||
443 | } | ||
444 | |||
445 | static int pm2_int_reg5(void *pm2_data, int val) | ||
446 | { | ||
447 | struct pm2xxx_charger *pm2 = pm2_data; | ||
448 | int ret = 0; | ||
449 | |||
450 | |||
451 | if (val & (PM2XXX_INT6_ITVPWR2DROP | PM2XXX_INT6_ITVPWR1DROP)) { | ||
452 | dev_dbg(pm2->dev, "VMPWR drop to VBAT level\n"); | ||
453 | } | ||
454 | |||
455 | if (val & (PM2XXX_INT6_ITVPWR2VALIDRISE | | ||
456 | PM2XXX_INT6_ITVPWR1VALIDRISE | | ||
457 | PM2XXX_INT6_ITVPWR2VALIDFALL | | ||
458 | PM2XXX_INT6_ITVPWR1VALIDFALL)) { | ||
459 | dev_dbg(pm2->dev, "Falling/Rising edge on WPWR1/2\n"); | ||
460 | } | ||
461 | |||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | static irqreturn_t pm2xxx_irq_int(int irq, void *data) | ||
466 | { | ||
467 | struct pm2xxx_charger *pm2 = data; | ||
468 | struct pm2xxx_interrupts *interrupt = pm2->pm2_int; | ||
469 | int i; | ||
470 | |||
471 | for (i = 0; i < PM2XXX_NUM_INT_REG; i++) { | ||
472 | pm2xxx_reg_read(pm2, | ||
473 | pm2xxx_interrupt_registers[i], | ||
474 | &(interrupt->reg[i])); | ||
475 | |||
476 | if (interrupt->reg[i] > 0) | ||
477 | interrupt->handler[i](pm2, interrupt->reg[i]); | ||
478 | } | ||
479 | |||
480 | return IRQ_HANDLED; | ||
481 | } | ||
482 | |||
483 | static int pm2xxx_charger_get_ac_cv(struct pm2xxx_charger *pm2) | ||
484 | { | ||
485 | int ret = 0; | ||
486 | u8 val; | ||
487 | |||
488 | if (pm2->ac.charger_connected && pm2->ac.charger_online) { | ||
489 | |||
490 | ret = pm2xxx_reg_read(pm2, PM2XXX_SRCE_REG_INT4, &val); | ||
491 | if (ret < 0) { | ||
492 | dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__); | ||
493 | goto out; | ||
494 | } | ||
495 | |||
496 | if (val & PM2XXX_INT4_S_ITCVPHASE) | ||
497 | ret = PM2XXX_CONST_VOLT; | ||
498 | else | ||
499 | ret = PM2XXX_CONST_CURR; | ||
500 | } | ||
501 | out: | ||
502 | return ret; | ||
503 | } | ||
504 | |||
505 | static int pm2xxx_current_to_regval(int curr) | ||
506 | { | ||
507 | int i; | ||
508 | |||
509 | if (curr < pm2xxx_charger_current_map[0]) | ||
510 | return 0; | ||
511 | |||
512 | for (i = 1; i < ARRAY_SIZE(pm2xxx_charger_current_map); i++) { | ||
513 | if (curr < pm2xxx_charger_current_map[i]) | ||
514 | return (i - 1); | ||
515 | } | ||
516 | |||
517 | i = ARRAY_SIZE(pm2xxx_charger_current_map) - 1; | ||
518 | if (curr == pm2xxx_charger_current_map[i]) | ||
519 | return i; | ||
520 | else | ||
521 | return -EINVAL; | ||
522 | } | ||
523 | |||
524 | static int pm2xxx_voltage_to_regval(int curr) | ||
525 | { | ||
526 | int i; | ||
527 | |||
528 | if (curr < pm2xxx_charger_voltage_map[0]) | ||
529 | return 0; | ||
530 | |||
531 | for (i = 1; i < ARRAY_SIZE(pm2xxx_charger_voltage_map); i++) { | ||
532 | if (curr < pm2xxx_charger_voltage_map[i]) | ||
533 | return i - 1; | ||
534 | } | ||
535 | |||
536 | i = ARRAY_SIZE(pm2xxx_charger_voltage_map) - 1; | ||
537 | if (curr == pm2xxx_charger_voltage_map[i]) | ||
538 | return i; | ||
539 | else | ||
540 | return -EINVAL; | ||
541 | } | ||
542 | |||
543 | static int pm2xxx_charger_update_charger_current(struct ux500_charger *charger, | ||
544 | int ich_out) | ||
545 | { | ||
546 | int ret; | ||
547 | int curr_index; | ||
548 | struct pm2xxx_charger *pm2; | ||
549 | u8 val; | ||
550 | |||
551 | if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS) | ||
552 | pm2 = to_pm2xxx_charger_ac_device_info(charger); | ||
553 | else | ||
554 | return -ENXIO; | ||
555 | |||
556 | curr_index = pm2xxx_current_to_regval(ich_out); | ||
557 | if (curr_index < 0) { | ||
558 | dev_err(pm2->dev, | ||
559 | "Charger current too high, charging not started\n"); | ||
560 | return -ENXIO; | ||
561 | } | ||
562 | |||
563 | ret = pm2xxx_reg_read(pm2, PM2XXX_BATT_CTRL_REG6, &val); | ||
564 | if (ret >= 0) { | ||
565 | val &= ~PM2XXX_DIR_CH_CC_CURRENT_MASK; | ||
566 | val |= curr_index; | ||
567 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6, val); | ||
568 | if (ret < 0) { | ||
569 | dev_err(pm2->dev, | ||
570 | "%s write failed\n", __func__); | ||
571 | } | ||
572 | } | ||
573 | else | ||
574 | dev_err(pm2->dev, "%s read failed\n", __func__); | ||
575 | |||
576 | return ret; | ||
577 | } | ||
578 | |||
579 | static int pm2xxx_charger_ac_get_property(struct power_supply *psy, | ||
580 | enum power_supply_property psp, | ||
581 | union power_supply_propval *val) | ||
582 | { | ||
583 | struct pm2xxx_charger *pm2; | ||
584 | |||
585 | pm2 = to_pm2xxx_charger_ac_device_info(psy_to_ux500_charger(psy)); | ||
586 | |||
587 | switch (psp) { | ||
588 | case POWER_SUPPLY_PROP_HEALTH: | ||
589 | if (pm2->flags.mainextchnotok) | ||
590 | val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE; | ||
591 | else if (pm2->ac.wd_expired) | ||
592 | val->intval = POWER_SUPPLY_HEALTH_DEAD; | ||
593 | else if (pm2->flags.main_thermal_prot) | ||
594 | val->intval = POWER_SUPPLY_HEALTH_OVERHEAT; | ||
595 | else | ||
596 | val->intval = POWER_SUPPLY_HEALTH_GOOD; | ||
597 | break; | ||
598 | case POWER_SUPPLY_PROP_ONLINE: | ||
599 | val->intval = pm2->ac.charger_online; | ||
600 | break; | ||
601 | case POWER_SUPPLY_PROP_PRESENT: | ||
602 | val->intval = pm2->ac.charger_connected; | ||
603 | break; | ||
604 | case POWER_SUPPLY_PROP_VOLTAGE_AVG: | ||
605 | pm2->ac.cv_active = pm2xxx_charger_get_ac_cv(pm2); | ||
606 | val->intval = pm2->ac.cv_active; | ||
607 | break; | ||
608 | default: | ||
609 | return -EINVAL; | ||
610 | } | ||
611 | return 0; | ||
612 | } | ||
613 | |||
614 | static int pm2xxx_charging_init(struct pm2xxx_charger *pm2) | ||
615 | { | ||
616 | int ret = 0; | ||
617 | |||
618 | /* enable CC and CV watchdog */ | ||
619 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG3, | ||
620 | (PM2XXX_CH_WD_CV_PHASE_60MIN | PM2XXX_CH_WD_CC_PHASE_60MIN)); | ||
621 | if( ret < 0) | ||
622 | return ret; | ||
623 | |||
624 | /* enable precharge watchdog */ | ||
625 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG4, | ||
626 | PM2XXX_CH_WD_PRECH_PHASE_60MIN); | ||
627 | |||
628 | /* Disable auto timeout */ | ||
629 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG5, | ||
630 | PM2XXX_CH_WD_AUTO_TIMEOUT_20MIN); | ||
631 | |||
632 | /* | ||
633 | * EOC current level = 100mA | ||
634 | * Precharge current level = 100mA | ||
635 | * CC current level = 1000mA | ||
636 | */ | ||
637 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6, | ||
638 | (PM2XXX_DIR_CH_CC_CURRENT_1000MA | | ||
639 | PM2XXX_CH_PRECH_CURRENT_100MA | | ||
640 | PM2XXX_CH_EOC_CURRENT_100MA)); | ||
641 | |||
642 | /* | ||
643 | * recharge threshold = 3.8V | ||
644 | * Precharge to CC threshold = 2.9V | ||
645 | */ | ||
646 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG7, | ||
647 | (PM2XXX_CH_PRECH_VOL_2_9 | PM2XXX_CH_VRESUME_VOL_3_8)); | ||
648 | |||
649 | /* float voltage charger level = 4.2V */ | ||
650 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG8, | ||
651 | PM2XXX_CH_VOLT_4_2); | ||
652 | |||
653 | /* Voltage drop between VBAT and VSYS in HW charging = 300mV */ | ||
654 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG9, | ||
655 | (PM2XXX_CH_150MV_DROP_300MV | PM2XXX_CHARCHING_INFO_DIS | | ||
656 | PM2XXX_CH_CC_REDUCED_CURRENT_IDENT | | ||
657 | PM2XXX_CH_CC_MODEDROP_DIS)); | ||
658 | |||
659 | /* Input charger level of over voltage = 10V */ | ||
660 | ret = pm2xxx_reg_write(pm2, PM2XXX_INP_VOLT_VPWR2, | ||
661 | PM2XXX_VPWR2_OVV_10); | ||
662 | ret = pm2xxx_reg_write(pm2, PM2XXX_INP_VOLT_VPWR1, | ||
663 | PM2XXX_VPWR1_OVV_10); | ||
664 | |||
665 | /* Input charger drop */ | ||
666 | ret = pm2xxx_reg_write(pm2, PM2XXX_INP_DROP_VPWR2, | ||
667 | (PM2XXX_VPWR2_HW_OPT_DIS | PM2XXX_VPWR2_VALID_DIS | | ||
668 | PM2XXX_VPWR2_DROP_DIS)); | ||
669 | ret = pm2xxx_reg_write(pm2, PM2XXX_INP_DROP_VPWR1, | ||
670 | (PM2XXX_VPWR1_HW_OPT_DIS | PM2XXX_VPWR1_VALID_DIS | | ||
671 | PM2XXX_VPWR1_DROP_DIS)); | ||
672 | |||
673 | /* Disable battery low monitoring */ | ||
674 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_LOW_LEV_COMP_REG, | ||
675 | PM2XXX_VBAT_LOW_MONITORING_ENA); | ||
676 | |||
677 | /* Disable LED */ | ||
678 | ret = pm2xxx_reg_write(pm2, PM2XXX_LED_CTRL_REG, | ||
679 | PM2XXX_LED_SELECT_DIS); | ||
680 | |||
681 | return ret; | ||
682 | } | ||
683 | |||
684 | static int pm2xxx_charger_ac_en(struct ux500_charger *charger, | ||
685 | int enable, int vset, int iset) | ||
686 | { | ||
687 | int ret; | ||
688 | int volt_index; | ||
689 | int curr_index; | ||
690 | u8 val; | ||
691 | |||
692 | struct pm2xxx_charger *pm2 = to_pm2xxx_charger_ac_device_info(charger); | ||
693 | |||
694 | if (enable) { | ||
695 | if (!pm2->ac.charger_connected) { | ||
696 | dev_dbg(pm2->dev, "AC charger not connected\n"); | ||
697 | return -ENXIO; | ||
698 | } | ||
699 | |||
700 | dev_dbg(pm2->dev, "Enable AC: %dmV %dmA\n", vset, iset); | ||
701 | if (!pm2->vddadc_en_ac) { | ||
702 | regulator_enable(pm2->regu); | ||
703 | pm2->vddadc_en_ac = true; | ||
704 | } | ||
705 | |||
706 | ret = pm2xxx_charging_init(pm2); | ||
707 | if (ret < 0) { | ||
708 | dev_err(pm2->dev, "%s charging init failed\n", | ||
709 | __func__); | ||
710 | goto error_occured; | ||
711 | } | ||
712 | |||
713 | volt_index = pm2xxx_voltage_to_regval(vset); | ||
714 | curr_index = pm2xxx_current_to_regval(iset); | ||
715 | |||
716 | if (volt_index < 0 || curr_index < 0) { | ||
717 | dev_err(pm2->dev, | ||
718 | "Charger voltage or current too high, " | ||
719 | "charging not started\n"); | ||
720 | return -ENXIO; | ||
721 | } | ||
722 | |||
723 | ret = pm2xxx_reg_read(pm2, PM2XXX_BATT_CTRL_REG8, &val); | ||
724 | if (ret < 0) { | ||
725 | dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__); | ||
726 | goto error_occured; | ||
727 | } | ||
728 | val &= ~PM2XXX_CH_VOLT_MASK; | ||
729 | val |= volt_index; | ||
730 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG8, val); | ||
731 | if (ret < 0) { | ||
732 | dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); | ||
733 | goto error_occured; | ||
734 | } | ||
735 | |||
736 | ret = pm2xxx_reg_read(pm2, PM2XXX_BATT_CTRL_REG6, &val); | ||
737 | if (ret < 0) { | ||
738 | dev_err(pm2->dev, "%s pm2xxx read failed\n", __func__); | ||
739 | goto error_occured; | ||
740 | } | ||
741 | val &= ~PM2XXX_DIR_CH_CC_CURRENT_MASK; | ||
742 | val |= curr_index; | ||
743 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6, val); | ||
744 | if (ret < 0) { | ||
745 | dev_err(pm2->dev, "%s pm2xxx write failed\n", __func__); | ||
746 | goto error_occured; | ||
747 | } | ||
748 | |||
749 | if (!pm2->bat->enable_overshoot) { | ||
750 | ret = pm2xxx_reg_read(pm2, PM2XXX_LED_CTRL_REG, &val); | ||
751 | if (ret < 0) { | ||
752 | dev_err(pm2->dev, "%s pm2xxx read failed\n", | ||
753 | __func__); | ||
754 | goto error_occured; | ||
755 | } | ||
756 | val |= PM2XXX_ANTI_OVERSHOOT_EN; | ||
757 | ret = pm2xxx_reg_write(pm2, PM2XXX_LED_CTRL_REG, val); | ||
758 | if (ret < 0) { | ||
759 | dev_err(pm2->dev, "%s pm2xxx write failed\n", | ||
760 | __func__); | ||
761 | goto error_occured; | ||
762 | } | ||
763 | } | ||
764 | |||
765 | ret = pm2xxx_charging_enable_mngt(pm2); | ||
766 | if (ret < 0) { | ||
767 | dev_err(pm2->dev, "Failed to enable" | ||
768 | "pm2xxx ac charger\n"); | ||
769 | goto error_occured; | ||
770 | } | ||
771 | |||
772 | pm2->ac.charger_online = 1; | ||
773 | } else { | ||
774 | pm2->ac.charger_online = 0; | ||
775 | pm2->ac.wd_expired = false; | ||
776 | |||
777 | /* Disable regulator if enabled */ | ||
778 | if (pm2->vddadc_en_ac) { | ||
779 | regulator_disable(pm2->regu); | ||
780 | pm2->vddadc_en_ac = false; | ||
781 | } | ||
782 | |||
783 | ret = pm2xxx_charging_disable_mngt(pm2); | ||
784 | if (ret < 0) { | ||
785 | dev_err(pm2->dev, "failed to disable" | ||
786 | "pm2xxx ac charger\n"); | ||
787 | goto error_occured; | ||
788 | } | ||
789 | |||
790 | dev_dbg(pm2->dev, "PM2301: " "Disabled AC charging\n"); | ||
791 | } | ||
792 | power_supply_changed(&pm2->ac_chg.psy); | ||
793 | |||
794 | error_occured: | ||
795 | return ret; | ||
796 | } | ||
797 | |||
798 | static int pm2xxx_charger_watchdog_kick(struct ux500_charger *charger) | ||
799 | { | ||
800 | int ret; | ||
801 | struct pm2xxx_charger *pm2; | ||
802 | |||
803 | if (charger->psy.type == POWER_SUPPLY_TYPE_MAINS) | ||
804 | pm2 = to_pm2xxx_charger_ac_device_info(charger); | ||
805 | else | ||
806 | return -ENXIO; | ||
807 | |||
808 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_WD_KICK, WD_TIMER); | ||
809 | if (ret) | ||
810 | dev_err(pm2->dev, "Failed to kick WD!\n"); | ||
811 | |||
812 | return ret; | ||
813 | } | ||
814 | |||
815 | static void pm2xxx_charger_ac_work(struct work_struct *work) | ||
816 | { | ||
817 | struct pm2xxx_charger *pm2 = container_of(work, | ||
818 | struct pm2xxx_charger, ac_work); | ||
819 | |||
820 | |||
821 | power_supply_changed(&pm2->ac_chg.psy); | ||
822 | sysfs_notify(&pm2->ac_chg.psy.dev->kobj, NULL, "present"); | ||
823 | }; | ||
824 | |||
825 | static void pm2xxx_charger_check_main_thermal_prot_work( | ||
826 | struct work_struct *work) | ||
827 | { | ||
828 | }; | ||
829 | |||
830 | static struct pm2xxx_interrupts pm2xxx_int = { | ||
831 | .handler[0] = pm2_int_reg0, | ||
832 | .handler[1] = pm2_int_reg1, | ||
833 | .handler[2] = pm2_int_reg2, | ||
834 | .handler[3] = pm2_int_reg3, | ||
835 | .handler[4] = pm2_int_reg4, | ||
836 | .handler[5] = pm2_int_reg5, | ||
837 | }; | ||
838 | |||
839 | static struct pm2xxx_irq pm2xxx_charger_irq[] = { | ||
840 | {"PM2XXX_IRQ_INT", pm2xxx_irq_int}, | ||
841 | }; | ||
842 | |||
843 | static int pm2xxx_wall_charger_resume(struct i2c_client *i2c_client) | ||
844 | { | ||
845 | return 0; | ||
846 | } | ||
847 | |||
848 | static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client, | ||
849 | pm_message_t state) | ||
850 | { | ||
851 | return 0; | ||
852 | } | ||
853 | |||
854 | static int __devinit pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, | ||
855 | const struct i2c_device_id *id) | ||
856 | { | ||
857 | struct pm2xxx_platform_data *pl_data = i2c_client->dev.platform_data; | ||
858 | struct pm2xxx_charger *pm2; | ||
859 | int ret = 0; | ||
860 | u8 val; | ||
861 | |||
862 | pm2 = kzalloc(sizeof(struct pm2xxx_charger), GFP_KERNEL); | ||
863 | if (!pm2) { | ||
864 | dev_err(pm2->dev, "pm2xxx_charger allocation failed\n"); | ||
865 | return -ENOMEM; | ||
866 | } | ||
867 | |||
868 | /* get parent data */ | ||
869 | pm2->dev = &i2c_client->dev; | ||
870 | pm2->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); | ||
871 | |||
872 | pm2->pm2_int = &pm2xxx_int; | ||
873 | |||
874 | /* get charger spcific platform data */ | ||
875 | if (!pl_data->wall_charger) { | ||
876 | dev_err(pm2->dev, "no charger platform data supplied\n"); | ||
877 | ret = -EINVAL; | ||
878 | goto free_device_info; | ||
879 | } | ||
880 | |||
881 | pm2->pdata = pl_data->wall_charger; | ||
882 | |||
883 | /* get battery specific platform data */ | ||
884 | if (!pl_data->battery) { | ||
885 | dev_err(pm2->dev, "no battery platform data supplied\n"); | ||
886 | ret = -EINVAL; | ||
887 | goto free_device_info; | ||
888 | } | ||
889 | |||
890 | pm2->bat = pl_data->battery; | ||
891 | |||
892 | /*get lpn GPIO from platform data*/ | ||
893 | if (!pm2->pdata->lpn_gpio) { | ||
894 | dev_err(pm2->dev, "no lpn gpio data supplied\n"); | ||
895 | ret = -EINVAL; | ||
896 | goto free_device_info; | ||
897 | } | ||
898 | pm2->lpn_pin = pm2->pdata->lpn_gpio; | ||
899 | |||
900 | if (!i2c_check_functionality(i2c_client->adapter, | ||
901 | I2C_FUNC_SMBUS_BYTE_DATA | | ||
902 | I2C_FUNC_SMBUS_READ_WORD_DATA)) { | ||
903 | ret = -ENODEV; | ||
904 | dev_info(pm2->dev, "pm2301 i2c_check_functionality failed\n"); | ||
905 | goto free_device_info; | ||
906 | } | ||
907 | |||
908 | pm2->config.pm2xxx_i2c = i2c_client; | ||
909 | pm2->config.pm2xxx_id = (struct i2c_device_id *) id; | ||
910 | i2c_set_clientdata(i2c_client, pm2); | ||
911 | |||
912 | /* AC supply */ | ||
913 | /* power_supply base class */ | ||
914 | pm2->ac_chg.psy.name = pm2->pdata->label; | ||
915 | pm2->ac_chg.psy.type = POWER_SUPPLY_TYPE_MAINS; | ||
916 | pm2->ac_chg.psy.properties = pm2xxx_charger_ac_props; | ||
917 | pm2->ac_chg.psy.num_properties = ARRAY_SIZE(pm2xxx_charger_ac_props); | ||
918 | pm2->ac_chg.psy.get_property = pm2xxx_charger_ac_get_property; | ||
919 | pm2->ac_chg.psy.supplied_to = pm2->pdata->supplied_to; | ||
920 | pm2->ac_chg.psy.num_supplicants = pm2->pdata->num_supplicants; | ||
921 | /* pm2xxx_charger sub-class */ | ||
922 | pm2->ac_chg.ops.enable = &pm2xxx_charger_ac_en; | ||
923 | pm2->ac_chg.ops.kick_wd = &pm2xxx_charger_watchdog_kick; | ||
924 | pm2->ac_chg.ops.update_curr = &pm2xxx_charger_update_charger_current; | ||
925 | pm2->ac_chg.max_out_volt = pm2xxx_charger_voltage_map[ | ||
926 | ARRAY_SIZE(pm2xxx_charger_voltage_map) - 1]; | ||
927 | pm2->ac_chg.max_out_curr = pm2xxx_charger_current_map[ | ||
928 | ARRAY_SIZE(pm2xxx_charger_current_map) - 1]; | ||
929 | pm2->ac_chg.wdt_refresh = WD_KICK_INTERVAL; | ||
930 | pm2->ac_chg.enabled = true; | ||
931 | pm2->ac_chg.external = true; | ||
932 | |||
933 | /* Create a work queue for the charger */ | ||
934 | pm2->charger_wq = | ||
935 | create_singlethread_workqueue("pm2xxx_charger_wq"); | ||
936 | if (pm2->charger_wq == NULL) { | ||
937 | dev_err(pm2->dev, "failed to create work queue\n"); | ||
938 | goto free_device_info; | ||
939 | } | ||
940 | |||
941 | /* Init work for charger detection */ | ||
942 | INIT_WORK(&pm2->ac_work, pm2xxx_charger_ac_work); | ||
943 | |||
944 | /* Init work for checking HW status */ | ||
945 | INIT_WORK(&pm2->check_main_thermal_prot_work, | ||
946 | pm2xxx_charger_check_main_thermal_prot_work); | ||
947 | |||
948 | /* | ||
949 | * VDD ADC supply needs to be enabled from this driver when there | ||
950 | * is a charger connected to avoid erroneous BTEMP_HIGH/LOW | ||
951 | * interrupts during charging | ||
952 | */ | ||
953 | pm2->regu = regulator_get(pm2->dev, "vddadc"); | ||
954 | if (IS_ERR(pm2->regu)) { | ||
955 | ret = PTR_ERR(pm2->regu); | ||
956 | dev_err(pm2->dev, "failed to get vddadc regulator\n"); | ||
957 | goto free_charger_wq; | ||
958 | } | ||
959 | |||
960 | /* Register AC charger class */ | ||
961 | ret = power_supply_register(pm2->dev, &pm2->ac_chg.psy); | ||
962 | if (ret) { | ||
963 | dev_err(pm2->dev, "failed to register AC charger\n"); | ||
964 | goto free_regulator; | ||
965 | } | ||
966 | |||
967 | /* Register interrupts */ | ||
968 | ret = request_threaded_irq(pm2->pdata->irq_number, NULL, | ||
969 | pm2xxx_charger_irq[0].isr, | ||
970 | pm2->pdata->irq_type, | ||
971 | pm2xxx_charger_irq[0].name, pm2); | ||
972 | |||
973 | if (ret != 0) { | ||
974 | dev_err(pm2->dev, "failed to request %s IRQ %d: %d\n", | ||
975 | pm2xxx_charger_irq[0].name, pm2->pdata->irq_number, ret); | ||
976 | goto unregister_pm2xxx_charger; | ||
977 | } | ||
978 | |||
979 | /*Initialize lock*/ | ||
980 | mutex_init(&pm2->lock); | ||
981 | |||
982 | /* | ||
983 | * Charger detection mechanism requires pulling up the LPN pin | ||
984 | * while i2c communication if Charger is not connected | ||
985 | * LPN pin of PM2301 is GPIO60 of AB9540 | ||
986 | */ | ||
987 | ret = gpio_request(pm2->lpn_pin, "pm2301_lpm_gpio"); | ||
988 | if (ret < 0) { | ||
989 | dev_err(pm2->dev, "pm2301_lpm_gpio request failed\n"); | ||
990 | goto unregister_pm2xxx_charger; | ||
991 | } | ||
992 | ret = gpio_direction_output(pm2->lpn_pin, 0); | ||
993 | if (ret < 0) { | ||
994 | dev_err(pm2->dev, "pm2301_lpm_gpio direction failed\n"); | ||
995 | goto free_gpio; | ||
996 | } | ||
997 | |||
998 | ret = pm2xxx_charger_detection(pm2, &val); | ||
999 | |||
1000 | if ((ret == 0) && val) { | ||
1001 | pm2->ac.charger_connected = 1; | ||
1002 | pm2->ac_conn = true; | ||
1003 | power_supply_changed(&pm2->ac_chg.psy); | ||
1004 | sysfs_notify(&pm2->ac_chg.psy.dev->kobj, NULL, "present"); | ||
1005 | } | ||
1006 | |||
1007 | return 0; | ||
1008 | |||
1009 | free_gpio: | ||
1010 | gpio_free(pm2->lpn_pin); | ||
1011 | unregister_pm2xxx_charger: | ||
1012 | /* unregister power supply */ | ||
1013 | power_supply_unregister(&pm2->ac_chg.psy); | ||
1014 | free_regulator: | ||
1015 | /* disable the regulator */ | ||
1016 | regulator_put(pm2->regu); | ||
1017 | free_charger_wq: | ||
1018 | destroy_workqueue(pm2->charger_wq); | ||
1019 | free_device_info: | ||
1020 | kfree(pm2); | ||
1021 | return ret; | ||
1022 | } | ||
1023 | |||
1024 | static int __devexit pm2xxx_wall_charger_remove(struct i2c_client *i2c_client) | ||
1025 | { | ||
1026 | struct pm2xxx_charger *pm2 = i2c_get_clientdata(i2c_client); | ||
1027 | |||
1028 | /* Disable AC charging */ | ||
1029 | pm2xxx_charger_ac_en(&pm2->ac_chg, false, 0, 0); | ||
1030 | |||
1031 | /* Disable interrupts */ | ||
1032 | free_irq(pm2->pdata->irq_number, pm2); | ||
1033 | |||
1034 | /* Delete the work queue */ | ||
1035 | destroy_workqueue(pm2->charger_wq); | ||
1036 | |||
1037 | flush_scheduled_work(); | ||
1038 | |||
1039 | /* disable the regulator */ | ||
1040 | regulator_put(pm2->regu); | ||
1041 | |||
1042 | power_supply_unregister(&pm2->ac_chg.psy); | ||
1043 | |||
1044 | /*Free GPIO60*/ | ||
1045 | gpio_free(pm2->lpn_pin); | ||
1046 | |||
1047 | kfree(pm2); | ||
1048 | |||
1049 | return 0; | ||
1050 | } | ||
1051 | |||
1052 | static const struct i2c_device_id pm2xxx_id[] = { | ||
1053 | { "pm2301", 0 }, | ||
1054 | { } | ||
1055 | }; | ||
1056 | |||
1057 | MODULE_DEVICE_TABLE(i2c, pm2xxx_id); | ||
1058 | |||
1059 | static struct i2c_driver pm2xxx_charger_driver = { | ||
1060 | .probe = pm2xxx_wall_charger_probe, | ||
1061 | .remove = __devexit_p(pm2xxx_wall_charger_remove), | ||
1062 | .suspend = pm2xxx_wall_charger_suspend, | ||
1063 | .resume = pm2xxx_wall_charger_resume, | ||
1064 | .driver = { | ||
1065 | .name = "pm2xxx-wall_charger", | ||
1066 | .owner = THIS_MODULE, | ||
1067 | }, | ||
1068 | .id_table = pm2xxx_id, | ||
1069 | }; | ||
1070 | |||
1071 | static int __init pm2xxx_charger_init(void) | ||
1072 | { | ||
1073 | return i2c_add_driver(&pm2xxx_charger_driver); | ||
1074 | } | ||
1075 | |||
1076 | static void __exit pm2xxx_charger_exit(void) | ||
1077 | { | ||
1078 | i2c_del_driver(&pm2xxx_charger_driver); | ||
1079 | } | ||
1080 | |||
1081 | subsys_initcall_sync(pm2xxx_charger_init); | ||
1082 | module_exit(pm2xxx_charger_exit); | ||
1083 | |||
1084 | MODULE_LICENSE("GPL v2"); | ||
1085 | MODULE_AUTHOR("Rajkumar kasirajan, Olivier Launay"); | ||
1086 | MODULE_ALIAS("platform:pm2xxx-charger"); | ||
1087 | MODULE_DESCRIPTION("PM2xxx charger management driver"); | ||
1088 | |||
diff --git a/drivers/power/pm2301_charger.h b/drivers/power/pm2301_charger.h new file mode 100644 index 000000000000..e6319cdbc94f --- /dev/null +++ b/drivers/power/pm2301_charger.h | |||
@@ -0,0 +1,513 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2012 | ||
3 | * | ||
4 | * PM2301 power supply interface | ||
5 | * | ||
6 | * License terms: GNU General Public License (GPL), version 2 | ||
7 | */ | ||
8 | |||
9 | #ifndef PM2301_CHARGER_H | ||
10 | #define PM2301_CHARGER_H | ||
11 | |||
12 | #define MAIN_WDOG_ENA 0x01 | ||
13 | #define MAIN_WDOG_KICK 0x02 | ||
14 | #define MAIN_WDOG_DIS 0x00 | ||
15 | #define CHARG_WD_KICK 0x01 | ||
16 | #define MAIN_CH_ENA 0x01 | ||
17 | #define MAIN_CH_NO_OVERSHOOT_ENA_N 0x02 | ||
18 | #define MAIN_CH_DET 0x01 | ||
19 | #define MAIN_CH_CV_ON 0x04 | ||
20 | #define OTP_ENABLE_WD 0x01 | ||
21 | |||
22 | #define MAIN_CH_INPUT_CURR_SHIFT 4 | ||
23 | |||
24 | #define LED_INDICATOR_PWM_ENA 0x01 | ||
25 | #define LED_INDICATOR_PWM_DIS 0x00 | ||
26 | #define LED_IND_CUR_5MA 0x04 | ||
27 | #define LED_INDICATOR_PWM_DUTY_252_256 0xBF | ||
28 | |||
29 | /* HW failure constants */ | ||
30 | #define MAIN_CH_TH_PROT 0x02 | ||
31 | #define MAIN_CH_NOK 0x01 | ||
32 | |||
33 | /* Watchdog timeout constant */ | ||
34 | #define WD_TIMER 0x30 /* 4min */ | ||
35 | #define WD_KICK_INTERVAL (30 * HZ) | ||
36 | |||
37 | #define PM2XXX_NUM_INT_REG 0x6 | ||
38 | |||
39 | /* Constant voltage/current */ | ||
40 | #define PM2XXX_CONST_CURR 0x0 | ||
41 | #define PM2XXX_CONST_VOLT 0x1 | ||
42 | |||
43 | /* Lowest charger voltage is 3.39V -> 0x4E */ | ||
44 | #define LOW_VOLT_REG 0x4E | ||
45 | |||
46 | #define PM2XXX_BATT_CTRL_REG1 0x00 | ||
47 | #define PM2XXX_BATT_CTRL_REG2 0x01 | ||
48 | #define PM2XXX_BATT_CTRL_REG3 0x02 | ||
49 | #define PM2XXX_BATT_CTRL_REG4 0x03 | ||
50 | #define PM2XXX_BATT_CTRL_REG5 0x04 | ||
51 | #define PM2XXX_BATT_CTRL_REG6 0x05 | ||
52 | #define PM2XXX_BATT_CTRL_REG7 0x06 | ||
53 | #define PM2XXX_BATT_CTRL_REG8 0x07 | ||
54 | #define PM2XXX_NTC_CTRL_REG1 0x08 | ||
55 | #define PM2XXX_NTC_CTRL_REG2 0x09 | ||
56 | #define PM2XXX_BATT_CTRL_REG9 0x0A | ||
57 | #define PM2XXX_BATT_STAT_REG1 0x0B | ||
58 | #define PM2XXX_INP_VOLT_VPWR2 0x11 | ||
59 | #define PM2XXX_INP_DROP_VPWR2 0x13 | ||
60 | #define PM2XXX_INP_VOLT_VPWR1 0x15 | ||
61 | #define PM2XXX_INP_DROP_VPWR1 0x17 | ||
62 | #define PM2XXX_INP_MODE_VPWR 0x18 | ||
63 | #define PM2XXX_BATT_WD_KICK 0x70 | ||
64 | #define PM2XXX_DEV_VER_STAT 0x0C | ||
65 | #define PM2XXX_THERM_WARN_CTRL_REG 0x20 | ||
66 | #define PM2XXX_BATT_DISC_REG 0x21 | ||
67 | #define PM2XXX_BATT_LOW_LEV_COMP_REG 0x22 | ||
68 | #define PM2XXX_BATT_LOW_LEV_VAL_REG 0x23 | ||
69 | #define PM2XXX_I2C_PAD_CTRL_REG 0x24 | ||
70 | #define PM2XXX_SW_CTRL_REG 0x26 | ||
71 | #define PM2XXX_LED_CTRL_REG 0x28 | ||
72 | |||
73 | #define PM2XXX_REG_INT1 0x40 | ||
74 | #define PM2XXX_MASK_REG_INT1 0x50 | ||
75 | #define PM2XXX_SRCE_REG_INT1 0x60 | ||
76 | #define PM2XXX_REG_INT2 0x41 | ||
77 | #define PM2XXX_MASK_REG_INT2 0x51 | ||
78 | #define PM2XXX_SRCE_REG_INT2 0x61 | ||
79 | #define PM2XXX_REG_INT3 0x42 | ||
80 | #define PM2XXX_MASK_REG_INT3 0x52 | ||
81 | #define PM2XXX_SRCE_REG_INT3 0x62 | ||
82 | #define PM2XXX_REG_INT4 0x43 | ||
83 | #define PM2XXX_MASK_REG_INT4 0x53 | ||
84 | #define PM2XXX_SRCE_REG_INT4 0x63 | ||
85 | #define PM2XXX_REG_INT5 0x44 | ||
86 | #define PM2XXX_MASK_REG_INT5 0x54 | ||
87 | #define PM2XXX_SRCE_REG_INT5 0x64 | ||
88 | #define PM2XXX_REG_INT6 0x45 | ||
89 | #define PM2XXX_MASK_REG_INT6 0x55 | ||
90 | #define PM2XXX_SRCE_REG_INT6 0x65 | ||
91 | |||
92 | #define VPWR_OVV 0x0 | ||
93 | #define VSYSTEM_OVV 0x1 | ||
94 | |||
95 | /* control Reg 1 */ | ||
96 | #define PM2XXX_CH_RESUME_EN 0x1 | ||
97 | #define PM2XXX_CH_RESUME_DIS 0x0 | ||
98 | |||
99 | /* control Reg 2 */ | ||
100 | #define PM2XXX_CH_AUTO_RESUME_EN 0X2 | ||
101 | #define PM2XXX_CH_AUTO_RESUME_DIS 0X0 | ||
102 | #define PM2XXX_CHARGER_ENA 0x4 | ||
103 | #define PM2XXX_CHARGER_DIS 0x0 | ||
104 | |||
105 | /* control Reg 3 */ | ||
106 | #define PM2XXX_CH_WD_CC_PHASE_OFF 0x0 | ||
107 | #define PM2XXX_CH_WD_CC_PHASE_5MIN 0x1 | ||
108 | #define PM2XXX_CH_WD_CC_PHASE_10MIN 0x2 | ||
109 | #define PM2XXX_CH_WD_CC_PHASE_30MIN 0x3 | ||
110 | #define PM2XXX_CH_WD_CC_PHASE_60MIN 0x4 | ||
111 | #define PM2XXX_CH_WD_CC_PHASE_120MIN 0x5 | ||
112 | #define PM2XXX_CH_WD_CC_PHASE_240MIN 0x6 | ||
113 | #define PM2XXX_CH_WD_CC_PHASE_360MIN 0x7 | ||
114 | |||
115 | #define PM2XXX_CH_WD_CV_PHASE_OFF (0x0<<3) | ||
116 | #define PM2XXX_CH_WD_CV_PHASE_5MIN (0x1<<3) | ||
117 | #define PM2XXX_CH_WD_CV_PHASE_10MIN (0x2<<3) | ||
118 | #define PM2XXX_CH_WD_CV_PHASE_30MIN (0x3<<3) | ||
119 | #define PM2XXX_CH_WD_CV_PHASE_60MIN (0x4<<3) | ||
120 | #define PM2XXX_CH_WD_CV_PHASE_120MIN (0x5<<3) | ||
121 | #define PM2XXX_CH_WD_CV_PHASE_240MIN (0x6<<3) | ||
122 | #define PM2XXX_CH_WD_CV_PHASE_360MIN (0x7<<3) | ||
123 | |||
124 | /* control Reg 4 */ | ||
125 | #define PM2XXX_CH_WD_PRECH_PHASE_OFF 0x0 | ||
126 | #define PM2XXX_CH_WD_PRECH_PHASE_1MIN 0x1 | ||
127 | #define PM2XXX_CH_WD_PRECH_PHASE_5MIN 0x2 | ||
128 | #define PM2XXX_CH_WD_PRECH_PHASE_10MIN 0x3 | ||
129 | #define PM2XXX_CH_WD_PRECH_PHASE_30MIN 0x4 | ||
130 | #define PM2XXX_CH_WD_PRECH_PHASE_60MIN 0x5 | ||
131 | #define PM2XXX_CH_WD_PRECH_PHASE_120MIN 0x6 | ||
132 | #define PM2XXX_CH_WD_PRECH_PHASE_240MIN 0x7 | ||
133 | |||
134 | /* control Reg 5 */ | ||
135 | #define PM2XXX_CH_WD_AUTO_TIMEOUT_NONE 0x0 | ||
136 | #define PM2XXX_CH_WD_AUTO_TIMEOUT_20MIN 0x1 | ||
137 | |||
138 | /* control Reg 6 */ | ||
139 | #define PM2XXX_DIR_CH_CC_CURRENT_MASK 0x0F | ||
140 | #define PM2XXX_DIR_CH_CC_CURRENT_200MA 0x0 | ||
141 | #define PM2XXX_DIR_CH_CC_CURRENT_400MA 0x2 | ||
142 | #define PM2XXX_DIR_CH_CC_CURRENT_600MA 0x3 | ||
143 | #define PM2XXX_DIR_CH_CC_CURRENT_800MA 0x4 | ||
144 | #define PM2XXX_DIR_CH_CC_CURRENT_1000MA 0x5 | ||
145 | #define PM2XXX_DIR_CH_CC_CURRENT_1200MA 0x6 | ||
146 | #define PM2XXX_DIR_CH_CC_CURRENT_1400MA 0x7 | ||
147 | #define PM2XXX_DIR_CH_CC_CURRENT_1600MA 0x8 | ||
148 | #define PM2XXX_DIR_CH_CC_CURRENT_1800MA 0x9 | ||
149 | #define PM2XXX_DIR_CH_CC_CURRENT_2000MA 0xA | ||
150 | #define PM2XXX_DIR_CH_CC_CURRENT_2200MA 0xB | ||
151 | #define PM2XXX_DIR_CH_CC_CURRENT_2400MA 0xC | ||
152 | #define PM2XXX_DIR_CH_CC_CURRENT_2600MA 0xD | ||
153 | #define PM2XXX_DIR_CH_CC_CURRENT_2800MA 0xE | ||
154 | #define PM2XXX_DIR_CH_CC_CURRENT_3000MA 0xF | ||
155 | |||
156 | #define PM2XXX_CH_PRECH_CURRENT_MASK 0x30 | ||
157 | #define PM2XXX_CH_PRECH_CURRENT_25MA (0x0<<4) | ||
158 | #define PM2XXX_CH_PRECH_CURRENT_50MA (0x1<<4) | ||
159 | #define PM2XXX_CH_PRECH_CURRENT_75MA (0x2<<4) | ||
160 | #define PM2XXX_CH_PRECH_CURRENT_100MA (0x3<<4) | ||
161 | |||
162 | #define PM2XXX_CH_EOC_CURRENT_MASK 0xC0 | ||
163 | #define PM2XXX_CH_EOC_CURRENT_100MA (0x0<<6) | ||
164 | #define PM2XXX_CH_EOC_CURRENT_150MA (0x1<<6) | ||
165 | #define PM2XXX_CH_EOC_CURRENT_300MA (0x2<<6) | ||
166 | #define PM2XXX_CH_EOC_CURRENT_400MA (0x3<<6) | ||
167 | |||
168 | /* control Reg 7 */ | ||
169 | #define PM2XXX_CH_PRECH_VOL_2_5 0x0 | ||
170 | #define PM2XXX_CH_PRECH_VOL_2_7 0x1 | ||
171 | #define PM2XXX_CH_PRECH_VOL_2_9 0x2 | ||
172 | #define PM2XXX_CH_PRECH_VOL_3_1 0x3 | ||
173 | |||
174 | #define PM2XXX_CH_VRESUME_VOL_3_2 (0x0<<2) | ||
175 | #define PM2XXX_CH_VRESUME_VOL_3_4 (0x1<<2) | ||
176 | #define PM2XXX_CH_VRESUME_VOL_3_6 (0x2<<2) | ||
177 | #define PM2XXX_CH_VRESUME_VOL_3_8 (0x3<<2) | ||
178 | |||
179 | /* control Reg 8 */ | ||
180 | #define PM2XXX_CH_VOLT_MASK 0x3F | ||
181 | #define PM2XXX_CH_VOLT_3_5 0x0 | ||
182 | #define PM2XXX_CH_VOLT_3_5225 0x1 | ||
183 | #define PM2XXX_CH_VOLT_3_6 0x4 | ||
184 | #define PM2XXX_CH_VOLT_3_7 0x8 | ||
185 | #define PM2XXX_CH_VOLT_4_0 0x14 | ||
186 | #define PM2XXX_CH_VOLT_4_175 0x1B | ||
187 | #define PM2XXX_CH_VOLT_4_2 0x1C | ||
188 | #define PM2XXX_CH_VOLT_4_275 0x1F | ||
189 | #define PM2XXX_CH_VOLT_4_3 0x20 | ||
190 | |||
191 | /*NTC control register 1*/ | ||
192 | #define PM2XXX_BTEMP_HIGH_TH_45 0x0 | ||
193 | #define PM2XXX_BTEMP_HIGH_TH_50 0x1 | ||
194 | #define PM2XXX_BTEMP_HIGH_TH_55 0x2 | ||
195 | #define PM2XXX_BTEMP_HIGH_TH_60 0x3 | ||
196 | #define PM2XXX_BTEMP_HIGH_TH_65 0x4 | ||
197 | |||
198 | #define PM2XXX_BTEMP_LOW_TH_N5 (0x0<<3) | ||
199 | #define PM2XXX_BTEMP_LOW_TH_0 (0x1<<3) | ||
200 | #define PM2XXX_BTEMP_LOW_TH_5 (0x2<<3) | ||
201 | #define PM2XXX_BTEMP_LOW_TH_10 (0x3<<3) | ||
202 | |||
203 | /*NTC control register 2*/ | ||
204 | #define PM2XXX_NTC_BETA_COEFF_3477 0x0 | ||
205 | #define PM2XXX_NTC_BETA_COEFF_3964 0x1 | ||
206 | |||
207 | #define PM2XXX_NTC_RES_10K (0x0<<2) | ||
208 | #define PM2XXX_NTC_RES_47K (0x1<<2) | ||
209 | #define PM2XXX_NTC_RES_100K (0x2<<2) | ||
210 | #define PM2XXX_NTC_RES_NO_NTC (0x3<<2) | ||
211 | |||
212 | /* control Reg 9 */ | ||
213 | #define PM2XXX_CH_CC_MODEDROP_EN 1 | ||
214 | #define PM2XXX_CH_CC_MODEDROP_DIS 0 | ||
215 | |||
216 | #define PM2XXX_CH_CC_REDUCED_CURRENT_100MA (0x0<<1) | ||
217 | #define PM2XXX_CH_CC_REDUCED_CURRENT_200MA (0x1<<1) | ||
218 | #define PM2XXX_CH_CC_REDUCED_CURRENT_400MA (0x2<<1) | ||
219 | #define PM2XXX_CH_CC_REDUCED_CURRENT_IDENT (0x3<<1) | ||
220 | |||
221 | #define PM2XXX_CHARCHING_INFO_DIS (0<<3) | ||
222 | #define PM2XXX_CHARCHING_INFO_EN (1<<3) | ||
223 | |||
224 | #define PM2XXX_CH_150MV_DROP_300MV (0<<4) | ||
225 | #define PM2XXX_CH_150MV_DROP_150MV (1<<4) | ||
226 | |||
227 | |||
228 | /* charger status register */ | ||
229 | #define PM2XXX_CHG_STATUS_OFF 0x0 | ||
230 | #define PM2XXX_CHG_STATUS_ON 0x1 | ||
231 | #define PM2XXX_CHG_STATUS_FULL 0x2 | ||
232 | #define PM2XXX_CHG_STATUS_ERR 0x3 | ||
233 | #define PM2XXX_CHG_STATUS_WAIT 0x4 | ||
234 | #define PM2XXX_CHG_STATUS_NOBAT 0x5 | ||
235 | |||
236 | /* Input charger voltage VPWR2 */ | ||
237 | #define PM2XXX_VPWR2_OVV_6_0 0x0 | ||
238 | #define PM2XXX_VPWR2_OVV_6_3 0x1 | ||
239 | #define PM2XXX_VPWR2_OVV_10 0x2 | ||
240 | #define PM2XXX_VPWR2_OVV_NONE 0x3 | ||
241 | |||
242 | /* Input charger drop VPWR2 */ | ||
243 | #define PM2XXX_VPWR2_HW_OPT_EN (0x1<<4) | ||
244 | #define PM2XXX_VPWR2_HW_OPT_DIS (0x0<<4) | ||
245 | |||
246 | #define PM2XXX_VPWR2_VALID_EN (0x1<<3) | ||
247 | #define PM2XXX_VPWR2_VALID_DIS (0x0<<3) | ||
248 | |||
249 | #define PM2XXX_VPWR2_DROP_EN (0x1<<2) | ||
250 | #define PM2XXX_VPWR2_DROP_DIS (0x0<<2) | ||
251 | |||
252 | /* Input charger voltage VPWR1 */ | ||
253 | #define PM2XXX_VPWR1_OVV_6_0 0x0 | ||
254 | #define PM2XXX_VPWR1_OVV_6_3 0x1 | ||
255 | #define PM2XXX_VPWR1_OVV_10 0x2 | ||
256 | #define PM2XXX_VPWR1_OVV_NONE 0x3 | ||
257 | |||
258 | /* Input charger drop VPWR1 */ | ||
259 | #define PM2XXX_VPWR1_HW_OPT_EN (0x1<<4) | ||
260 | #define PM2XXX_VPWR1_HW_OPT_DIS (0x0<<4) | ||
261 | |||
262 | #define PM2XXX_VPWR1_VALID_EN (0x1<<3) | ||
263 | #define PM2XXX_VPWR1_VALID_DIS (0x0<<3) | ||
264 | |||
265 | #define PM2XXX_VPWR1_DROP_EN (0x1<<2) | ||
266 | #define PM2XXX_VPWR1_DROP_DIS (0x0<<2) | ||
267 | |||
268 | /* Battery low level comparator control register */ | ||
269 | #define PM2XXX_VBAT_LOW_MONITORING_DIS 0x0 | ||
270 | #define PM2XXX_VBAT_LOW_MONITORING_ENA 0x1 | ||
271 | |||
272 | /* Battery low level value control register */ | ||
273 | #define PM2XXX_VBAT_LOW_LEVEL_2_3 0x0 | ||
274 | #define PM2XXX_VBAT_LOW_LEVEL_2_4 0x1 | ||
275 | #define PM2XXX_VBAT_LOW_LEVEL_2_5 0x2 | ||
276 | #define PM2XXX_VBAT_LOW_LEVEL_2_6 0x3 | ||
277 | #define PM2XXX_VBAT_LOW_LEVEL_2_7 0x4 | ||
278 | #define PM2XXX_VBAT_LOW_LEVEL_2_8 0x5 | ||
279 | #define PM2XXX_VBAT_LOW_LEVEL_2_9 0x6 | ||
280 | #define PM2XXX_VBAT_LOW_LEVEL_3_0 0x7 | ||
281 | #define PM2XXX_VBAT_LOW_LEVEL_3_1 0x8 | ||
282 | #define PM2XXX_VBAT_LOW_LEVEL_3_2 0x9 | ||
283 | #define PM2XXX_VBAT_LOW_LEVEL_3_3 0xA | ||
284 | #define PM2XXX_VBAT_LOW_LEVEL_3_4 0xB | ||
285 | #define PM2XXX_VBAT_LOW_LEVEL_3_5 0xC | ||
286 | #define PM2XXX_VBAT_LOW_LEVEL_3_6 0xD | ||
287 | #define PM2XXX_VBAT_LOW_LEVEL_3_7 0xE | ||
288 | #define PM2XXX_VBAT_LOW_LEVEL_3_8 0xF | ||
289 | #define PM2XXX_VBAT_LOW_LEVEL_3_9 0x10 | ||
290 | #define PM2XXX_VBAT_LOW_LEVEL_4_0 0x11 | ||
291 | #define PM2XXX_VBAT_LOW_LEVEL_4_1 0x12 | ||
292 | #define PM2XXX_VBAT_LOW_LEVEL_4_2 0x13 | ||
293 | |||
294 | /* SW CTRL */ | ||
295 | #define PM2XXX_SWCTRL_HW 0x0 | ||
296 | #define PM2XXX_SWCTRL_SW 0x1 | ||
297 | |||
298 | |||
299 | /* LED Driver Control */ | ||
300 | #define PM2XXX_LED_CURRENT_MASK 0x0C | ||
301 | #define PM2XXX_LED_CURRENT_2_5MA (0X0<<2) | ||
302 | #define PM2XXX_LED_CURRENT_1MA (0X1<<2) | ||
303 | #define PM2XXX_LED_CURRENT_5MA (0X2<<2) | ||
304 | #define PM2XXX_LED_CURRENT_10MA (0X3<<2) | ||
305 | |||
306 | #define PM2XXX_LED_SELECT_MASK 0x02 | ||
307 | #define PM2XXX_LED_SELECT_EN (0X0<<1) | ||
308 | #define PM2XXX_LED_SELECT_DIS (0X1<<1) | ||
309 | |||
310 | #define PM2XXX_ANTI_OVERSHOOT_MASK 0x01 | ||
311 | #define PM2XXX_ANTI_OVERSHOOT_DIS 0X0 | ||
312 | #define PM2XXX_ANTI_OVERSHOOT_EN 0X1 | ||
313 | |||
314 | enum pm2xxx_reg_int1 { | ||
315 | PM2XXX_INT1_ITVBATDISCONNECT = 0x02, | ||
316 | PM2XXX_INT1_ITVBATLOWR = 0x04, | ||
317 | PM2XXX_INT1_ITVBATLOWF = 0x08, | ||
318 | }; | ||
319 | |||
320 | enum pm2xxx_mask_reg_int1 { | ||
321 | PM2XXX_INT1_M_ITVBATDISCONNECT = 0x02, | ||
322 | PM2XXX_INT1_M_ITVBATLOWR = 0x04, | ||
323 | PM2XXX_INT1_M_ITVBATLOWF = 0x08, | ||
324 | }; | ||
325 | |||
326 | enum pm2xxx_source_reg_int1 { | ||
327 | PM2XXX_INT1_S_ITVBATDISCONNECT = 0x02, | ||
328 | PM2XXX_INT1_S_ITVBATLOWR = 0x04, | ||
329 | PM2XXX_INT1_S_ITVBATLOWF = 0x08, | ||
330 | }; | ||
331 | |||
332 | enum pm2xxx_reg_int2 { | ||
333 | PM2XXX_INT2_ITVPWR2PLUG = 0x01, | ||
334 | PM2XXX_INT2_ITVPWR2UNPLUG = 0x02, | ||
335 | PM2XXX_INT2_ITVPWR1PLUG = 0x04, | ||
336 | PM2XXX_INT2_ITVPWR1UNPLUG = 0x08, | ||
337 | }; | ||
338 | |||
339 | enum pm2xxx_mask_reg_int2 { | ||
340 | PM2XXX_INT2_M_ITVPWR2PLUG = 0x01, | ||
341 | PM2XXX_INT2_M_ITVPWR2UNPLUG = 0x02, | ||
342 | PM2XXX_INT2_M_ITVPWR1PLUG = 0x04, | ||
343 | PM2XXX_INT2_M_ITVPWR1UNPLUG = 0x08, | ||
344 | }; | ||
345 | |||
346 | enum pm2xxx_source_reg_int2 { | ||
347 | PM2XXX_INT2_S_ITVPWR2PLUG = 0x03, | ||
348 | PM2XXX_INT2_S_ITVPWR1PLUG = 0x0c, | ||
349 | }; | ||
350 | |||
351 | enum pm2xxx_reg_int3 { | ||
352 | PM2XXX_INT3_ITCHPRECHARGEWD = 0x01, | ||
353 | PM2XXX_INT3_ITCHCCWD = 0x02, | ||
354 | PM2XXX_INT3_ITCHCVWD = 0x04, | ||
355 | PM2XXX_INT3_ITAUTOTIMEOUTWD = 0x08, | ||
356 | }; | ||
357 | |||
358 | enum pm2xxx_mask_reg_int3 { | ||
359 | PM2XXX_INT3_M_ITCHPRECHARGEWD = 0x01, | ||
360 | PM2XXX_INT3_M_ITCHCCWD = 0x02, | ||
361 | PM2XXX_INT3_M_ITCHCVWD = 0x04, | ||
362 | PM2XXX_INT3_M_ITAUTOTIMEOUTWD = 0x08, | ||
363 | }; | ||
364 | |||
365 | enum pm2xxx_source_reg_int3 { | ||
366 | PM2XXX_INT3_S_ITCHPRECHARGEWD = 0x01, | ||
367 | PM2XXX_INT3_S_ITCHCCWD = 0x02, | ||
368 | PM2XXX_INT3_S_ITCHCVWD = 0x04, | ||
369 | PM2XXX_INT3_S_ITAUTOTIMEOUTWD = 0x08, | ||
370 | }; | ||
371 | |||
372 | enum pm2xxx_reg_int4 { | ||
373 | PM2XXX_INT4_ITBATTEMPCOLD = 0x01, | ||
374 | PM2XXX_INT4_ITBATTEMPHOT = 0x02, | ||
375 | PM2XXX_INT4_ITVPWR2OVV = 0x04, | ||
376 | PM2XXX_INT4_ITVPWR1OVV = 0x08, | ||
377 | PM2XXX_INT4_ITCHARGINGON = 0x10, | ||
378 | PM2XXX_INT4_ITVRESUME = 0x20, | ||
379 | PM2XXX_INT4_ITBATTFULL = 0x40, | ||
380 | PM2XXX_INT4_ITCVPHASE = 0x80, | ||
381 | }; | ||
382 | |||
383 | enum pm2xxx_mask_reg_int4 { | ||
384 | PM2XXX_INT4_M_ITBATTEMPCOLD = 0x01, | ||
385 | PM2XXX_INT4_M_ITBATTEMPHOT = 0x02, | ||
386 | PM2XXX_INT4_M_ITVPWR2OVV = 0x04, | ||
387 | PM2XXX_INT4_M_ITVPWR1OVV = 0x08, | ||
388 | PM2XXX_INT4_M_ITCHARGINGON = 0x10, | ||
389 | PM2XXX_INT4_M_ITVRESUME = 0x20, | ||
390 | PM2XXX_INT4_M_ITBATTFULL = 0x40, | ||
391 | PM2XXX_INT4_M_ITCVPHASE = 0x80, | ||
392 | }; | ||
393 | |||
394 | enum pm2xxx_source_reg_int4 { | ||
395 | PM2XXX_INT4_S_ITBATTEMPCOLD = 0x01, | ||
396 | PM2XXX_INT4_S_ITBATTEMPHOT = 0x02, | ||
397 | PM2XXX_INT4_S_ITVPWR2OVV = 0x04, | ||
398 | PM2XXX_INT4_S_ITVPWR1OVV = 0x08, | ||
399 | PM2XXX_INT4_S_ITCHARGINGON = 0x10, | ||
400 | PM2XXX_INT4_S_ITVRESUME = 0x20, | ||
401 | PM2XXX_INT4_S_ITBATTFULL = 0x40, | ||
402 | PM2XXX_INT4_S_ITCVPHASE = 0x80, | ||
403 | }; | ||
404 | |||
405 | enum pm2xxx_reg_int5 { | ||
406 | PM2XXX_INT5_ITTHERMALSHUTDOWNRISE = 0x01, | ||
407 | PM2XXX_INT5_ITTHERMALSHUTDOWNFALL = 0x02, | ||
408 | PM2XXX_INT5_ITTHERMALWARNINGRISE = 0x04, | ||
409 | PM2XXX_INT5_ITTHERMALWARNINGFALL = 0x08, | ||
410 | PM2XXX_INT5_ITVSYSTEMOVV = 0x10, | ||
411 | }; | ||
412 | |||
413 | enum pm2xxx_mask_reg_int5 { | ||
414 | PM2XXX_INT5_M_ITTHERMALSHUTDOWNRISE = 0x01, | ||
415 | PM2XXX_INT5_M_ITTHERMALSHUTDOWNFALL = 0x02, | ||
416 | PM2XXX_INT5_M_ITTHERMALWARNINGRISE = 0x04, | ||
417 | PM2XXX_INT5_M_ITTHERMALWARNINGFALL = 0x08, | ||
418 | PM2XXX_INT5_M_ITVSYSTEMOVV = 0x10, | ||
419 | }; | ||
420 | |||
421 | enum pm2xxx_source_reg_int5 { | ||
422 | PM2XXX_INT5_S_ITTHERMALSHUTDOWNRISE = 0x01, | ||
423 | PM2XXX_INT5_S_ITTHERMALSHUTDOWNFALL = 0x02, | ||
424 | PM2XXX_INT5_S_ITTHERMALWARNINGRISE = 0x04, | ||
425 | PM2XXX_INT5_S_ITTHERMALWARNINGFALL = 0x08, | ||
426 | PM2XXX_INT5_S_ITVSYSTEMOVV = 0x10, | ||
427 | }; | ||
428 | |||
429 | enum pm2xxx_reg_int6 { | ||
430 | PM2XXX_INT6_ITVPWR2DROP = 0x01, | ||
431 | PM2XXX_INT6_ITVPWR1DROP = 0x02, | ||
432 | PM2XXX_INT6_ITVPWR2VALIDRISE = 0x04, | ||
433 | PM2XXX_INT6_ITVPWR2VALIDFALL = 0x08, | ||
434 | PM2XXX_INT6_ITVPWR1VALIDRISE = 0x10, | ||
435 | PM2XXX_INT6_ITVPWR1VALIDFALL = 0x20, | ||
436 | }; | ||
437 | |||
438 | enum pm2xxx_mask_reg_int6 { | ||
439 | PM2XXX_INT6_M_ITVPWR2DROP = 0x01, | ||
440 | PM2XXX_INT6_M_ITVPWR1DROP = 0x02, | ||
441 | PM2XXX_INT6_M_ITVPWR2VALIDRISE = 0x04, | ||
442 | PM2XXX_INT6_M_ITVPWR2VALIDFALL = 0x08, | ||
443 | PM2XXX_INT6_M_ITVPWR1VALIDRISE = 0x10, | ||
444 | PM2XXX_INT6_M_ITVPWR1VALIDFALL = 0x20, | ||
445 | }; | ||
446 | |||
447 | enum pm2xxx_source_reg_int6 { | ||
448 | PM2XXX_INT6_S_ITVPWR2DROP = 0x01, | ||
449 | PM2XXX_INT6_S_ITVPWR1DROP = 0x02, | ||
450 | PM2XXX_INT6_S_ITVPWR2VALIDRISE = 0x04, | ||
451 | PM2XXX_INT6_S_ITVPWR2VALIDFALL = 0x08, | ||
452 | PM2XXX_INT6_S_ITVPWR1VALIDRISE = 0x10, | ||
453 | PM2XXX_INT6_S_ITVPWR1VALIDFALL = 0x20, | ||
454 | }; | ||
455 | |||
456 | struct pm2xxx_charger_info { | ||
457 | int charger_connected; | ||
458 | int charger_online; | ||
459 | int cv_active; | ||
460 | bool wd_expired; | ||
461 | }; | ||
462 | |||
463 | struct pm2xxx_charger_event_flags { | ||
464 | bool mainextchnotok; | ||
465 | bool main_thermal_prot; | ||
466 | bool ovv; | ||
467 | bool chgwdexp; | ||
468 | }; | ||
469 | |||
470 | struct pm2xxx_interrupts { | ||
471 | u8 reg[PM2XXX_NUM_INT_REG]; | ||
472 | int (*handler[PM2XXX_NUM_INT_REG])(void *, int); | ||
473 | }; | ||
474 | |||
475 | struct pm2xxx_config { | ||
476 | struct i2c_client *pm2xxx_i2c; | ||
477 | struct i2c_device_id *pm2xxx_id; | ||
478 | }; | ||
479 | |||
480 | struct pm2xxx_irq { | ||
481 | char *name; | ||
482 | irqreturn_t (*isr)(int irq, void *data); | ||
483 | }; | ||
484 | |||
485 | struct pm2xxx_charger { | ||
486 | struct device *dev; | ||
487 | u8 chip_id; | ||
488 | bool vddadc_en_ac; | ||
489 | struct pm2xxx_config config; | ||
490 | bool ac_conn; | ||
491 | unsigned int gpio_irq; | ||
492 | int vbat; | ||
493 | int old_vbat; | ||
494 | int failure_case; | ||
495 | int failure_input_ovv; | ||
496 | unsigned int lpn_pin; | ||
497 | struct pm2xxx_interrupts *pm2_int; | ||
498 | struct ab8500_gpadc *gpadc; | ||
499 | struct regulator *regu; | ||
500 | struct pm2xxx_bm_data *bat; | ||
501 | struct mutex lock; | ||
502 | struct ab8500 *parent; | ||
503 | struct pm2xxx_charger_info ac; | ||
504 | struct pm2xxx_charger_platform_data *pdata; | ||
505 | struct workqueue_struct *charger_wq; | ||
506 | struct delayed_work check_vbat_work; | ||
507 | struct work_struct ac_work; | ||
508 | struct work_struct check_main_thermal_prot_work; | ||
509 | struct ux500_charger ac_chg; | ||
510 | struct pm2xxx_charger_event_flags flags; | ||
511 | }; | ||
512 | |||
513 | #endif /* PM2301_CHARGER_H */ | ||