Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 16169
b: refs/heads/master
c: ea265c0
h: refs/heads/master
i:
  16167: ccc9a12
v: v3
  • Loading branch information
Nicolas Pitre authored and Jaroslav Kysela committed Jan 3, 2006
1 parent 9b0290f commit 52b9876
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 18 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: aa1e77e691025149908f7641e77de93ffd7f1188
refs/heads/master: ea265c0a433fda15fb69b9fd733e0ea4215c216e
39 changes: 22 additions & 17 deletions trunk/sound/arm/pxa2xx-ac97.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,39 +37,47 @@ static DECLARE_MUTEX(car_mutex);
static DECLARE_WAIT_QUEUE_HEAD(gsr_wq);
static volatile long gsr_bits;

/*
* Beware PXA27x bugs:
*
* o Slot 12 read from modem space will hang controller.
* o CDONE, SDONE interrupt fails after any slot 12 IO.
*
* We therefore have an hybrid approach for waiting on SDONE (interrupt or
* 1 jiffy timeout if interrupt never comes).
*/

static unsigned short pxa2xx_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
{
unsigned short val = -1;
volatile u32 *reg_addr;

down(&car_mutex);
if (CAR & CAR_CAIP) {
printk(KERN_CRIT"%s: CAR_CAIP already set\n", __FUNCTION__);
goto out;
}

/* set up primary or secondary codec space */
reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
reg_addr += (reg >> 1);

/* start read access across the ac97 link */
GSR = GSR_CDONE | GSR_SDONE;
gsr_bits = 0;
val = *reg_addr;
if (reg == AC97_GPIO_STATUS)
goto out;
wait_event_timeout(gsr_wq, gsr_bits & GSR_SDONE, 1);
if (!gsr_bits & GSR_SDONE) {
if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1) <= 0 &&
!((GSR | gsr_bits) & GSR_SDONE)) {
printk(KERN_ERR "%s: read error (ac97_reg=%d GSR=%#lx)\n",
__FUNCTION__, reg, gsr_bits);
__FUNCTION__, reg, GSR | gsr_bits);
val = -1;
goto out;
}

/* valid data now */
GSR = GSR_CDONE | GSR_SDONE;
gsr_bits = 0;
val = *reg_addr;
/* but we've just started another cycle... */
wait_event_timeout(gsr_wq, gsr_bits & GSR_SDONE, 1);
wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_SDONE, 1);

out: up(&car_mutex);
return val;
Expand All @@ -81,22 +89,19 @@ static void pxa2xx_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigne

down(&car_mutex);

if (CAR & CAR_CAIP) {
printk(KERN_CRIT "%s: CAR_CAIP already set\n", __FUNCTION__);
goto out;
}

/* set up primary or secondary codec space */
reg_addr = (ac97->num & 1) ? &SAC_REG_BASE : &PAC_REG_BASE;
reg_addr += (reg >> 1);

GSR = GSR_CDONE | GSR_SDONE;
gsr_bits = 0;
*reg_addr = val;
wait_event_timeout(gsr_wq, gsr_bits & GSR_CDONE, 1);
if (!gsr_bits & GSR_SDONE)
if (wait_event_timeout(gsr_wq, (GSR | gsr_bits) & GSR_CDONE, 1) <= 0 &&
!((GSR | gsr_bits) & GSR_CDONE))
printk(KERN_ERR "%s: write error (ac97_reg=%d GSR=%#lx)\n",
__FUNCTION__, reg, gsr_bits);
__FUNCTION__, reg, GSR | gsr_bits);

out: up(&car_mutex);
up(&car_mutex);
}

static void pxa2xx_ac97_reset(struct snd_ac97 *ac97)
Expand Down

0 comments on commit 52b9876

Please sign in to comment.