forked from len0rd/rockbox
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
This commit is contained in:
parent
2ed7745dde
commit
88c55d7290
10 changed files with 156 additions and 106 deletions
|
|
@ -108,7 +108,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \
|
#if defined(SANSA_E200) || defined(SANSA_C200) || defined(PHILIPS_SA9200) \
|
||||||
|| defined(SANSA_CLIP) || defined(SANSA_FUZE) || defined(SANSA_C200V2)
|
|| (CONFIG_CPU == AS3525 && defined(CONFIG_CHARGING)) \
|
||||||
|
|| CONFIG_CPU == AS3525v2
|
||||||
#include "ascodec.h"
|
#include "ascodec.h"
|
||||||
#include "as3514.h"
|
#include "as3514.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1656,8 +1657,8 @@ static bool view_battery(void)
|
||||||
lcd_puts(0, line++, "T Battery: ?");
|
lcd_puts(0, line++, "T Battery: ?");
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(SANSA_E200) || defined(SANSA_C200) || defined(SANSA_CLIP) || \
|
#elif defined(SANSA_E200) || defined(SANSA_C200) || CONFIG_CPU == AS3525 || \
|
||||||
defined(SANSA_FUZE) || defined (SANSA_C200V2)
|
CONFIG_CPU == AS3525v2
|
||||||
const int first = CHARGE_STATE_DISABLED;
|
const int first = CHARGE_STATE_DISABLED;
|
||||||
static const char * const chrgstate_strings[] =
|
static const char * const chrgstate_strings[] =
|
||||||
{
|
{
|
||||||
|
|
@ -1678,8 +1679,7 @@ static bool view_battery(void)
|
||||||
lcd_putsf(0, 4, "State: %s",
|
lcd_putsf(0, 4, "State: %s",
|
||||||
str ? str : "<unknown>");
|
str ? str : "<unknown>");
|
||||||
|
|
||||||
lcd_putsf(0, 5, "CHARGER: %02X",
|
lcd_putsf(0, 5, "CHARGER: %02X", ascodec_read_charger());
|
||||||
ascodec_read(AS3514_CHARGER));
|
|
||||||
#elif defined(IPOD_NANO2G)
|
#elif defined(IPOD_NANO2G)
|
||||||
y = pmu_read_battery_voltage();
|
y = pmu_read_battery_voltage();
|
||||||
lcd_putsf(17, 1, "RAW: %d.%03d V", y / 1000, y % 1000);
|
lcd_putsf(17, 1, "RAW: %d.%03d V", y / 1000, y % 1000);
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,10 @@ extern void audiohw_set_lineout_vol(int vol_l, int vol_r);
|
||||||
|
|
||||||
#define AS3514_PLLMODE 0x1d
|
#define AS3514_PLLMODE 0x1d
|
||||||
|
|
||||||
|
#ifdef HAVE_AS3543
|
||||||
|
#define AS3543_CHARGER 0x19 /* PMU: sub register 1 (CHGVBUS1) */
|
||||||
|
#endif
|
||||||
|
|
||||||
#define AS3514_SYSTEM 0x20
|
#define AS3514_SYSTEM 0x20
|
||||||
#define AS3514_CVDD_DCDC3 0x21
|
#define AS3514_CVDD_DCDC3 0x21
|
||||||
#define AS3514_CHARGER 0x22
|
#define AS3514_CHARGER 0x22
|
||||||
|
|
|
||||||
|
|
@ -173,19 +173,15 @@
|
||||||
|
|
||||||
#define USB_HANDLED_BY_OF
|
#define USB_HANDLED_BY_OF
|
||||||
|
|
||||||
#if 0 /* disabled since there is no USB driver */
|
|
||||||
|
|
||||||
/* USB On-the-go */
|
/* USB On-the-go */
|
||||||
#define CONFIG_USBOTG USBOTG_ARC
|
#define CONFIG_USBOTG USBOTG_AS3525
|
||||||
|
|
||||||
/* enable these for the experimental usb stack */
|
/* enable these for the experimental usb stack */
|
||||||
#define HAVE_USBSTACK
|
//#define HAVE_USBSTACK
|
||||||
#define USB_VENDOR_ID 0x0781
|
#define USB_VENDOR_ID 0x0781
|
||||||
#define USB_PRODUCT_ID 0x74d1
|
#define USB_PRODUCT_ID 0x74d1
|
||||||
#endif /* BOOTLOADER */
|
#endif /* BOOTLOADER */
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Virtual LED (icon) */
|
/* Virtual LED (icon) */
|
||||||
#define CONFIG_LED LED_VIRTUAL
|
#define CONFIG_LED LED_VIRTUAL
|
||||||
|
|
|
||||||
|
|
@ -185,10 +185,18 @@ void ascodec_init(void)
|
||||||
|
|
||||||
I2C2_IMR = 0x00; /* disable interrupts */
|
I2C2_IMR = 0x00; /* disable interrupts */
|
||||||
I2C2_INT_CLR |= I2C2_RIS; /* clear interrupt status */
|
I2C2_INT_CLR |= I2C2_RIS; /* clear interrupt status */
|
||||||
VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO | INTERRUPT_AUDIO;
|
VIC_INT_ENABLE = INTERRUPT_I2C_AUDIO;
|
||||||
|
#if CONFIG_CPU == AS3525 /* interrupts do not work correctly on as3525v2 */
|
||||||
|
VIC_INT_ENABLE = INTERRUPT_AUDIO;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Generate irq for usb+charge status change */
|
/* Generate irq for usb+charge status change */
|
||||||
ascodec_write(AS3514_IRQ_ENRD0, /*IRQ_CHGSTAT |*/ IRQ_USBSTAT);
|
ascodec_write(AS3514_IRQ_ENRD0,
|
||||||
|
#ifdef CONFIG_CHARGING /* m200v4 can't charge */
|
||||||
|
IRQ_CHGSTAT | IRQ_ENDOFCH |
|
||||||
|
#endif
|
||||||
|
IRQ_USBSTAT);
|
||||||
|
|
||||||
/* Generate irq for push-pull, active high, irq on rtc+adc change */
|
/* Generate irq for push-pull, active high, irq on rtc+adc change */
|
||||||
ascodec_write(AS3514_IRQ_ENRD2, IRQ_PUSHPULL | IRQ_HIGHACTIVE |
|
ascodec_write(AS3514_IRQ_ENRD2, IRQ_PUSHPULL | IRQ_HIGHACTIVE |
|
||||||
/*IRQ_RTC |*/ IRQ_ADC);
|
/*IRQ_RTC |*/ IRQ_ADC);
|
||||||
|
|
@ -342,19 +350,8 @@ static void ascodec_wait(struct ascodec_request *req)
|
||||||
void ascodec_async_write(unsigned int index, unsigned int value,
|
void ascodec_async_write(unsigned int index, unsigned int value,
|
||||||
struct ascodec_request *req)
|
struct ascodec_request *req)
|
||||||
{
|
{
|
||||||
switch(index) {
|
if (index == AS3514_CVDD_DCDC3) /* prevent setting of the LREG_CP_not bit */
|
||||||
case AS3514_CVDD_DCDC3:
|
|
||||||
/* prevent setting of the LREG_CP_not bit */
|
|
||||||
value &= ~(1 << 5);
|
value &= ~(1 << 5);
|
||||||
break;
|
|
||||||
case AS3514_IRQ_ENRD0:
|
|
||||||
/* save value in register shadow
|
|
||||||
* for ascodec_(en|dis)able_endofch_irq() */
|
|
||||||
ascodec_enrd0_shadow = value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ascodec_req_init(req, ASCODEC_REQ_WRITE, index, 1);
|
ascodec_req_init(req, ASCODEC_REQ_WRITE, index, 1);
|
||||||
req->data[0] = value;
|
req->data[0] = value;
|
||||||
|
|
@ -429,24 +426,37 @@ int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_CPU == AS3525
|
/*
|
||||||
static void ascodec_read_cb(unsigned const char *data, unsigned int len)
|
* Reading AS3514_IRQ_ENRD0 clears all interrupt bits, so we cache the results
|
||||||
|
* and clear individual bits when a specific interrupt is checked:
|
||||||
|
* - we clear the ENDOFCH (end of charge) interrupt when it's read
|
||||||
|
* - we set the usb and charger presence when the status change is detected
|
||||||
|
*
|
||||||
|
* on AS3525(v1) ENRD0 is only read in an interrupt handler
|
||||||
|
* on AS3525v2 the interrupt handler doesn't work (yet), so we read the register
|
||||||
|
* synchronously.
|
||||||
|
* - To avoid race conditions all the reads to this register must be atomic.
|
||||||
|
* We don't need to disable interrupts when reading it because all the reads
|
||||||
|
* (in powermgmt-ascodec.c and power-as3525.c) are performed by the same
|
||||||
|
* thread (the power thread).
|
||||||
|
*/
|
||||||
|
static void cache_enrd0(int enrd0)
|
||||||
{
|
{
|
||||||
if (len != 3) /* some error happened? */
|
if (enrd0 & CHG_ENDOFCH) { /* chg finished */
|
||||||
return;
|
ascodec_enrd0_shadow |= CHG_ENDOFCH;
|
||||||
|
|
||||||
if (data[0] & CHG_ENDOFCH) { /* chg finished */
|
|
||||||
IFDEBUG(int_chg_finished++);
|
IFDEBUG(int_chg_finished++);
|
||||||
}
|
}
|
||||||
if (data[0] & CHG_CHANGED) { /* chg status changed */
|
if (enrd0 & CHG_CHANGED) { /* chg status changed */
|
||||||
if (data[0] & CHG_STATUS) {
|
if (enrd0 & CHG_STATUS) {
|
||||||
|
ascodec_enrd0_shadow |= CHG_STATUS;
|
||||||
IFDEBUG(int_chg_insert++);
|
IFDEBUG(int_chg_insert++);
|
||||||
} else {
|
} else {
|
||||||
|
ascodec_enrd0_shadow &= ~CHG_STATUS;
|
||||||
IFDEBUG(int_chg_remove++);
|
IFDEBUG(int_chg_remove++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data[0] & USB_CHANGED) { /* usb status changed */
|
if (enrd0 & USB_CHANGED) { /* usb status changed */
|
||||||
if (data[0] & USB_STATUS) {
|
if (enrd0 & USB_STATUS) {
|
||||||
IFDEBUG(int_usb_insert++);
|
IFDEBUG(int_usb_insert++);
|
||||||
usb_insert_int();
|
usb_insert_int();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -454,6 +464,16 @@ static void ascodec_read_cb(unsigned const char *data, unsigned int len)
|
||||||
usb_remove_int();
|
usb_remove_int();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_CPU == AS3525
|
||||||
|
static void ascodec_read_cb(unsigned const char *data, unsigned int len)
|
||||||
|
{
|
||||||
|
if (len != 3) /* some error happened? */
|
||||||
|
return;
|
||||||
|
|
||||||
|
cache_enrd0(data[0]);
|
||||||
|
|
||||||
if (data[2] & IRQ_RTC) { /* rtc irq */
|
if (data[2] & IRQ_RTC) { /* rtc irq */
|
||||||
/*
|
/*
|
||||||
* Can be configured for once per second or once per minute,
|
* Can be configured for once per second or once per minute,
|
||||||
|
|
@ -468,23 +488,41 @@ static void ascodec_read_cb(unsigned const char *data, unsigned int len)
|
||||||
VIC_INT_ENABLE = INTERRUPT_AUDIO;
|
VIC_INT_ENABLE = INTERRUPT_AUDIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ascodec_wait_adc_finished(void)
|
|
||||||
{
|
|
||||||
wakeup_wait(&adc_wkup, TIMEOUT_BLOCK);
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_CPU == AS3525 */
|
#endif /* CONFIG_CPU == AS3525 */
|
||||||
|
|
||||||
|
void ascodec_wait_adc_finished(void)
|
||||||
void ascodec_enable_endofch_irq(void)
|
|
||||||
{
|
{
|
||||||
ascodec_write(AS3514_IRQ_ENRD0, ascodec_enrd0_shadow | CHG_ENDOFCH);
|
#if CONFIG_CPU == AS3525
|
||||||
|
wakeup_wait(&adc_wkup, TIMEOUT_BLOCK);
|
||||||
|
#else
|
||||||
|
/* no interrupts, busy wait
|
||||||
|
* XXX: make sure this is the only reader of IRQ_ENRD2
|
||||||
|
*/
|
||||||
|
while(!(ascodec_read(AS3514_IRQ_ENRD2) & IRQ_ADC))
|
||||||
|
yield();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void ascodec_disable_endofch_irq(void)
|
#ifdef CONFIG_CHARGING
|
||||||
|
bool ascodec_endofch(void)
|
||||||
{
|
{
|
||||||
ascodec_write(AS3514_IRQ_ENRD0, ascodec_enrd0_shadow & ~CHG_ENDOFCH);
|
#if CONFIG_CPU != AS3525
|
||||||
|
cache_enrd0(ascodec_read(AS3514_IRQ_ENRD0));
|
||||||
|
#endif
|
||||||
|
bool ret = ascodec_enrd0_shadow & CHG_ENDOFCH;
|
||||||
|
ascodec_enrd0_shadow &= ~CHG_ENDOFCH; // clear interrupt
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ascodec_chg_status(void)
|
||||||
|
{
|
||||||
|
#if CONFIG_CPU != AS3525
|
||||||
|
cache_enrd0(ascodec_read(AS3514_IRQ_ENRD0));
|
||||||
|
#endif
|
||||||
|
return ascodec_enrd0_shadow & CHG_STATUS;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_CHARGING */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* After the conversion to interrupts, ascodec_(lock|unlock) are only used by
|
* After the conversion to interrupts, ascodec_(lock|unlock) are only used by
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@
|
||||||
/*
|
/*
|
||||||
* How many bytes we using in struct ascodec_request for the data buffer.
|
* How many bytes we using in struct ascodec_request for the data buffer.
|
||||||
* 4 fits the alignment best right now.
|
* 4 fits the alignment best right now.
|
||||||
* We don't actually use more than 2 at the moment (in adc_read).
|
* We don't actually use more than 3 at the moment (when reading interrupts)
|
||||||
* Upper limit would be 255 since DACNT is 8 bits!
|
* Upper limit would be 255 since DACNT is 8 bits!
|
||||||
*/
|
*/
|
||||||
#define ASCODEC_REQ_MAXLEN 4
|
#define ASCODEC_REQ_MAXLEN 4
|
||||||
|
|
@ -74,19 +74,6 @@ void ascodec_init(void);
|
||||||
|
|
||||||
int ascodec_write(unsigned int index, unsigned int value);
|
int ascodec_write(unsigned int index, unsigned int value);
|
||||||
|
|
||||||
#if CONFIG_CPU == AS3525v2
|
|
||||||
static inline void ascodec_write_pmu(unsigned int index, unsigned int subreg,
|
|
||||||
unsigned int value)
|
|
||||||
{
|
|
||||||
/* we disable interrupts to make sure no operation happen on the i2c bus
|
|
||||||
* between selecting the sub register and writing to it */
|
|
||||||
int oldstatus = disable_irq_save();
|
|
||||||
ascodec_write(AS3543_PMU_ENABLE, 8|subreg);
|
|
||||||
ascodec_write(index, value);
|
|
||||||
restore_irq(oldstatus);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int ascodec_read(unsigned int index);
|
int ascodec_read(unsigned int index);
|
||||||
|
|
||||||
int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data);
|
int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data);
|
||||||
|
|
@ -119,18 +106,55 @@ void ascodec_lock(void);
|
||||||
|
|
||||||
void ascodec_unlock(void);
|
void ascodec_unlock(void);
|
||||||
|
|
||||||
#if CONFIG_CPU == AS3525
|
|
||||||
void ascodec_wait_adc_finished(void);
|
void ascodec_wait_adc_finished(void);
|
||||||
#else
|
|
||||||
static inline void ascodec_wait_adc_finished(void)
|
static inline void ascodec_monitor_endofch(void) {} /* already enabled */
|
||||||
|
|
||||||
|
bool ascodec_endofch(void);
|
||||||
|
|
||||||
|
bool ascodec_chg_status(void);
|
||||||
|
|
||||||
|
#if CONFIG_CPU == AS3525v2
|
||||||
|
static inline void ascodec_write_pmu(unsigned int index, unsigned int subreg,
|
||||||
|
unsigned int value)
|
||||||
{
|
{
|
||||||
/* FIXME: Doesn't work yet on AS3525v2 */
|
/* we disable interrupts to make sure no operation happen on the i2c bus
|
||||||
|
* between selecting the sub register and writing to it */
|
||||||
|
int oldstatus = disable_irq_save();
|
||||||
|
ascodec_write(AS3543_PMU_ENABLE, 8|subreg);
|
||||||
|
ascodec_write(index, value);
|
||||||
|
restore_irq(oldstatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int ascodec_read_pmu(unsigned int index, unsigned int subreg)
|
||||||
|
{
|
||||||
|
/* we disable interrupts to make sure no operation happen on the i2c bus
|
||||||
|
* between selecting the sub register and reading it */
|
||||||
|
int oldstatus = disable_irq_save();
|
||||||
|
ascodec_write(AS3543_PMU_ENABLE, 8|subreg);
|
||||||
|
int ret = ascodec_read(index);
|
||||||
|
restore_irq(oldstatus);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_CPU == AS3525v2 */
|
||||||
|
|
||||||
|
static inline void ascodec_write_charger(int value)
|
||||||
|
{
|
||||||
|
#if CONFIG_CPU == AS3525
|
||||||
|
ascodec_write(AS3514_CHARGER, value);
|
||||||
|
#else
|
||||||
|
ascodec_write_pmu(AS3543_CHARGER, 1, value);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void ascodec_enable_endofch_irq(void);
|
static inline int ascodec_read_charger(void)
|
||||||
|
{
|
||||||
void ascodec_disable_endofch_irq(void);
|
#if CONFIG_CPU == AS3525
|
||||||
|
return ascodec_read(AS3514_CHARGER);
|
||||||
|
#else
|
||||||
|
return ascodec_read_pmu(AS3543_CHARGER, 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !SIMULATOR */
|
#endif /* !SIMULATOR */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ void power_init(void)
|
||||||
#if CONFIG_CHARGING
|
#if CONFIG_CHARGING
|
||||||
unsigned int power_input_status(void)
|
unsigned int power_input_status(void)
|
||||||
{
|
{
|
||||||
return (ascodec_read(AS3514_IRQ_ENRD0) & (1<<5)) ?
|
return ascodec_chg_status() ?
|
||||||
POWER_INPUT_MAIN_CHARGER : POWER_INPUT_NONE;
|
POWER_INPUT_MAIN_CHARGER : POWER_INPUT_NONE;
|
||||||
|
|
||||||
/* TODO: Handle USB and other sources properly */
|
/* TODO: Handle USB and other sources properly */
|
||||||
|
|
|
||||||
|
|
@ -29,13 +29,7 @@
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "as3525.h"
|
#include "as3525.h"
|
||||||
|
|
||||||
#if CONFIG_CPU == AS3525
|
|
||||||
static int usb_status = USB_EXTRACTED;
|
static int usb_status = USB_EXTRACTED;
|
||||||
#else
|
|
||||||
#if defined(SANSA_CLIPV2)
|
|
||||||
#define USB_DETECT_PIN 6
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void usb_enable(bool on)
|
void usb_enable(bool on)
|
||||||
{
|
{
|
||||||
|
|
@ -51,12 +45,8 @@ void usb_enable(bool on)
|
||||||
|
|
||||||
void usb_init_device(void)
|
void usb_init_device(void)
|
||||||
{
|
{
|
||||||
#ifdef USB_DETECT_PIN
|
|
||||||
GPIOA_DIR &= ~(1 << USB_DETECT_PIN); /* set as input */
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_CPU == AS3525
|
|
||||||
void usb_insert_int(void)
|
void usb_insert_int(void)
|
||||||
{
|
{
|
||||||
usb_status = USB_INSERTED;
|
usb_status = USB_INSERTED;
|
||||||
|
|
@ -71,14 +61,3 @@ int usb_detect(void)
|
||||||
{
|
{
|
||||||
return usb_status;
|
return usb_status;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
int usb_detect(void)
|
|
||||||
{
|
|
||||||
#ifdef USB_DETECT_PIN
|
|
||||||
if (GPIOA_PIN( USB_DETECT_PIN ))
|
|
||||||
return USB_INSERTED;
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
return USB_EXTRACTED;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,7 @@
|
||||||
|
|
||||||
void usb_init_device(void);
|
void usb_init_device(void);
|
||||||
int usb_detect(void);
|
int usb_detect(void);
|
||||||
#if CONFIG_CPU == AS3525
|
|
||||||
void usb_insert_int(void);
|
void usb_insert_int(void);
|
||||||
void usb_remove_int(void);
|
void usb_remove_int(void);
|
||||||
#endif /* CONFIG_CPU == AS3525 */
|
|
||||||
|
|
||||||
#endif /* USB_TARGET_H */
|
#endif /* USB_TARGET_H */
|
||||||
|
|
|
||||||
|
|
@ -59,14 +59,19 @@ static inline void ascodec_unlock(void)
|
||||||
i2c_unlock();
|
i2c_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ascodec_enable_endofch_irq(void)
|
static inline bool ascodec_chg_status(void)
|
||||||
{
|
{
|
||||||
ascodec_write(AS3514_IRQ_ENRD0, IRQ_ENDOFCH);
|
return ascodec_read(AS3514_IRQ_ENRD0) & CHG_STATUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ascodec_disable_endofch_irq(void)
|
static inline bool ascodec_endofch(void)
|
||||||
{
|
{
|
||||||
ascodec_write(AS3514_IRQ_ENRD0, 0);
|
return ascodec_read(AS3514_IRQ_ENRD0) & CHG_ENDOFCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ascodec_monitor_endofch(void)
|
||||||
|
{
|
||||||
|
ascodec_write(AS3514_IRQ_ENRD0, IRQ_ENDOFCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ascodec_wait_adc_finished(void)
|
static inline void ascodec_wait_adc_finished(void)
|
||||||
|
|
@ -81,6 +86,16 @@ static inline void ascodec_wait_adc_finished(void)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void ascodec_write_charger(int value)
|
||||||
|
{
|
||||||
|
ascodec_write(AS3514_CHARGER, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ascodec_read_charger(void)
|
||||||
|
{
|
||||||
|
return ascodec_read(AS3514_CHARGER);
|
||||||
|
}
|
||||||
|
|
||||||
extern void ascodec_suppressor_on(bool on);
|
extern void ascodec_suppressor_on(bool on);
|
||||||
|
|
||||||
#endif /* CPU_PP */
|
#endif /* CPU_PP */
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,7 @@ static void battery_voltage_sync(void)
|
||||||
/* Disable charger and minimize all settings. Reset timers, etc. */
|
/* Disable charger and minimize all settings. Reset timers, etc. */
|
||||||
static void disable_charger(void)
|
static void disable_charger(void)
|
||||||
{
|
{
|
||||||
ascodec_disable_endofch_irq();
|
ascodec_write_charger(TMPSUP_OFF | CHG_I_50MA | CHG_V_3_90V | CHG_OFF);
|
||||||
ascodec_write(AS3514_CHARGER,
|
|
||||||
TMPSUP_OFF | CHG_I_50MA | CHG_V_3_90V | CHG_OFF);
|
|
||||||
|
|
||||||
if (charge_state > DISCHARGING)
|
if (charge_state > DISCHARGING)
|
||||||
charge_state = DISCHARGING; /* Not an error state already */
|
charge_state = DISCHARGING; /* Not an error state already */
|
||||||
|
|
@ -108,14 +106,13 @@ static void disable_charger(void)
|
||||||
/* Enable charger with specified settings. Start timers, etc. */
|
/* Enable charger with specified settings. Start timers, etc. */
|
||||||
static void enable_charger(void)
|
static void enable_charger(void)
|
||||||
{
|
{
|
||||||
ascodec_write(AS3514_CHARGER, BATT_CHG_I | BATT_CHG_V);
|
ascodec_write_charger(BATT_CHG_I | BATT_CHG_V);
|
||||||
/* Watch for end of charge. Temperature supervision is handled in
|
|
||||||
* hardware. Charger status can be read and has no interrupt enable. */
|
|
||||||
ascodec_enable_endofch_irq();
|
|
||||||
|
|
||||||
sleep(HZ/10); /* Allow charger turn-on time (it could be gradual). */
|
sleep(HZ/10); /* Allow charger turn-on time (it could be gradual). */
|
||||||
|
|
||||||
ascodec_disable_endofch_irq();
|
/* acknowledge first end of charging interrupt, it seems to happen both
|
||||||
|
* at charger plug and charger unplug */
|
||||||
|
ascodec_endofch();
|
||||||
|
|
||||||
charge_state = CHARGING;
|
charge_state = CHARGING;
|
||||||
charger_total_timer = CHARGER_TOTAL_TIMER;
|
charger_total_timer = CHARGER_TOTAL_TIMER;
|
||||||
|
|
@ -125,9 +122,8 @@ static void enable_charger(void)
|
||||||
void powermgmt_init_target(void)
|
void powermgmt_init_target(void)
|
||||||
{
|
{
|
||||||
/* Everything CHARGER, OFF! */
|
/* Everything CHARGER, OFF! */
|
||||||
ascodec_disable_endofch_irq();
|
ascodec_monitor_endofch();
|
||||||
ascodec_write(AS3514_CHARGER,
|
ascodec_write_charger(TMPSUP_OFF | CHG_I_50MA | CHG_V_3_90V | CHG_OFF);
|
||||||
TMPSUP_OFF | CHG_I_50MA | CHG_V_3_90V | CHG_OFF);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void charger_plugged(void)
|
static inline void charger_plugged(void)
|
||||||
|
|
@ -148,7 +144,7 @@ static inline void charger_control(void)
|
||||||
if (BATT_FULL_VOLTAGE == thresh)
|
if (BATT_FULL_VOLTAGE == thresh)
|
||||||
{
|
{
|
||||||
/* Wait for CHG_status to be indicated. */
|
/* Wait for CHG_status to be indicated. */
|
||||||
if ((ascodec_read(AS3514_IRQ_ENRD0) & CHG_STATUS) == 0)
|
if (!ascodec_chg_status())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
batt_threshold = BATT_VAUTO_RECHARGE;
|
batt_threshold = BATT_VAUTO_RECHARGE;
|
||||||
|
|
@ -163,7 +159,7 @@ static inline void charger_control(void)
|
||||||
|
|
||||||
case CHARGING:
|
case CHARGING:
|
||||||
{
|
{
|
||||||
if ((ascodec_read(AS3514_IRQ_ENRD0) & CHG_ENDOFCH) == 0)
|
if (!ascodec_endofch())
|
||||||
{
|
{
|
||||||
if (--charger_total_timer > 0)
|
if (--charger_total_timer > 0)
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue