aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/pcm.h2
-rw-r--r--sound/core/pcm_lib.c23
-rw-r--r--sound/pci/sis7019.c16
3 files changed, 25 insertions, 16 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index 07fd630db88d..304025b23520 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -317,7 +317,7 @@ struct snd_pcm_runtime {
317 struct snd_pcm_mmap_control *control; 317 struct snd_pcm_mmap_control *control;
318 318
319 /* -- locking / scheduling -- */ 319 /* -- locking / scheduling -- */
320 unsigned int twake: 1; /* do transfer (!poll) wakeup */ 320 snd_pcm_uframes_t twake; /* do transfer (!poll) wakeup if non-zero */
321 wait_queue_head_t sleep; /* poll sleep */ 321 wait_queue_head_t sleep; /* poll sleep */
322 wait_queue_head_t tsleep; /* transfer sleep */ 322 wait_queue_head_t tsleep; /* transfer sleep */
323 struct fasync_struct *fasync; 323 struct fasync_struct *fasync;
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index e9d98be190c5..bcf95d3ff5c7 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -287,8 +287,11 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
287 return -EPIPE; 287 return -EPIPE;
288 } 288 }
289 } 289 }
290 if (avail >= runtime->control->avail_min) 290 if (runtime->twake) {
291 wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep); 291 if (avail >= runtime->twake)
292 wake_up(&runtime->tsleep);
293 } else if (avail >= runtime->control->avail_min)
294 wake_up(&runtime->sleep);
292 return 0; 295 return 0;
293} 296}
294 297
@@ -1707,7 +1710,7 @@ EXPORT_SYMBOL(snd_pcm_period_elapsed);
1707 * The available space is stored on availp. When err = 0 and avail = 0 1710 * The available space is stored on availp. When err = 0 and avail = 0
1708 * on the capture stream, it indicates the stream is in DRAINING state. 1711 * on the capture stream, it indicates the stream is in DRAINING state.
1709 */ 1712 */
1710static int wait_for_avail_min(struct snd_pcm_substream *substream, 1713static int wait_for_avail(struct snd_pcm_substream *substream,
1711 snd_pcm_uframes_t *availp) 1714 snd_pcm_uframes_t *availp)
1712{ 1715{
1713 struct snd_pcm_runtime *runtime = substream->runtime; 1716 struct snd_pcm_runtime *runtime = substream->runtime;
@@ -1757,7 +1760,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream,
1757 avail = snd_pcm_playback_avail(runtime); 1760 avail = snd_pcm_playback_avail(runtime);
1758 else 1761 else
1759 avail = snd_pcm_capture_avail(runtime); 1762 avail = snd_pcm_capture_avail(runtime);
1760 if (avail >= runtime->control->avail_min) 1763 if (avail >= runtime->twake)
1761 break; 1764 break;
1762 } 1765 }
1763 _endloop: 1766 _endloop:
@@ -1820,7 +1823,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1820 goto _end_unlock; 1823 goto _end_unlock;
1821 } 1824 }
1822 1825
1823 runtime->twake = 1; 1826 runtime->twake = runtime->control->avail_min ? : 1;
1824 while (size > 0) { 1827 while (size > 0) {
1825 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 1828 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1826 snd_pcm_uframes_t avail; 1829 snd_pcm_uframes_t avail;
@@ -1833,7 +1836,9 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1833 err = -EAGAIN; 1836 err = -EAGAIN;
1834 goto _end_unlock; 1837 goto _end_unlock;
1835 } 1838 }
1836 err = wait_for_avail_min(substream, &avail); 1839 runtime->twake = min_t(snd_pcm_uframes_t, size,
1840 runtime->control->avail_min ? : 1);
1841 err = wait_for_avail(substream, &avail);
1837 if (err < 0) 1842 if (err < 0)
1838 goto _end_unlock; 1843 goto _end_unlock;
1839 } 1844 }
@@ -2042,7 +2047,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2042 goto _end_unlock; 2047 goto _end_unlock;
2043 } 2048 }
2044 2049
2045 runtime->twake = 1; 2050 runtime->twake = runtime->control->avail_min ? : 1;
2046 while (size > 0) { 2051 while (size > 0) {
2047 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 2052 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
2048 snd_pcm_uframes_t avail; 2053 snd_pcm_uframes_t avail;
@@ -2060,7 +2065,9 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2060 err = -EAGAIN; 2065 err = -EAGAIN;
2061 goto _end_unlock; 2066 goto _end_unlock;
2062 } 2067 }
2063 err = wait_for_avail_min(substream, &avail); 2068 runtime->twake = min_t(snd_pcm_uframes_t, size,
2069 runtime->control->avail_min ? : 1);
2070 err = wait_for_avail(substream, &avail);
2064 if (err < 0) 2071 if (err < 0)
2065 goto _end_unlock; 2072 goto _end_unlock;
2066 if (!avail) 2073 if (!avail)
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 9cc1b5aa0148..1b8f6742b5fa 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -264,11 +264,13 @@ static void sis_update_voice(struct voice *voice)
264 * if using small periods. 264 * if using small periods.
265 * 265 *
266 * If we're less than 9 samples behind, we're on target. 266 * If we're less than 9 samples behind, we're on target.
267 * Otherwise, shorten the next vperiod by the amount we've
268 * been delayed.
267 */ 269 */
268 if (sync > -9) 270 if (sync > -9)
269 voice->vperiod = voice->sync_period_size + 1; 271 voice->vperiod = voice->sync_period_size + 1;
270 else 272 else
271 voice->vperiod = voice->sync_period_size - 4; 273 voice->vperiod = voice->sync_period_size + sync + 10;
272 274
273 if (voice->vperiod < voice->buffer_size) { 275 if (voice->vperiod < voice->buffer_size) {
274 sis_update_sso(voice, voice->vperiod); 276 sis_update_sso(voice, voice->vperiod);
@@ -736,7 +738,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
736 period_size = buffer_size; 738 period_size = buffer_size;
737 739
738 /* Initially, we want to interrupt just a bit behind the end of 740 /* Initially, we want to interrupt just a bit behind the end of
739 * the period we're clocking out. 10 samples seems to give a good 741 * the period we're clocking out. 12 samples seems to give a good
740 * delay. 742 * delay.
741 * 743 *
742 * We want to spread our interrupts throughout the virtual period, 744 * We want to spread our interrupts throughout the virtual period,
@@ -747,7 +749,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
747 * 749 *
748 * This is all moot if we don't need to use virtual periods. 750 * This is all moot if we don't need to use virtual periods.
749 */ 751 */
750 vperiod = runtime->period_size + 10; 752 vperiod = runtime->period_size + 12;
751 if (vperiod > period_size) { 753 if (vperiod > period_size) {
752 u16 tail = vperiod % period_size; 754 u16 tail = vperiod % period_size;
753 u16 quarter_period = period_size / 4; 755 u16 quarter_period = period_size / 4;
@@ -776,7 +778,7 @@ static void sis_prepare_timing_voice(struct voice *voice,
776 */ 778 */
777 timing->flags |= VOICE_SYNC_TIMING; 779 timing->flags |= VOICE_SYNC_TIMING;
778 timing->sync_base = voice->ctrl_base; 780 timing->sync_base = voice->ctrl_base;
779 timing->sync_cso = runtime->period_size - 1; 781 timing->sync_cso = runtime->period_size;
780 timing->sync_period_size = runtime->period_size; 782 timing->sync_period_size = runtime->period_size;
781 timing->sync_buffer_size = runtime->buffer_size; 783 timing->sync_buffer_size = runtime->buffer_size;
782 timing->period_size = period_size; 784 timing->period_size = period_size;
@@ -1047,7 +1049,7 @@ static int sis_chip_free(struct sis7019 *sis)
1047 /* Reset the chip, and disable all interrputs. 1049 /* Reset the chip, and disable all interrputs.
1048 */ 1050 */
1049 outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR); 1051 outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR);
1050 udelay(10); 1052 udelay(25);
1051 outl(0, sis->ioport + SIS_GCR); 1053 outl(0, sis->ioport + SIS_GCR);
1052 outl(0, sis->ioport + SIS_GIER); 1054 outl(0, sis->ioport + SIS_GIER);
1053 1055
@@ -1083,7 +1085,7 @@ static int sis_chip_init(struct sis7019 *sis)
1083 /* Reset the audio controller 1085 /* Reset the audio controller
1084 */ 1086 */
1085 outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR); 1087 outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR);
1086 udelay(10); 1088 udelay(25);
1087 outl(0, io + SIS_GCR); 1089 outl(0, io + SIS_GCR);
1088 1090
1089 /* Get the AC-link semaphore, and reset the codecs 1091 /* Get the AC-link semaphore, and reset the codecs
@@ -1096,7 +1098,7 @@ static int sis_chip_init(struct sis7019 *sis)
1096 return -EIO; 1098 return -EIO;
1097 1099
1098 outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD); 1100 outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD);
1099 udelay(10); 1101 udelay(250);
1100 1102
1101 count = 0xffff; 1103 count = 0xffff;
1102 while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) 1104 while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)