diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2007-10-16 08:54:58 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2007-10-23 02:04:28 -0400 |
commit | 9823adf632c57e9728d651707abd324eb4454eb9 (patch) | |
tree | a0d7b62ff0e0b1556be3fb919faf652b7019999b /sound | |
parent | 0895e91d60ef9bdef426d1ce14bb94bd5875870d (diff) |
[ALSA] This simplifies and fixes waiting loops of the mce_down()
function after Trent Piepho's patch for AD1848.
It also makes busy_wait() function call not atomic.
Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/sparc/cs4231.c | 59 |
1 files changed, 19 insertions, 40 deletions
diff --git a/sound/sparc/cs4231.c b/sound/sparc/cs4231.c index 9785382a5f39..f8c7a120ccbb 100644 --- a/sound/sparc/cs4231.c +++ b/sound/sparc/cs4231.c | |||
@@ -400,65 +400,44 @@ static void snd_cs4231_mce_up(struct snd_cs4231 *chip) | |||
400 | 400 | ||
401 | static void snd_cs4231_mce_down(struct snd_cs4231 *chip) | 401 | static void snd_cs4231_mce_down(struct snd_cs4231 *chip) |
402 | { | 402 | { |
403 | unsigned long flags; | 403 | unsigned long flags, timeout; |
404 | unsigned long end_time; | 404 | int reg; |
405 | int timeout; | ||
406 | 405 | ||
407 | spin_lock_irqsave(&chip->lock, flags); | ||
408 | snd_cs4231_busy_wait(chip); | 406 | snd_cs4231_busy_wait(chip); |
407 | spin_lock_irqsave(&chip->lock, flags); | ||
409 | #ifdef CONFIG_SND_DEBUG | 408 | #ifdef CONFIG_SND_DEBUG |
410 | if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) | 409 | if (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) |
411 | snd_printdd("mce_down [%p] - auto calibration time out (0)\n", | 410 | snd_printdd("mce_down [%p] - auto calibration time out (0)\n", |
412 | CS4231U(chip, REGSEL)); | 411 | CS4231U(chip, REGSEL)); |
413 | #endif | 412 | #endif |
414 | chip->mce_bit &= ~CS4231_MCE; | 413 | chip->mce_bit &= ~CS4231_MCE; |
415 | timeout = __cs4231_readb(chip, CS4231U(chip, REGSEL)); | 414 | reg = __cs4231_readb(chip, CS4231U(chip, REGSEL)); |
416 | __cs4231_writeb(chip, chip->mce_bit | (timeout & 0x1f), | 415 | __cs4231_writeb(chip, chip->mce_bit | (reg & 0x1f), |
417 | CS4231U(chip, REGSEL)); | 416 | CS4231U(chip, REGSEL)); |
418 | if (timeout == 0x80) | 417 | if (reg == 0x80) |
419 | snd_printdd("mce_down [%p]: serious init problem - " | 418 | snd_printdd("mce_down [%p]: serious init problem " |
420 | "codec still busy\n", | 419 | "- codec still busy\n", chip->port); |
421 | chip->port); | 420 | if ((reg & CS4231_MCE) == 0) { |
422 | if ((timeout & CS4231_MCE) == 0) { | ||
423 | spin_unlock_irqrestore(&chip->lock, flags); | 421 | spin_unlock_irqrestore(&chip->lock, flags); |
424 | return; | 422 | return; |
425 | } | 423 | } |
426 | 424 | ||
427 | /* | 425 | /* |
428 | * Wait for (possible -- during init auto-calibration may not be set) | 426 | * Wait for auto-calibration (AC) process to finish, i.e. ACI to go low. |
429 | * calibration process to start. Needs upto 5 sample periods on AD1848 | ||
430 | * which at the slowest possible rate of 5.5125 kHz means 907 us. | ||
431 | */ | 427 | */ |
432 | msleep(1); | 428 | timeout = jiffies + msecs_to_jiffies(250); |
433 | 429 | do { | |
434 | /* check condition up to 250ms */ | ||
435 | end_time = jiffies + msecs_to_jiffies(250); | ||
436 | while (snd_cs4231_in(chip, CS4231_TEST_INIT) & | ||
437 | CS4231_CALIB_IN_PROGRESS) { | ||
438 | |||
439 | spin_unlock_irqrestore(&chip->lock, flags); | 430 | spin_unlock_irqrestore(&chip->lock, flags); |
440 | if (time_after(jiffies, end_time)) { | ||
441 | snd_printk("mce_down - " | ||
442 | "auto calibration time out (2)\n"); | ||
443 | return; | ||
444 | } | ||
445 | msleep(1); | ||
446 | spin_lock_irqsave(&chip->lock, flags); | ||
447 | } | ||
448 | |||
449 | /* check condition up to 100ms */ | ||
450 | end_time = jiffies + msecs_to_jiffies(100); | ||
451 | while (__cs4231_readb(chip, CS4231U(chip, REGSEL)) & CS4231_INIT) { | ||
452 | spin_unlock_irqrestore(&chip->lock, flags); | ||
453 | if (time_after(jiffies, end_time)) { | ||
454 | snd_printk("mce_down - " | ||
455 | "auto calibration time out (3)\n"); | ||
456 | return; | ||
457 | } | ||
458 | msleep(1); | 431 | msleep(1); |
459 | spin_lock_irqsave(&chip->lock, flags); | 432 | spin_lock_irqsave(&chip->lock, flags); |
460 | } | 433 | reg = snd_cs4231_in(chip, CS4231_TEST_INIT); |
434 | reg &= CS4231_CALIB_IN_PROGRESS; | ||
435 | } while (reg && time_before(jiffies, timeout)); | ||
461 | spin_unlock_irqrestore(&chip->lock, flags); | 436 | spin_unlock_irqrestore(&chip->lock, flags); |
437 | |||
438 | if (reg) | ||
439 | snd_printk(KERN_ERR | ||
440 | "mce_down - auto calibration time out (2)\n"); | ||
462 | } | 441 | } |
463 | 442 | ||
464 | static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont, | 443 | static void snd_cs4231_advance_dma(struct cs4231_dma_control *dma_cont, |