diff options
author | Olivier Clergeaud <olivier.clergeaud@stericsson.com> | 2012-05-14 10:50:29 -0400 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2013-01-23 09:39:13 -0500 |
commit | 006f82d67cba34d44adcfd0b3698836ffc463d85 (patch) | |
tree | 7fe7f9caef55fb4210c6f4046d7504bd7a82f120 /drivers/power | |
parent | 2fa5b0f4a5fff1fe77665ac380ca4322df42fe8d (diff) |
pm2301: Clean-up PM2301 interrupt management
Fix the way interrupts are handled within the PM2301 charging driver.
Signed-off-by: Rajkumar Kasirajan <rajkumar.kasirajan@stericsson.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Olivier CLERGEAUD <olivier.clergeaud@stericsson.com>
Reviewed-by: Marcus COOPER <marcus.xm.cooper@stericsson.com>
Reviewed-by: Michel JAOUEN <michel.jaouen@stericsson.com>
Tested-by: Michel JAOUEN <michel.jaouen@stericsson.com>
Diffstat (limited to 'drivers/power')
-rw-r--r-- | drivers/power/pm2301_charger.c | 173 | ||||
-rw-r--r-- | drivers/power/pm2301_charger.h | 29 |
2 files changed, 148 insertions, 54 deletions
diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index e7a360a0426f..7d2ec541ba7f 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c | |||
@@ -224,7 +224,7 @@ static int pm2xxx_charger_bat_disc_mngt(struct pm2xxx_charger *pm2, int val) | |||
224 | { | 224 | { |
225 | dev_dbg(pm2->dev, "battery disconnected\n"); | 225 | dev_dbg(pm2->dev, "battery disconnected\n"); |
226 | 226 | ||
227 | return (pm2xxx_charging_disable_mngt(pm2)); | 227 | return 0; |
228 | } | 228 | } |
229 | 229 | ||
230 | static int pm2xxx_charger_detection(struct pm2xxx_charger *pm2, u8 *val) | 230 | static int pm2xxx_charger_detection(struct pm2xxx_charger *pm2, u8 *val) |
@@ -275,17 +275,17 @@ static int pm2xxx_charger_itv_pwr_unplug_mngt(struct pm2xxx_charger *pm2, | |||
275 | return 0; | 275 | return 0; |
276 | } | 276 | } |
277 | 277 | ||
278 | static int pm2_int_reg0(struct pm2xxx_charger *pm2) | 278 | static int pm2_int_reg0(void *pm2_data, int val) |
279 | { | 279 | { |
280 | struct pm2xxx_charger *pm2 = pm2_data; | ||
280 | int ret = 0; | 281 | int ret = 0; |
281 | 282 | ||
282 | if (pm2->pm2_int[0] & | 283 | if (val & (PM2XXX_INT1_ITVBATLOWR | PM2XXX_INT1_ITVBATLOWF)) { |
283 | (PM2XXX_INT1_ITVBATLOWR | PM2XXX_INT1_ITVBATLOWF)) { | 284 | ret = pm2xxx_charger_vbat_lsig_mngt(pm2, val & |
284 | ret = pm2xxx_charger_vbat_lsig_mngt(pm2, pm2->pm2_int[0] & | ||
285 | (PM2XXX_INT1_ITVBATLOWR | PM2XXX_INT1_ITVBATLOWF)); | 285 | (PM2XXX_INT1_ITVBATLOWR | PM2XXX_INT1_ITVBATLOWF)); |
286 | } | 286 | } |
287 | 287 | ||
288 | if (pm2->pm2_int[0] & PM2XXX_INT1_ITVBATDISCONNECT) { | 288 | if (val & PM2XXX_INT1_ITVBATDISCONNECT) { |
289 | ret = pm2xxx_charger_bat_disc_mngt(pm2, | 289 | ret = pm2xxx_charger_bat_disc_mngt(pm2, |
290 | PM2XXX_INT1_ITVBATDISCONNECT); | 290 | PM2XXX_INT1_ITVBATDISCONNECT); |
291 | } | 291 | } |
@@ -293,21 +293,21 @@ static int pm2_int_reg0(struct pm2xxx_charger *pm2) | |||
293 | return ret; | 293 | return ret; |
294 | } | 294 | } |
295 | 295 | ||
296 | static int pm2_int_reg1(struct pm2xxx_charger *pm2) | 296 | static int pm2_int_reg1(void *pm2_data, int val) |
297 | { | 297 | { |
298 | struct pm2xxx_charger *pm2 = pm2_data; | ||
298 | int ret = 0; | 299 | int ret = 0; |
299 | 300 | ||
300 | if (pm2->pm2_int[1] & | 301 | if (val & (PM2XXX_INT2_ITVPWR1PLUG | PM2XXX_INT2_ITVPWR2PLUG)) { |
301 | (PM2XXX_INT2_ITVPWR1PLUG | PM2XXX_INT2_ITVPWR2PLUG)) { | ||
302 | dev_dbg(pm2->dev , "Main charger plugged\n"); | 302 | dev_dbg(pm2->dev , "Main charger plugged\n"); |
303 | ret = pm2xxx_charger_itv_pwr_plug_mngt(pm2, pm2->pm2_int[1] & | 303 | ret = pm2xxx_charger_itv_pwr_plug_mngt(pm2, val & |
304 | (PM2XXX_INT2_ITVPWR1PLUG | PM2XXX_INT2_ITVPWR2PLUG)); | 304 | (PM2XXX_INT2_ITVPWR1PLUG | PM2XXX_INT2_ITVPWR2PLUG)); |
305 | } | 305 | } |
306 | 306 | ||
307 | if (pm2->pm2_int[1] & | 307 | if (val & |
308 | (PM2XXX_INT2_ITVPWR1UNPLUG | PM2XXX_INT2_ITVPWR2UNPLUG)) { | 308 | (PM2XXX_INT2_ITVPWR1UNPLUG | PM2XXX_INT2_ITVPWR2UNPLUG)) { |
309 | dev_dbg(pm2->dev , "Main charger unplugged\n"); | 309 | dev_dbg(pm2->dev , "Main charger unplugged\n"); |
310 | ret = pm2xxx_charger_itv_pwr_unplug_mngt(pm2, pm2->pm2_int[1] & | 310 | ret = pm2xxx_charger_itv_pwr_unplug_mngt(pm2, val & |
311 | (PM2XXX_INT2_ITVPWR1UNPLUG | | 311 | (PM2XXX_INT2_ITVPWR1UNPLUG | |
312 | PM2XXX_INT2_ITVPWR2UNPLUG)); | 312 | PM2XXX_INT2_ITVPWR2UNPLUG)); |
313 | } | 313 | } |
@@ -315,14 +315,15 @@ static int pm2_int_reg1(struct pm2xxx_charger *pm2) | |||
315 | return ret; | 315 | return ret; |
316 | } | 316 | } |
317 | 317 | ||
318 | static int pm2_int_reg2(struct pm2xxx_charger *pm2) | 318 | static int pm2_int_reg2(void *pm2_data, int val) |
319 | { | 319 | { |
320 | struct pm2xxx_charger *pm2 = pm2_data; | ||
320 | int ret = 0; | 321 | int ret = 0; |
321 | 322 | ||
322 | if (pm2->pm2_int[2] & PM2XXX_INT3_ITAUTOTIMEOUTWD) | 323 | if (val & PM2XXX_INT3_ITAUTOTIMEOUTWD) |
323 | ret = pm2xxx_charger_wd_exp_mngt(pm2, pm2->pm2_int[2]); | 324 | ret = pm2xxx_charger_wd_exp_mngt(pm2, val); |
324 | 325 | ||
325 | if (pm2->pm2_int[2] & (PM2XXX_INT3_ITCHPRECHARGEWD | | 326 | if (val & (PM2XXX_INT3_ITCHPRECHARGEWD | |
326 | PM2XXX_INT3_ITCHCCWD | PM2XXX_INT3_ITCHCVWD)) { | 327 | PM2XXX_INT3_ITCHCCWD | PM2XXX_INT3_ITCHCVWD)) { |
327 | dev_dbg(pm2->dev, | 328 | dev_dbg(pm2->dev, |
328 | "Watchdog occured for precharge, CC and CV charge\n"); | 329 | "Watchdog occured for precharge, CC and CV charge\n"); |
@@ -331,64 +332,65 @@ static int pm2_int_reg2(struct pm2xxx_charger *pm2) | |||
331 | return ret; | 332 | return ret; |
332 | } | 333 | } |
333 | 334 | ||
334 | static int pm2_int_reg3(struct pm2xxx_charger *pm2) | 335 | static int pm2_int_reg3(void *pm2_data, int val) |
335 | { | 336 | { |
337 | struct pm2xxx_charger *pm2 = pm2_data; | ||
336 | int ret = 0; | 338 | int ret = 0; |
337 | 339 | ||
338 | if (pm2->pm2_int[3] & (PM2XXX_INT4_ITCHARGINGON)) { | 340 | if (val & (PM2XXX_INT4_ITCHARGINGON)) { |
339 | dev_dbg(pm2->dev , | 341 | dev_dbg(pm2->dev , |
340 | "chargind operation has started\n"); | 342 | "chargind operation has started\n"); |
341 | } | 343 | } |
342 | 344 | ||
343 | if (pm2->pm2_int[3] & (PM2XXX_INT4_ITVRESUME)) { | 345 | if (val & (PM2XXX_INT4_ITVRESUME)) { |
344 | dev_dbg(pm2->dev, | 346 | dev_dbg(pm2->dev, |
345 | "battery discharged down to VResume threshold\n"); | 347 | "battery discharged down to VResume threshold\n"); |
346 | } | 348 | } |
347 | 349 | ||
348 | if (pm2->pm2_int[3] & (PM2XXX_INT4_ITBATTFULL)) { | 350 | if (val & (PM2XXX_INT4_ITBATTFULL)) { |
349 | dev_dbg(pm2->dev , "battery fully detected\n"); | 351 | dev_dbg(pm2->dev , "battery fully detected\n"); |
350 | } | 352 | } |
351 | 353 | ||
352 | if (pm2->pm2_int[3] & (PM2XXX_INT4_ITCVPHASE)) { | 354 | if (val & (PM2XXX_INT4_ITCVPHASE)) { |
353 | dev_dbg(pm2->dev, "CV phase enter with 0.5C charging\n"); | 355 | dev_dbg(pm2->dev, "CV phase enter with 0.5C charging\n"); |
354 | } | 356 | } |
355 | 357 | ||
356 | if (pm2->pm2_int[3] & | 358 | if (val & (PM2XXX_INT4_ITVPWR2OVV | PM2XXX_INT4_ITVPWR1OVV)) { |
357 | (PM2XXX_INT4_ITVPWR2OVV | PM2XXX_INT4_ITVPWR1OVV)) { | ||
358 | pm2->failure_case = VPWR_OVV; | 359 | pm2->failure_case = VPWR_OVV; |
359 | ret = pm2xxx_charger_ovv_mngt(pm2, pm2->pm2_int[3] & | 360 | ret = pm2xxx_charger_ovv_mngt(pm2, val & |
360 | (PM2XXX_INT4_ITVPWR2OVV | PM2XXX_INT4_ITVPWR1OVV)); | 361 | (PM2XXX_INT4_ITVPWR2OVV | PM2XXX_INT4_ITVPWR1OVV)); |
361 | dev_dbg(pm2->dev, "VPWR/VSYSTEM overvoltage detected\n"); | 362 | dev_dbg(pm2->dev, "VPWR/VSYSTEM overvoltage detected\n"); |
362 | } | 363 | } |
363 | 364 | ||
364 | if (pm2->pm2_int[3] & (PM2XXX_INT4_S_ITBATTEMPCOLD | | 365 | if (val & (PM2XXX_INT4_S_ITBATTEMPCOLD | |
365 | PM2XXX_INT4_S_ITBATTEMPHOT)) { | 366 | PM2XXX_INT4_S_ITBATTEMPHOT)) { |
366 | ret = pm2xxx_charger_batt_therm_mngt(pm2, | 367 | ret = pm2xxx_charger_batt_therm_mngt(pm2, val & |
367 | pm2->pm2_int[3] & (PM2XXX_INT4_S_ITBATTEMPCOLD | | 368 | (PM2XXX_INT4_S_ITBATTEMPCOLD | |
368 | PM2XXX_INT4_S_ITBATTEMPHOT)); | 369 | PM2XXX_INT4_S_ITBATTEMPHOT)); |
369 | dev_dbg(pm2->dev, "BTEMP is too Low/High\n"); | 370 | dev_dbg(pm2->dev, "BTEMP is too Low/High\n"); |
370 | } | 371 | } |
371 | 372 | ||
372 | return ret; | 373 | return ret; |
373 | } | 374 | } |
374 | 375 | ||
375 | static int pm2_int_reg4(struct pm2xxx_charger *pm2) | 376 | static int pm2_int_reg4(void *pm2_data, int val) |
376 | { | 377 | { |
378 | struct pm2xxx_charger *pm2 = pm2_data; | ||
377 | int ret = 0; | 379 | int ret = 0; |
378 | 380 | ||
379 | if (pm2->pm2_int[4] & PM2XXX_INT5_ITVSYSTEMOVV) { | 381 | if (val & PM2XXX_INT5_ITVSYSTEMOVV) { |
380 | pm2->failure_case = VSYSTEM_OVV; | 382 | pm2->failure_case = VSYSTEM_OVV; |
381 | ret = pm2xxx_charger_ovv_mngt(pm2, pm2->pm2_int[4] & | 383 | ret = pm2xxx_charger_ovv_mngt(pm2, val & |
382 | PM2XXX_INT5_ITVSYSTEMOVV); | 384 | PM2XXX_INT5_ITVSYSTEMOVV); |
383 | dev_dbg(pm2->dev, "VSYSTEM overvoltage detected\n"); | 385 | dev_dbg(pm2->dev, "VSYSTEM overvoltage detected\n"); |
384 | } | 386 | } |
385 | 387 | ||
386 | if (pm2->pm2_int[4] & (PM2XXX_INT5_ITTHERMALWARNINGFALL | | 388 | if (val & (PM2XXX_INT5_ITTHERMALWARNINGFALL | |
387 | PM2XXX_INT5_ITTHERMALWARNINGRISE | | 389 | PM2XXX_INT5_ITTHERMALWARNINGRISE | |
388 | PM2XXX_INT5_ITTHERMALSHUTDOWNFALL | | 390 | PM2XXX_INT5_ITTHERMALSHUTDOWNFALL | |
389 | PM2XXX_INT5_ITTHERMALSHUTDOWNRISE)) { | 391 | PM2XXX_INT5_ITTHERMALSHUTDOWNRISE)) { |
390 | dev_dbg(pm2->dev, "BTEMP die temperature is too Low/High\n"); | 392 | dev_dbg(pm2->dev, "BTEMP die temperature is too Low/High\n"); |
391 | ret = pm2xxx_charger_die_therm_mngt(pm2, pm2->pm2_int[4] & | 393 | ret = pm2xxx_charger_die_therm_mngt(pm2, val & |
392 | (PM2XXX_INT5_ITTHERMALWARNINGFALL | | 394 | (PM2XXX_INT5_ITTHERMALWARNINGFALL | |
393 | PM2XXX_INT5_ITTHERMALWARNINGRISE | | 395 | PM2XXX_INT5_ITTHERMALWARNINGRISE | |
394 | PM2XXX_INT5_ITTHERMALSHUTDOWNFALL | | 396 | PM2XXX_INT5_ITTHERMALSHUTDOWNFALL | |
@@ -398,40 +400,40 @@ static int pm2_int_reg4(struct pm2xxx_charger *pm2) | |||
398 | return ret; | 400 | return ret; |
399 | } | 401 | } |
400 | 402 | ||
401 | static int pm2_int_reg5(struct pm2xxx_charger *pm2) | 403 | static int pm2_int_reg5(void *pm2_data, int val) |
402 | { | 404 | { |
405 | struct pm2xxx_charger *pm2 = pm2_data; | ||
406 | int ret = 0; | ||
407 | |||
403 | 408 | ||
404 | if (pm2->pm2_int[5] | 409 | if (val & (PM2XXX_INT6_ITVPWR2DROP | PM2XXX_INT6_ITVPWR1DROP)) { |
405 | & (PM2XXX_INT6_ITVPWR2DROP | PM2XXX_INT6_ITVPWR1DROP)) { | ||
406 | dev_dbg(pm2->dev, "VMPWR drop to VBAT level\n"); | 410 | dev_dbg(pm2->dev, "VMPWR drop to VBAT level\n"); |
407 | } | 411 | } |
408 | 412 | ||
409 | if (pm2->pm2_int[5] & (PM2XXX_INT6_ITVPWR2VALIDRISE | | 413 | if (val & (PM2XXX_INT6_ITVPWR2VALIDRISE | |
410 | PM2XXX_INT6_ITVPWR1VALIDRISE | | 414 | PM2XXX_INT6_ITVPWR1VALIDRISE | |
411 | PM2XXX_INT6_ITVPWR2VALIDFALL | | 415 | PM2XXX_INT6_ITVPWR2VALIDFALL | |
412 | PM2XXX_INT6_ITVPWR1VALIDFALL)) { | 416 | PM2XXX_INT6_ITVPWR1VALIDFALL)) { |
413 | dev_dbg(pm2->dev, "Falling/Rising edge on WPWR1/2\n"); | 417 | dev_dbg(pm2->dev, "Falling/Rising edge on WPWR1/2\n"); |
414 | } | 418 | } |
415 | 419 | ||
416 | return 0; | 420 | return ret; |
417 | } | 421 | } |
418 | 422 | ||
419 | static irqreturn_t pm2xxx_irq_int(int irq, void *data) | 423 | static irqreturn_t pm2xxx_irq_int(int irq, void *data) |
420 | { | 424 | { |
421 | struct pm2xxx_charger *pm2 = data; | 425 | struct pm2xxx_charger *pm2 = data; |
422 | int ret, i; | 426 | struct pm2xxx_interrupts *interrupt = pm2->pm2_int; |
427 | int i; | ||
423 | 428 | ||
424 | for (i = 0; i < ARRAY_SIZE(pm2->pm2_int); i++) { | 429 | for (i = 0; i < PM2XXX_NUM_INT_REG; i++) { |
425 | ret = pm2xxx_reg_read(pm2, pm2xxx_interrupt_registers[i], | 430 | pm2xxx_reg_read(pm2, |
426 | &(pm2->pm2_int[i])); | 431 | pm2xxx_interrupt_registers[i], |
427 | } | 432 | &(interrupt->reg[i])); |
428 | 433 | ||
429 | pm2_int_reg0(pm2); | 434 | if (interrupt->reg[i] > 0) |
430 | pm2_int_reg1(pm2); | 435 | interrupt->handler[i](pm2, interrupt->reg[i]); |
431 | pm2_int_reg2(pm2); | 436 | } |
432 | pm2_int_reg3(pm2); | ||
433 | pm2_int_reg4(pm2); | ||
434 | pm2_int_reg5(pm2); | ||
435 | 437 | ||
436 | return IRQ_HANDLED; | 438 | return IRQ_HANDLED; |
437 | } | 439 | } |
@@ -538,7 +540,7 @@ static int pm2xxx_charger_update_charger_current(struct ux500_charger *charger, | |||
538 | curr_index = pm2xxx_current_to_regval(ich_out); | 540 | curr_index = pm2xxx_current_to_regval(ich_out); |
539 | if (curr_index < 0) { | 541 | if (curr_index < 0) { |
540 | dev_err(pm2->dev, | 542 | dev_err(pm2->dev, |
541 | "Charger current too high: charging not started\n"); | 543 | "Charger current too high, charging not started\n"); |
542 | return -ENXIO; | 544 | return -ENXIO; |
543 | } | 545 | } |
544 | 546 | ||
@@ -614,6 +616,59 @@ static int pm2xxx_charging_init(struct pm2xxx_charger *pm2) | |||
614 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG4, | 616 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG4, |
615 | PM2XXX_CH_WD_PRECH_PHASE_60MIN); | 617 | PM2XXX_CH_WD_PRECH_PHASE_60MIN); |
616 | 618 | ||
619 | /* Disable auto timeout */ | ||
620 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG5, | ||
621 | PM2XXX_CH_WD_AUTO_TIMEOUT_20MIN); | ||
622 | |||
623 | /* | ||
624 | * EOC current level = 100mA | ||
625 | * Precharge current level = 100mA | ||
626 | * CC current level = 1000mA | ||
627 | */ | ||
628 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG6, | ||
629 | (PM2XXX_DIR_CH_CC_CURRENT_1000MA | | ||
630 | PM2XXX_CH_PRECH_CURRENT_100MA | | ||
631 | PM2XXX_CH_EOC_CURRENT_100MA)); | ||
632 | |||
633 | /* | ||
634 | * recharge threshold = 3.8V | ||
635 | * Precharge to CC threshold = 2.9V | ||
636 | */ | ||
637 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG7, | ||
638 | (PM2XXX_CH_PRECH_VOL_2_9 | PM2XXX_CH_VRESUME_VOL_3_8)); | ||
639 | |||
640 | /* float voltage charger level = 4.2V */ | ||
641 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG8, | ||
642 | PM2XXX_CH_VOLT_4_2); | ||
643 | |||
644 | /* Voltage drop between VBAT and VSYS in HW charging = 300mV */ | ||
645 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_CTRL_REG9, | ||
646 | (PM2XXX_CH_150MV_DROP_300MV | PM2XXX_CHARCHING_INFO_DIS | | ||
647 | PM2XXX_CH_CC_REDUCED_CURRENT_IDENT | | ||
648 | PM2XXX_CH_CC_MODEDROP_DIS)); | ||
649 | |||
650 | /* Input charger level of over voltage = 10V */ | ||
651 | ret = pm2xxx_reg_write(pm2, PM2XXX_INP_VOLT_VPWR2, | ||
652 | PM2XXX_VPWR2_OVV_10); | ||
653 | ret = pm2xxx_reg_write(pm2, PM2XXX_INP_VOLT_VPWR1, | ||
654 | PM2XXX_VPWR1_OVV_10); | ||
655 | |||
656 | /* Input charger drop */ | ||
657 | ret = pm2xxx_reg_write(pm2, PM2XXX_INP_DROP_VPWR2, | ||
658 | (PM2XXX_VPWR2_HW_OPT_DIS | PM2XXX_VPWR2_VALID_DIS | | ||
659 | PM2XXX_VPWR2_DROP_DIS)); | ||
660 | ret = pm2xxx_reg_write(pm2, PM2XXX_INP_DROP_VPWR1, | ||
661 | (PM2XXX_VPWR1_HW_OPT_DIS | PM2XXX_VPWR1_VALID_DIS | | ||
662 | PM2XXX_VPWR1_DROP_DIS)); | ||
663 | |||
664 | /* Disable battery low monitoring */ | ||
665 | ret = pm2xxx_reg_write(pm2, PM2XXX_BATT_LOW_LEV_COMP_REG, | ||
666 | PM2XXX_VBAT_LOW_MONITORING_DIS); | ||
667 | |||
668 | /* Disable LED */ | ||
669 | ret = pm2xxx_reg_write(pm2, PM2XXX_LED_CTRL_REG, | ||
670 | PM2XXX_LED_SELECT_DIS); | ||
671 | |||
617 | return ret; | 672 | return ret; |
618 | } | 673 | } |
619 | 674 | ||
@@ -764,6 +819,15 @@ static void pm2xxx_charger_check_main_thermal_prot_work( | |||
764 | { | 819 | { |
765 | }; | 820 | }; |
766 | 821 | ||
822 | static struct pm2xxx_interrupts pm2xxx_int = { | ||
823 | .handler[0] = pm2_int_reg0, | ||
824 | .handler[1] = pm2_int_reg1, | ||
825 | .handler[2] = pm2_int_reg2, | ||
826 | .handler[3] = pm2_int_reg3, | ||
827 | .handler[4] = pm2_int_reg4, | ||
828 | .handler[5] = pm2_int_reg5, | ||
829 | }; | ||
830 | |||
767 | static struct pm2xxx_irq pm2xxx_charger_irq[] = { | 831 | static struct pm2xxx_irq pm2xxx_charger_irq[] = { |
768 | {"PM2XXX_IRQ_INT", pm2xxx_irq_int}, | 832 | {"PM2XXX_IRQ_INT", pm2xxx_irq_int}, |
769 | }; | 833 | }; |
@@ -797,6 +861,8 @@ static int __devinit pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, | |||
797 | pm2->dev = &i2c_client->dev; | 861 | pm2->dev = &i2c_client->dev; |
798 | pm2->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); | 862 | pm2->gpadc = ab8500_gpadc_get("ab8500-gpadc.0"); |
799 | 863 | ||
864 | pm2->pm2_int = &pm2xxx_int; | ||
865 | |||
800 | /* get charger spcific platform data */ | 866 | /* get charger spcific platform data */ |
801 | if (!pl_data->wall_charger) { | 867 | if (!pl_data->wall_charger) { |
802 | dev_err(pm2->dev, "no charger platform data supplied\n"); | 868 | dev_err(pm2->dev, "no charger platform data supplied\n"); |
@@ -844,6 +910,7 @@ static int __devinit pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, | |||
844 | ARRAY_SIZE(pm2xxx_charger_voltage_map) - 1]; | 910 | ARRAY_SIZE(pm2xxx_charger_voltage_map) - 1]; |
845 | pm2->ac_chg.max_out_curr = pm2xxx_charger_current_map[ | 911 | pm2->ac_chg.max_out_curr = pm2xxx_charger_current_map[ |
846 | ARRAY_SIZE(pm2xxx_charger_current_map) - 1]; | 912 | ARRAY_SIZE(pm2xxx_charger_current_map) - 1]; |
913 | pm2->ac_chg.enabled = true; | ||
847 | 914 | ||
848 | /* Create a work queue for the charger */ | 915 | /* Create a work queue for the charger */ |
849 | pm2->charger_wq = | 916 | pm2->charger_wq = |
diff --git a/drivers/power/pm2301_charger.h b/drivers/power/pm2301_charger.h index bef38a3552b5..419014714c2f 100644 --- a/drivers/power/pm2301_charger.h +++ b/drivers/power/pm2301_charger.h | |||
@@ -34,6 +34,8 @@ | |||
34 | #define WD_TIMER 0x30 /* 4min */ | 34 | #define WD_TIMER 0x30 /* 4min */ |
35 | #define WD_KICK_INTERVAL (60 * HZ) | 35 | #define WD_KICK_INTERVAL (60 * HZ) |
36 | 36 | ||
37 | #define PM2XXX_NUM_INT_REG 0x6 | ||
38 | |||
37 | /* Constant voltage/current */ | 39 | /* Constant voltage/current */ |
38 | #define PM2XXX_CONST_CURR 0x0 | 40 | #define PM2XXX_CONST_CURR 0x0 |
39 | #define PM2XXX_CONST_VOLT 0x1 | 41 | #define PM2XXX_CONST_VOLT 0x1 |
@@ -237,12 +239,32 @@ | |||
237 | #define PM2XXX_VPWR2_OVV_10 0x2 | 239 | #define PM2XXX_VPWR2_OVV_10 0x2 |
238 | #define PM2XXX_VPWR2_OVV_NONE 0x3 | 240 | #define PM2XXX_VPWR2_OVV_NONE 0x3 |
239 | 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 | |||
240 | /* Input charger voltage VPWR1 */ | 252 | /* Input charger voltage VPWR1 */ |
241 | #define PM2XXX_VPWR1_OVV_6_0 0x0 | 253 | #define PM2XXX_VPWR1_OVV_6_0 0x0 |
242 | #define PM2XXX_VPWR1_OVV_6_3 0x1 | 254 | #define PM2XXX_VPWR1_OVV_6_3 0x1 |
243 | #define PM2XXX_VPWR1_OVV_10 0x2 | 255 | #define PM2XXX_VPWR1_OVV_10 0x2 |
244 | #define PM2XXX_VPWR1_OVV_NONE 0x3 | 256 | #define PM2XXX_VPWR1_OVV_NONE 0x3 |
245 | 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 | |||
246 | /* Battery low level comparator control register */ | 268 | /* Battery low level comparator control register */ |
247 | #define PM2XXX_VBAT_LOW_MONITORING_DIS 0x0 | 269 | #define PM2XXX_VBAT_LOW_MONITORING_DIS 0x0 |
248 | #define PM2XXX_VBAT_LOW_MONITORING_ENA 0x1 | 270 | #define PM2XXX_VBAT_LOW_MONITORING_ENA 0x1 |
@@ -446,6 +468,11 @@ struct pm2xxx_charger_event_flags { | |||
446 | bool chgwdexp; | 468 | bool chgwdexp; |
447 | }; | 469 | }; |
448 | 470 | ||
471 | struct pm2xxx_interrupts { | ||
472 | u8 reg[PM2XXX_NUM_INT_REG]; | ||
473 | int (*handler[PM2XXX_NUM_INT_REG])(void *, int); | ||
474 | }; | ||
475 | |||
449 | struct pm2xxx_config { | 476 | struct pm2xxx_config { |
450 | struct i2c_client *pm2xxx_i2c; | 477 | struct i2c_client *pm2xxx_i2c; |
451 | struct i2c_device_id *pm2xxx_id; | 478 | struct i2c_device_id *pm2xxx_id; |
@@ -467,7 +494,7 @@ struct pm2xxx_charger { | |||
467 | int old_vbat; | 494 | int old_vbat; |
468 | int failure_case; | 495 | int failure_case; |
469 | int failure_input_ovv; | 496 | int failure_input_ovv; |
470 | u8 pm2_int[6]; | 497 | struct pm2xxx_interrupts *pm2_int; |
471 | struct ab8500_gpadc *gpadc; | 498 | struct ab8500_gpadc *gpadc; |
472 | struct regulator *regu; | 499 | struct regulator *regu; |
473 | struct pm2xxx_bm_data *bat; | 500 | struct pm2xxx_bm_data *bat; |