mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-08 12:45:26 -05:00
Commit the ascodec-as3525.c/ascodec-target.h changes from FS#12452 that keep ascodec_read/write_pmu from keeping interrupts disabled for the full duration of two I2C transfers, which can contribute to I2S PUSH/POP FIFO under/over-flows. 'Tis peppered with a couple interrupt safety mods as well.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31264 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
47bade1437
commit
2026c9506c
2 changed files with 42 additions and 25 deletions
|
|
@ -115,7 +115,7 @@ struct ascodec_request {
|
|||
|
||||
static struct mutex as_mtx;
|
||||
|
||||
static int ascodec_enrd0_shadow = 0;
|
||||
static unsigned long ascodec_enrd0_shadow = 0;
|
||||
|
||||
static unsigned char *req_data_ptr = NULL;
|
||||
static struct ascodec_request *req_head = NULL;
|
||||
|
|
@ -160,8 +160,8 @@ static void ascodec_finish_req(struct ascodec_request *req)
|
|||
*/
|
||||
while (i2c_busy());
|
||||
|
||||
/* disable clock - already in IRQ context */
|
||||
CGU_PERI &= ~CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE;
|
||||
/* disable clock */
|
||||
bitclr32(&CGU_PERI, CGU_I2C_AUDIO_MASTER_CLOCK_ENABLE);
|
||||
|
||||
req->status = 1;
|
||||
|
||||
|
|
@ -434,6 +434,41 @@ int ascodec_readbytes(unsigned int index, unsigned int len, unsigned char *data)
|
|||
return i;
|
||||
}
|
||||
|
||||
#if CONFIG_CPU == AS3525v2
|
||||
void ascodec_write_pmu(unsigned int index, unsigned int subreg,
|
||||
unsigned int value)
|
||||
{
|
||||
struct ascodec_request reqs[2];
|
||||
|
||||
int oldstatus = disable_irq_save();
|
||||
/* we submit consecutive requests to make sure no operations happen on the
|
||||
* i2c bus between selecting the sub register and writing to it */
|
||||
ascodec_async_write(AS3543_PMU_ENABLE, 8 | subreg, &reqs[0]);
|
||||
ascodec_async_write(index, value, &reqs[1]);
|
||||
restore_irq(oldstatus);
|
||||
|
||||
/* Wait for second request to finish */
|
||||
ascodec_wait(&reqs[1]);
|
||||
}
|
||||
|
||||
int ascodec_read_pmu(unsigned int index, unsigned int subreg)
|
||||
{
|
||||
struct ascodec_request reqs[2];
|
||||
|
||||
int oldstatus = disable_irq_save();
|
||||
/* we submit consecutive requests to make sure no operations happen on the
|
||||
* i2c bus between selecting the sub register and reading it */
|
||||
ascodec_async_write(AS3543_PMU_ENABLE, subreg, &reqs[0]);
|
||||
ascodec_async_read(index, 1, &reqs[1], NULL);
|
||||
restore_irq(oldstatus);
|
||||
|
||||
/* Wait for second request to finish */
|
||||
ascodec_wait(&reqs[1]);
|
||||
|
||||
return reqs[1].data[0];
|
||||
}
|
||||
#endif /* CONFIG_CPU == AS3525v2 */
|
||||
|
||||
static void ascodec_read_cb(unsigned const char *data, unsigned int len)
|
||||
{
|
||||
if (UNLIKELY(len != 3)) /* some error happened? */
|
||||
|
|
@ -492,7 +527,7 @@ void ascodec_wait_adc_finished(void)
|
|||
bool ascodec_endofch(void)
|
||||
{
|
||||
bool ret = ascodec_enrd0_shadow & CHG_ENDOFCH;
|
||||
ascodec_enrd0_shadow &= ~CHG_ENDOFCH; // clear interrupt
|
||||
bitclr32(&ascodec_enrd0_shadow, CHG_ENDOFCH); /* clear interrupt */
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -67,27 +67,9 @@ 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)
|
||||
{
|
||||
/* 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, subreg);
|
||||
int ret = ascodec_read(index);
|
||||
restore_irq(oldstatus);
|
||||
return ret;
|
||||
}
|
||||
void ascodec_write_pmu(unsigned int index, unsigned int subreg,
|
||||
unsigned int value);
|
||||
int ascodec_read_pmu(unsigned int index, unsigned int subreg);
|
||||
#endif /* CONFIG_CPU == AS3525v2 */
|
||||
|
||||
static inline void ascodec_write_charger(int value)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue