Commit 65ee2ba3 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'devel' of git://git.alsa-project.org/alsa-kernel into topic/misc

parents b415ec70 08b45098
...@@ -317,7 +317,7 @@ struct snd_pcm_runtime { ...@@ -317,7 +317,7 @@ struct snd_pcm_runtime {
struct snd_pcm_mmap_control *control; struct snd_pcm_mmap_control *control;
/* -- locking / scheduling -- */ /* -- locking / scheduling -- */
unsigned int twake: 1; /* do transfer (!poll) wakeup */ snd_pcm_uframes_t twake; /* do transfer (!poll) wakeup if non-zero */
wait_queue_head_t sleep; /* poll sleep */ wait_queue_head_t sleep; /* poll sleep */
wait_queue_head_t tsleep; /* transfer sleep */ wait_queue_head_t tsleep; /* transfer sleep */
struct fasync_struct *fasync; struct fasync_struct *fasync;
......
...@@ -287,8 +287,11 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream, ...@@ -287,8 +287,11 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
return -EPIPE; return -EPIPE;
} }
} }
if (avail >= runtime->control->avail_min) if (runtime->twake) {
wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep); if (avail >= runtime->twake)
wake_up(&runtime->tsleep);
} else if (avail >= runtime->control->avail_min)
wake_up(&runtime->sleep);
return 0; return 0;
} }
...@@ -1707,7 +1710,7 @@ EXPORT_SYMBOL(snd_pcm_period_elapsed); ...@@ -1707,7 +1710,7 @@ EXPORT_SYMBOL(snd_pcm_period_elapsed);
* The available space is stored on availp. When err = 0 and avail = 0 * The available space is stored on availp. When err = 0 and avail = 0
* on the capture stream, it indicates the stream is in DRAINING state. * on the capture stream, it indicates the stream is in DRAINING state.
*/ */
static int wait_for_avail_min(struct snd_pcm_substream *substream, static int wait_for_avail(struct snd_pcm_substream *substream,
snd_pcm_uframes_t *availp) snd_pcm_uframes_t *availp)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
...@@ -1757,7 +1760,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream, ...@@ -1757,7 +1760,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream,
avail = snd_pcm_playback_avail(runtime); avail = snd_pcm_playback_avail(runtime);
else else
avail = snd_pcm_capture_avail(runtime); avail = snd_pcm_capture_avail(runtime);
if (avail >= runtime->control->avail_min) if (avail >= runtime->twake)
break; break;
} }
_endloop: _endloop:
...@@ -1820,7 +1823,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, ...@@ -1820,7 +1823,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
goto _end_unlock; goto _end_unlock;
} }
runtime->twake = 1; runtime->twake = runtime->control->avail_min ? : 1;
while (size > 0) { while (size > 0) {
snd_pcm_uframes_t frames, appl_ptr, appl_ofs; snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
snd_pcm_uframes_t avail; snd_pcm_uframes_t avail;
...@@ -1833,7 +1836,9 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream, ...@@ -1833,7 +1836,9 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
err = -EAGAIN; err = -EAGAIN;
goto _end_unlock; goto _end_unlock;
} }
err = wait_for_avail_min(substream, &avail); runtime->twake = min_t(snd_pcm_uframes_t, size,
runtime->control->avail_min ? : 1);
err = wait_for_avail(substream, &avail);
if (err < 0) if (err < 0)
goto _end_unlock; goto _end_unlock;
} }
...@@ -2042,7 +2047,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, ...@@ -2042,7 +2047,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
goto _end_unlock; goto _end_unlock;
} }
runtime->twake = 1; runtime->twake = runtime->control->avail_min ? : 1;
while (size > 0) { while (size > 0) {
snd_pcm_uframes_t frames, appl_ptr, appl_ofs; snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
snd_pcm_uframes_t avail; snd_pcm_uframes_t avail;
...@@ -2060,7 +2065,9 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream, ...@@ -2060,7 +2065,9 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
err = -EAGAIN; err = -EAGAIN;
goto _end_unlock; goto _end_unlock;
} }
err = wait_for_avail_min(substream, &avail); runtime->twake = min_t(snd_pcm_uframes_t, size,
runtime->control->avail_min ? : 1);
err = wait_for_avail(substream, &avail);
if (err < 0) if (err < 0)
goto _end_unlock; goto _end_unlock;
if (!avail) if (!avail)
......
...@@ -264,11 +264,13 @@ static void sis_update_voice(struct voice *voice) ...@@ -264,11 +264,13 @@ static void sis_update_voice(struct voice *voice)
* if using small periods. * if using small periods.
* *
* If we're less than 9 samples behind, we're on target. * If we're less than 9 samples behind, we're on target.
* Otherwise, shorten the next vperiod by the amount we've
* been delayed.
*/ */
if (sync > -9) if (sync > -9)
voice->vperiod = voice->sync_period_size + 1; voice->vperiod = voice->sync_period_size + 1;
else else
voice->vperiod = voice->sync_period_size - 4; voice->vperiod = voice->sync_period_size + sync + 10;
if (voice->vperiod < voice->buffer_size) { if (voice->vperiod < voice->buffer_size) {
sis_update_sso(voice, voice->vperiod); sis_update_sso(voice, voice->vperiod);
...@@ -736,7 +738,7 @@ static void sis_prepare_timing_voice(struct voice *voice, ...@@ -736,7 +738,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
period_size = buffer_size; period_size = buffer_size;
/* Initially, we want to interrupt just a bit behind the end of /* Initially, we want to interrupt just a bit behind the end of
* the period we're clocking out. 10 samples seems to give a good * the period we're clocking out. 12 samples seems to give a good
* delay. * delay.
* *
* We want to spread our interrupts throughout the virtual period, * We want to spread our interrupts throughout the virtual period,
...@@ -747,7 +749,7 @@ static void sis_prepare_timing_voice(struct voice *voice, ...@@ -747,7 +749,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
* *
* This is all moot if we don't need to use virtual periods. * This is all moot if we don't need to use virtual periods.
*/ */
vperiod = runtime->period_size + 10; vperiod = runtime->period_size + 12;
if (vperiod > period_size) { if (vperiod > period_size) {
u16 tail = vperiod % period_size; u16 tail = vperiod % period_size;
u16 quarter_period = period_size / 4; u16 quarter_period = period_size / 4;
...@@ -776,7 +778,7 @@ static void sis_prepare_timing_voice(struct voice *voice, ...@@ -776,7 +778,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
*/ */
timing->flags |= VOICE_SYNC_TIMING; timing->flags |= VOICE_SYNC_TIMING;
timing->sync_base = voice->ctrl_base; timing->sync_base = voice->ctrl_base;
timing->sync_cso = runtime->period_size - 1; timing->sync_cso = runtime->period_size;
timing->sync_period_size = runtime->period_size; timing->sync_period_size = runtime->period_size;
timing->sync_buffer_size = runtime->buffer_size; timing->sync_buffer_size = runtime->buffer_size;
timing->period_size = period_size; timing->period_size = period_size;
...@@ -1047,7 +1049,7 @@ static int sis_chip_free(struct sis7019 *sis) ...@@ -1047,7 +1049,7 @@ static int sis_chip_free(struct sis7019 *sis)
/* Reset the chip, and disable all interrputs. /* Reset the chip, and disable all interrputs.
*/ */
outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR); outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR);
udelay(10); udelay(25);
outl(0, sis->ioport + SIS_GCR); outl(0, sis->ioport + SIS_GCR);
outl(0, sis->ioport + SIS_GIER); outl(0, sis->ioport + SIS_GIER);
...@@ -1083,7 +1085,7 @@ static int sis_chip_init(struct sis7019 *sis) ...@@ -1083,7 +1085,7 @@ static int sis_chip_init(struct sis7019 *sis)
/* Reset the audio controller /* Reset the audio controller
*/ */
outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR); outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR);
udelay(10); udelay(25);
outl(0, io + SIS_GCR); outl(0, io + SIS_GCR);
/* Get the AC-link semaphore, and reset the codecs /* Get the AC-link semaphore, and reset the codecs
...@@ -1096,7 +1098,7 @@ static int sis_chip_init(struct sis7019 *sis) ...@@ -1096,7 +1098,7 @@ static int sis_chip_init(struct sis7019 *sis)
return -EIO; return -EIO;
outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD); outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD);
udelay(10); udelay(250);
count = 0xffff; count = 0xffff;
while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment