diff options
author | Rafaël Carré <rafael.carre@gmail.com> | 2010-05-17 20:53:25 +0000 |
---|---|---|
committer | Rafaël Carré <rafael.carre@gmail.com> | 2010-05-17 20:53:25 +0000 |
commit | 88c55d7290b7c360075557c40fdf65ceeeaf0c4b (patch) | |
tree | 29cf685626bf8c01bb64ed9456850f62e4a57d7d /firmware/target/arm | |
parent | 2ed7745ddefc084ca7030d48b251882e94fa2f9c (diff) | |
download | rockbox-88c55d7290b7c360075557c40fdf65ceeeaf0c4b.tar.gz rockbox-88c55d7290b7c360075557c40fdf65ceeeaf0c4b.zip |
as3514/as3543 fixes
- Enable end of charge monitoring once, it doesn't need to be disabled
- Acknowledge the first (wrong) end of charge interrupt on charger enable
(this had been broken in r25299)
- Centralize reads to ENRD* registers and cache the results when needed
- on PP it is not needed because reads are atomic, we only check for
end of charge when the charging, and for charger presence when
discharging
as3525v2 (using as3543) specifics
- I got the datasheet today from AMS, thanks to them for being so fast
and not require me to sign tons of papers!
- USB detection now works on as3525v2 using the as3543. Clip+ won't
reboot to OF yet, it needs mkamsboot support first (usbstack disabled)
- Charging should work, the CHARGER register is at a different place, it
is an extended PMU register -> use ascodec_read/write_charger() to
access it
- real interrupts are not used yet for ENRD, we get thousands of
interrupts per second, apparently only limited by the i2c clock.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26116 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/as3525/ascodec-as3525.c | 98 | ||||
-rw-r--r-- | firmware/target/arm/as3525/ascodec-target.h | 66 | ||||
-rw-r--r-- | firmware/target/arm/as3525/power-as3525.c | 2 | ||||
-rw-r--r-- | firmware/target/arm/as3525/usb-as3525.c | 21 | ||||
-rw-r--r-- | firmware/target/arm/as3525/usb-target.h | 2 | ||||
-rw-r--r-- | firmware/target/arm/ascodec-target.h | 23 | ||||
-rw-r--r-- | firmware/target/arm/powermgmt-ascodec.c | 22 |
7 files changed, 142 insertions, 92 deletions
diff --git a/firmware/target/arm/as3525/ascodec-as3525.c b/firmware/target/arm/as3525/ascodec-as3525.c index 87a1447c63..52d50ef077 100644 --- a/firmware/target/arm/as3525/ascodec-as3525.c +++ b/firmware/target/arm/as3525/ascodec-as3525.c | |||
@@ -185,10 +185,18 @@ void ascodec_init(void) | |||
185 | 185 | ||
186 | I2C2_IMR = 0x00; /* disable interrupts */ | 186 | I2C2_IMR = 0x00; /* disable interrupts */ |
187 | I2C2_INT_CLR |= I2C2_RIS; /* clear interrupt status */ | 187 | I2C2_INT_CLR |= I2C2_RIS; /* clear interrupt status */ |
188 | VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO | INTERRUPT_AUDIO; | 188 | VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO; |
189 | #if CONFIG_CPU == AS3525 /* interrupts do not work correctly on as3525v2 */ | ||
190 | VIC_INT_ENABLE = INTERRUPT_AUDIO; | ||
191 | #endif | ||
189 | 192 | ||
190 | /* Generate irq for usb+charge status change */ | 193 | /* Generate irq for usb+charge status change */ |
191 | ascodec_write(AS3514_IRQ_ENRD0, /*IRQ_CHGSTAT |*/ IRQ_USBSTAT); | 194 | ascodec_write(AS3514_IRQ_ENRD0, |
195 | #ifdef CONFIG_CHARGING /* m200v4 can't charge */ | ||
196 | IRQ_CHGSTAT | IRQ_ENDOFCH | | ||
197 | #endif | ||
198 | IRQ_USBSTAT); | ||
199 | |||
192 | /* Generate irq for push-pull, active high, irq on rtc+adc change */ | 200 | /* Generate irq for push-pull, active high, irq on rtc+adc change */ |
193 | ascodec_write(AS3514_IRQ_ENRD2, IRQ_PUSHPULL | IRQ_HIGHACTIVE | | 201 | ascodec_write(AS3514_IRQ_ENRD2, IRQ_PUSHPULL | IRQ_HIGHACTIVE | |
194 | /*IRQ_RTC |*/ IRQ_ADC); | 202 | /*IRQ_RTC |*/ IRQ_ADC); |
@@ -342,19 +350,8 @@ static void ascodec_wait(struct ascodec_request *req) | |||
342 | void ascodec_async_write(unsigned int index, unsigned int value, | 350 | void ascodec_async_write(unsigned int index, unsigned int value, |
343 | struct ascodec_request *req) | 351 | struct ascodec_request *req) |
344 | { | 352 | { |
345 | switch(index) { | 353 | if (index == AS3514_CVDD_DCDC3) /* prevent setting of the LREG_CP_not bit */ |
346 | case AS3514_CVDD_DCDC3: | ||
347 | /* prevent setting of the LREG_CP_not bit */ | ||
348 | value &= ~(1 << 5); | 354 | value &= ~(1 << 5); |
349 | break; | ||
350 | case AS3514_IRQ_ENRD0: | ||
351 | /* save value in register shadow | ||
352 | * for ascodec_(en|dis)able_endofch_irq() */ | ||
353 | ascodec_enrd0_shadow = value; | ||
354 | break; | ||
355 | default: | ||
356 | break; | ||
357 | } | ||
358 | 355 | ||
359 | ascodec_req_init(req, ASCODEC_REQ_WRITE, index, 1); | 356 | ascodec_req_init(req, ASCODEC_REQ_WRITE, index, 1); |
360 | req->data[0] = value; | 357 | req->data[0] = value; |
@@ -429,24 +426,37 @@ int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data) | |||
429 | return i; | 426 | return i; |
430 | } | 427 | } |
431 | 428 | ||
432 | #if CONFIG_CPU == AS3525 | 429 | /* |
433 | static void ascodec_read_cb(unsigned const char *data, unsigned int len) | 430 | * Reading AS3514_IRQ_ENRD0 clears all interrupt bits, so we cache the results |
431 | * and clear individual bits when a specific interrupt is checked: | ||
432 | * - we clear the ENDOFCH (end of charge) interrupt when it's read | ||
433 | * - we set the usb and charger presence when the status change is detected | ||
434 | * | ||
435 | * on AS3525(v1) ENRD0 is only read in an interrupt handler | ||
436 | * on AS3525v2 the interrupt handler doesn't work (yet), so we read the register | ||
437 | * synchronously. | ||
438 | * - To avoid race conditions all the reads to this register must be atomic. | ||
439 | * We don't need to disable interrupts when reading it because all the reads | ||
440 | * (in powermgmt-ascodec.c and power-as3525.c) are performed by the same | ||
441 | * thread (the power thread). | ||
442 | */ | ||
443 | static void cache_enrd0(int enrd0) | ||
434 | { | 444 | { |
435 | if (len != 3) /* some error happened? */ | 445 | if (enrd0 & CHG_ENDOFCH) { /* chg finished */ |
436 | return; | 446 | ascodec_enrd0_shadow |= CHG_ENDOFCH; |
437 | |||
438 | if (data[0] & CHG_ENDOFCH) { /* chg finished */ | ||
439 | IFDEBUG(int_chg_finished++); | 447 | IFDEBUG(int_chg_finished++); |
440 | } | 448 | } |
441 | if (data[0] & CHG_CHANGED) { /* chg status changed */ | 449 | if (enrd0 & CHG_CHANGED) { /* chg status changed */ |
442 | if (data[0] & CHG_STATUS) { | 450 | if (enrd0 & CHG_STATUS) { |
451 | ascodec_enrd0_shadow |= CHG_STATUS; | ||
443 | IFDEBUG(int_chg_insert++); | 452 | IFDEBUG(int_chg_insert++); |
444 | } else { | 453 | } else { |
454 | ascodec_enrd0_shadow &= ~CHG_STATUS; | ||
445 | IFDEBUG(int_chg_remove++); | 455 | IFDEBUG(int_chg_remove++); |
446 | } | 456 | } |
447 | } | 457 | } |
448 | if (data[0] & USB_CHANGED) { /* usb status changed */ | 458 | if (enrd0 & USB_CHANGED) { /* usb status changed */ |
449 | if (data[0] & USB_STATUS) { | 459 | if (enrd0 & USB_STATUS) { |
450 | IFDEBUG(int_usb_insert++); | 460 | IFDEBUG(int_usb_insert++); |
451 | usb_insert_int(); | 461 | usb_insert_int(); |
452 | } else { | 462 | } else { |
@@ -454,6 +464,16 @@ static void ascodec_read_cb(unsigned const char *data, unsigned int len) | |||
454 | usb_remove_int(); | 464 | usb_remove_int(); |
455 | } | 465 | } |
456 | } | 466 | } |
467 | } | ||
468 | |||
469 | #if CONFIG_CPU == AS3525 | ||
470 | static void ascodec_read_cb(unsigned const char *data, unsigned int len) | ||
471 | { | ||
472 | if (len != 3) /* some error happened? */ | ||
473 | return; | ||
474 | |||
475 | cache_enrd0(data[0]); | ||
476 | |||
457 | if (data[2] & IRQ_RTC) { /* rtc irq */ | 477 | if (data[2] & IRQ_RTC) { /* rtc irq */ |
458 | /* | 478 | /* |
459 | * Can be configured for once per second or once per minute, | 479 | * Can be configured for once per second or once per minute, |
@@ -468,22 +488,40 @@ static void ascodec_read_cb(unsigned const char *data, unsigned int len) | |||
468 | VIC_INT_ENABLE = INTERRUPT_AUDIO; | 488 | VIC_INT_ENABLE = INTERRUPT_AUDIO; |
469 | } | 489 | } |
470 | 490 | ||
491 | #endif /* CONFIG_CPU == AS3525 */ | ||
492 | |||
471 | void ascodec_wait_adc_finished(void) | 493 | void ascodec_wait_adc_finished(void) |
472 | { | 494 | { |
495 | #if CONFIG_CPU == AS3525 | ||
473 | wakeup_wait(&adc_wkup, TIMEOUT_BLOCK); | 496 | wakeup_wait(&adc_wkup, TIMEOUT_BLOCK); |
497 | #else | ||
498 | /* no interrupts, busy wait | ||
499 | * XXX: make sure this is the only reader of IRQ_ENRD2 | ||
500 | */ | ||
501 | while(!(ascodec_read(AS3514_IRQ_ENRD2) & IRQ_ADC)) | ||
502 | yield(); | ||
503 | #endif | ||
474 | } | 504 | } |
475 | #endif /* CONFIG_CPU == AS3525 */ | ||
476 | |||
477 | 505 | ||
478 | void ascodec_enable_endofch_irq(void) | 506 | #ifdef CONFIG_CHARGING |
507 | bool ascodec_endofch(void) | ||
479 | { | 508 | { |
480 | ascodec_write(AS3514_IRQ_ENRD0, ascodec_enrd0_shadow | CHG_ENDOFCH); | 509 | #if CONFIG_CPU != AS3525 |
510 | cache_enrd0(ascodec_read(AS3514_IRQ_ENRD0)); | ||
511 | #endif | ||
512 | bool ret = ascodec_enrd0_shadow & CHG_ENDOFCH; | ||
513 | ascodec_enrd0_shadow &= ~CHG_ENDOFCH; // clear interrupt | ||
514 | return ret; | ||
481 | } | 515 | } |
482 | 516 | ||
483 | void ascodec_disable_endofch_irq(void) | 517 | bool ascodec_chg_status(void) |
484 | { | 518 | { |
485 | ascodec_write(AS3514_IRQ_ENRD0, ascodec_enrd0_shadow & ~CHG_ENDOFCH); | 519 | #if CONFIG_CPU != AS3525 |
520 | cache_enrd0(ascodec_read(AS3514_IRQ_ENRD0)); | ||
521 | #endif | ||
522 | return ascodec_enrd0_shadow & CHG_STATUS; | ||
486 | } | 523 | } |
524 | #endif /* CONFIG_CHARGING */ | ||
487 | 525 | ||
488 | /* | 526 | /* |
489 | * NOTE: | 527 | * NOTE: |
diff --git a/firmware/target/arm/as3525/ascodec-target.h b/firmware/target/arm/as3525/ascodec-target.h index 37947541c2..8ce9a428d3 100644 --- a/firmware/target/arm/as3525/ascodec-target.h +++ b/firmware/target/arm/as3525/ascodec-target.h | |||
@@ -52,7 +52,7 @@ | |||
52 | /* | 52 | /* |
53 | * How many bytes we using in struct ascodec_request for the data buffer. | 53 | * How many bytes we using in struct ascodec_request for the data buffer. |
54 | * 4 fits the alignment best right now. | 54 | * 4 fits the alignment best right now. |
55 | * We don't actually use more than 2 at the moment (in adc_read). | 55 | * We don't actually use more than 3 at the moment (when reading interrupts) |
56 | * Upper limit would be 255 since DACNT is 8 bits! | 56 | * Upper limit would be 255 since DACNT is 8 bits! |
57 | */ | 57 | */ |
58 | #define ASCODEC_REQ_MAXLEN 4 | 58 | #define ASCODEC_REQ_MAXLEN 4 |
@@ -74,19 +74,6 @@ void ascodec_init(void); | |||
74 | 74 | ||
75 | int ascodec_write(unsigned int index, unsigned int value); | 75 | int ascodec_write(unsigned int index, unsigned int value); |
76 | 76 | ||
77 | #if CONFIG_CPU == AS3525v2 | ||
78 | static inline void ascodec_write_pmu(unsigned int index, unsigned int subreg, | ||
79 | unsigned int value) | ||
80 | { | ||
81 | /* we disable interrupts to make sure no operation happen on the i2c bus | ||
82 | * between selecting the sub register and writing to it */ | ||
83 | int oldstatus = disable_irq_save(); | ||
84 | ascodec_write(AS3543_PMU_ENABLE, 8|subreg); | ||
85 | ascodec_write(index, value); | ||
86 | restore_irq(oldstatus); | ||
87 | } | ||
88 | #endif | ||
89 | |||
90 | int ascodec_read(unsigned int index); | 77 | int ascodec_read(unsigned int index); |
91 | 78 | ||
92 | int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data); | 79 | int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data); |
@@ -119,18 +106,55 @@ void ascodec_lock(void); | |||
119 | 106 | ||
120 | void ascodec_unlock(void); | 107 | void ascodec_unlock(void); |
121 | 108 | ||
122 | #if CONFIG_CPU == AS3525 | ||
123 | void ascodec_wait_adc_finished(void); | 109 | void ascodec_wait_adc_finished(void); |
124 | #else | 110 | |
125 | static inline void ascodec_wait_adc_finished(void) | 111 | static inline void ascodec_monitor_endofch(void) {} /* already enabled */ |
112 | |||
113 | bool ascodec_endofch(void); | ||
114 | |||
115 | bool ascodec_chg_status(void); | ||
116 | |||
117 | #if CONFIG_CPU == AS3525v2 | ||
118 | static inline void ascodec_write_pmu(unsigned int index, unsigned int subreg, | ||
119 | unsigned int value) | ||
120 | { | ||
121 | /* we disable interrupts to make sure no operation happen on the i2c bus | ||
122 | * between selecting the sub register and writing to it */ | ||
123 | int oldstatus = disable_irq_save(); | ||
124 | ascodec_write(AS3543_PMU_ENABLE, 8|subreg); | ||
125 | ascodec_write(index, value); | ||
126 | restore_irq(oldstatus); | ||
127 | } | ||
128 | |||
129 | static inline int ascodec_read_pmu(unsigned int index, unsigned int subreg) | ||
126 | { | 130 | { |
127 | /* FIXME: Doesn't work yet on AS3525v2 */ | 131 | /* we disable interrupts to make sure no operation happen on the i2c bus |
132 | * between selecting the sub register and reading it */ | ||
133 | int oldstatus = disable_irq_save(); | ||
134 | ascodec_write(AS3543_PMU_ENABLE, 8|subreg); | ||
135 | int ret = ascodec_read(index); | ||
136 | restore_irq(oldstatus); | ||
137 | return ret; | ||
128 | } | 138 | } |
129 | #endif | 139 | #endif /* CONFIG_CPU == AS3525v2 */ |
130 | 140 | ||
131 | void ascodec_enable_endofch_irq(void); | 141 | static inline void ascodec_write_charger(int value) |
142 | { | ||
143 | #if CONFIG_CPU == AS3525 | ||
144 | ascodec_write(AS3514_CHARGER, value); | ||
145 | #else | ||
146 | ascodec_write_pmu(AS3543_CHARGER, 1, value); | ||
147 | #endif | ||
148 | } | ||
132 | 149 | ||
133 | void ascodec_disable_endofch_irq(void); | 150 | static inline int ascodec_read_charger(void) |
151 | { | ||
152 | #if CONFIG_CPU == AS3525 | ||
153 | return ascodec_read(AS3514_CHARGER); | ||
154 | #else | ||
155 | return ascodec_read_pmu(AS3543_CHARGER, 1); | ||
156 | #endif | ||
157 | } | ||
134 | 158 | ||
135 | #endif /* !SIMULATOR */ | 159 | #endif /* !SIMULATOR */ |
136 | 160 | ||
diff --git a/firmware/target/arm/as3525/power-as3525.c b/firmware/target/arm/as3525/power-as3525.c index 3570d7c75a..7b93dd1cd1 100644 --- a/firmware/target/arm/as3525/power-as3525.c +++ b/firmware/target/arm/as3525/power-as3525.c | |||
@@ -41,7 +41,7 @@ void power_init(void) | |||
41 | #if CONFIG_CHARGING | 41 | #if CONFIG_CHARGING |
42 | unsigned int power_input_status(void) | 42 | unsigned int power_input_status(void) |
43 | { | 43 | { |
44 | return (ascodec_read(AS3514_IRQ_ENRD0) & (1<<5)) ? | 44 | return ascodec_chg_status() ? |
45 | POWER_INPUT_MAIN_CHARGER : POWER_INPUT_NONE; | 45 | POWER_INPUT_MAIN_CHARGER : POWER_INPUT_NONE; |
46 | 46 | ||
47 | /* TODO: Handle USB and other sources properly */ | 47 | /* TODO: Handle USB and other sources properly */ |
diff --git a/firmware/target/arm/as3525/usb-as3525.c b/firmware/target/arm/as3525/usb-as3525.c index 74bfc17364..be62752033 100644 --- a/firmware/target/arm/as3525/usb-as3525.c +++ b/firmware/target/arm/as3525/usb-as3525.c | |||
@@ -29,13 +29,7 @@ | |||
29 | #include "power.h" | 29 | #include "power.h" |
30 | #include "as3525.h" | 30 | #include "as3525.h" |
31 | 31 | ||
32 | #if CONFIG_CPU == AS3525 | ||
33 | static int usb_status = USB_EXTRACTED; | 32 | static int usb_status = USB_EXTRACTED; |
34 | #else | ||
35 | #if defined(SANSA_CLIPV2) | ||
36 | #define USB_DETECT_PIN 6 | ||
37 | #endif | ||
38 | #endif | ||
39 | 33 | ||
40 | void usb_enable(bool on) | 34 | void usb_enable(bool on) |
41 | { | 35 | { |
@@ -51,12 +45,8 @@ void usb_enable(bool on) | |||
51 | 45 | ||
52 | void usb_init_device(void) | 46 | void usb_init_device(void) |
53 | { | 47 | { |
54 | #ifdef USB_DETECT_PIN | ||
55 | GPIOA_DIR &= ~(1 << USB_DETECT_PIN); /* set as input */ | ||
56 | #endif | ||
57 | } | 48 | } |
58 | 49 | ||
59 | #if CONFIG_CPU == AS3525 | ||
60 | void usb_insert_int(void) | 50 | void usb_insert_int(void) |
61 | { | 51 | { |
62 | usb_status = USB_INSERTED; | 52 | usb_status = USB_INSERTED; |
@@ -71,14 +61,3 @@ int usb_detect(void) | |||
71 | { | 61 | { |
72 | return usb_status; | 62 | return usb_status; |
73 | } | 63 | } |
74 | #else | ||
75 | int usb_detect(void) | ||
76 | { | ||
77 | #ifdef USB_DETECT_PIN | ||
78 | if (GPIOA_PIN( USB_DETECT_PIN )) | ||
79 | return USB_INSERTED; | ||
80 | else | ||
81 | #endif | ||
82 | return USB_EXTRACTED; | ||
83 | } | ||
84 | #endif | ||
diff --git a/firmware/target/arm/as3525/usb-target.h b/firmware/target/arm/as3525/usb-target.h index 4c54dc182d..6df6d7c1d5 100644 --- a/firmware/target/arm/as3525/usb-target.h +++ b/firmware/target/arm/as3525/usb-target.h | |||
@@ -23,9 +23,7 @@ | |||
23 | 23 | ||
24 | void usb_init_device(void); | 24 | void usb_init_device(void); |
25 | int usb_detect(void); | 25 | int usb_detect(void); |
26 | #if CONFIG_CPU == AS3525 | ||
27 | void usb_insert_int(void); | 26 | void usb_insert_int(void); |
28 | void usb_remove_int(void); | 27 | void usb_remove_int(void); |
29 | #endif /* CONFIG_CPU == AS3525 */ | ||
30 | 28 | ||
31 | #endif /* USB_TARGET_H */ | 29 | #endif /* USB_TARGET_H */ |
diff --git a/firmware/target/arm/ascodec-target.h b/firmware/target/arm/ascodec-target.h index c87d869ebb..68d9905a6b 100644 --- a/firmware/target/arm/ascodec-target.h +++ b/firmware/target/arm/ascodec-target.h | |||
@@ -59,14 +59,19 @@ static inline void ascodec_unlock(void) | |||
59 | i2c_unlock(); | 59 | i2c_unlock(); |
60 | } | 60 | } |
61 | 61 | ||
62 | static inline void ascodec_enable_endofch_irq(void) | 62 | static inline bool ascodec_chg_status(void) |
63 | { | 63 | { |
64 | ascodec_write(AS3514_IRQ_ENRD0, IRQ_ENDOFCH); | 64 | return ascodec_read(AS3514_IRQ_ENRD0) & CHG_STATUS; |
65 | } | ||
66 | |||
67 | static inline bool ascodec_endofch(void) | ||
68 | { | ||
69 | return ascodec_read(AS3514_IRQ_ENRD0) & CHG_ENDOFCH; | ||
65 | } | 70 | } |
66 | 71 | ||
67 | static inline void ascodec_disable_endofch_irq(void) | 72 | static inline void ascodec_monitor_endofch(void) |
68 | { | 73 | { |
69 | ascodec_write(AS3514_IRQ_ENRD0, 0); | 74 | ascodec_write(AS3514_IRQ_ENRD0, IRQ_ENDOFCH); |
70 | } | 75 | } |
71 | 76 | ||
72 | static inline void ascodec_wait_adc_finished(void) | 77 | static inline void ascodec_wait_adc_finished(void) |
@@ -81,6 +86,16 @@ static inline void ascodec_wait_adc_finished(void) | |||
81 | */ | 86 | */ |
82 | } | 87 | } |
83 | 88 | ||
89 | static inline void ascodec_write_charger(int value) | ||
90 | { | ||
91 | ascodec_write(AS3514_CHARGER, value); | ||
92 | } | ||
93 | |||
94 | static inline int ascodec_read_charger(void) | ||
95 | { | ||
96 | return ascodec_read(AS3514_CHARGER); | ||
97 | } | ||
98 | |||
84 | extern void ascodec_suppressor_on(bool on); | 99 | extern void ascodec_suppressor_on(bool on); |
85 | 100 | ||
86 | #endif /* CPU_PP */ | 101 | #endif /* CPU_PP */ |
diff --git a/firmware/target/arm/powermgmt-ascodec.c b/firmware/target/arm/powermgmt-ascodec.c index b463486346..e50367fe93 100644 --- a/firmware/target/arm/powermgmt-ascodec.c +++ b/firmware/target/arm/powermgmt-ascodec.c | |||
@@ -94,9 +94,7 @@ static void battery_voltage_sync(void) | |||
94 | /* Disable charger and minimize all settings. Reset timers, etc. */ | 94 | /* Disable charger and minimize all settings. Reset timers, etc. */ |
95 | static void disable_charger(void) | 95 | static void disable_charger(void) |
96 | { | 96 | { |
97 | ascodec_disable_endofch_irq(); | 97 | ascodec_write_charger(TMPSUP_OFF | CHG_I_50MA | CHG_V_3_90V | CHG_OFF); |
98 | ascodec_write(AS3514_CHARGER, | ||
99 | TMPSUP_OFF | CHG_I_50MA | CHG_V_3_90V | CHG_OFF); | ||
100 | 98 | ||
101 | if (charge_state > DISCHARGING) | 99 | if (charge_state > DISCHARGING) |
102 | charge_state = DISCHARGING; /* Not an error state already */ | 100 | charge_state = DISCHARGING; /* Not an error state already */ |
@@ -108,14 +106,13 @@ static void disable_charger(void) | |||
108 | /* Enable charger with specified settings. Start timers, etc. */ | 106 | /* Enable charger with specified settings. Start timers, etc. */ |
109 | static void enable_charger(void) | 107 | static void enable_charger(void) |
110 | { | 108 | { |
111 | ascodec_write(AS3514_CHARGER, BATT_CHG_I | BATT_CHG_V); | 109 | ascodec_write_charger(BATT_CHG_I | BATT_CHG_V); |
112 | /* Watch for end of charge. Temperature supervision is handled in | ||
113 | * hardware. Charger status can be read and has no interrupt enable. */ | ||
114 | ascodec_enable_endofch_irq(); | ||
115 | 110 | ||
116 | sleep(HZ/10); /* Allow charger turn-on time (it could be gradual). */ | 111 | sleep(HZ/10); /* Allow charger turn-on time (it could be gradual). */ |
117 | 112 | ||
118 | ascodec_disable_endofch_irq(); | 113 | /* acknowledge first end of charging interrupt, it seems to happen both |
114 | * at charger plug and charger unplug */ | ||
115 | ascodec_endofch(); | ||
119 | 116 | ||
120 | charge_state = CHARGING; | 117 | charge_state = CHARGING; |
121 | charger_total_timer = CHARGER_TOTAL_TIMER; | 118 | charger_total_timer = CHARGER_TOTAL_TIMER; |
@@ -125,9 +122,8 @@ static void enable_charger(void) | |||
125 | void powermgmt_init_target(void) | 122 | void powermgmt_init_target(void) |
126 | { | 123 | { |
127 | /* Everything CHARGER, OFF! */ | 124 | /* Everything CHARGER, OFF! */ |
128 | ascodec_disable_endofch_irq(); | 125 | ascodec_monitor_endofch(); |
129 | ascodec_write(AS3514_CHARGER, | 126 | ascodec_write_charger(TMPSUP_OFF | CHG_I_50MA | CHG_V_3_90V | CHG_OFF); |
130 | TMPSUP_OFF | CHG_I_50MA | CHG_V_3_90V | CHG_OFF); | ||
131 | } | 127 | } |
132 | 128 | ||
133 | static inline void charger_plugged(void) | 129 | static inline void charger_plugged(void) |
@@ -148,7 +144,7 @@ static inline void charger_control(void) | |||
148 | if (BATT_FULL_VOLTAGE == thresh) | 144 | if (BATT_FULL_VOLTAGE == thresh) |
149 | { | 145 | { |
150 | /* Wait for CHG_status to be indicated. */ | 146 | /* Wait for CHG_status to be indicated. */ |
151 | if ((ascodec_read(AS3514_IRQ_ENRD0) & CHG_STATUS) == 0) | 147 | if (!ascodec_chg_status()) |
152 | break; | 148 | break; |
153 | 149 | ||
154 | batt_threshold = BATT_VAUTO_RECHARGE; | 150 | batt_threshold = BATT_VAUTO_RECHARGE; |
@@ -163,7 +159,7 @@ static inline void charger_control(void) | |||
163 | 159 | ||
164 | case CHARGING: | 160 | case CHARGING: |
165 | { | 161 | { |
166 | if ((ascodec_read(AS3514_IRQ_ENRD0) & CHG_ENDOFCH) == 0) | 162 | if (!ascodec_endofch()) |
167 | { | 163 | { |
168 | if (--charger_total_timer > 0) | 164 | if (--charger_total_timer > 0) |
169 | break; | 165 | break; |