aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sound/pcm.h1
-rw-r--r--sound/core/oss/pcm_oss.c3
-rw-r--r--sound/core/pcm_lib.c7
-rw-r--r--sound/core/pcm_native.c2
-rw-r--r--sound/pci/hda/patch_analog.c11
5 files changed, 19 insertions, 5 deletions
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index ee16122a1886..8b611a561985 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -271,6 +271,7 @@ struct snd_pcm_runtime {
271 int overrange; 271 int overrange;
272 snd_pcm_uframes_t avail_max; 272 snd_pcm_uframes_t avail_max;
273 snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */ 273 snd_pcm_uframes_t hw_ptr_base; /* Position at buffer restart */
274 snd_pcm_uframes_t hw_ptr_interrupt; /* Position at interrupt time */
274 unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */ 275 unsigned long hw_ptr_jiffies; /* Time when hw_ptr is updated */
275 snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */ 276 snd_pcm_sframes_t delay; /* extra delay; typically FIFO size */
276 277
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 255ad910077a..82d4e3329b3d 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -635,8 +635,7 @@ static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes)
635static inline 635static inline
636snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime) 636snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime)
637{ 637{
638 snd_pcm_uframes_t ptr = runtime->status->hw_ptr; 638 return runtime->hw_ptr_interrupt;
639 return ptr - (ptr % runtime->period_size);
640} 639}
641 640
642/* define extended formats in the recent OSS versions (if any) */ 641/* define extended formats in the recent OSS versions (if any) */
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 272f15d19017..b546ac2660f9 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -325,8 +325,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
325 if (in_interrupt) { 325 if (in_interrupt) {
326 /* we know that one period was processed */ 326 /* we know that one period was processed */
327 /* delta = "expected next hw_ptr" for in_interrupt != 0 */ 327 /* delta = "expected next hw_ptr" for in_interrupt != 0 */
328 delta = old_hw_ptr - (old_hw_ptr % runtime->period_size) 328 delta = runtime->hw_ptr_interrupt + runtime->period_size;
329 + runtime->period_size;
330 if (delta > new_hw_ptr) { 329 if (delta > new_hw_ptr) {
331 hw_base += runtime->buffer_size; 330 hw_base += runtime->buffer_size;
332 if (hw_base >= runtime->boundary) 331 if (hw_base >= runtime->boundary)
@@ -437,6 +436,10 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
437 runtime->silence_size > 0) 436 runtime->silence_size > 0)
438 snd_pcm_playback_silence(substream, new_hw_ptr); 437 snd_pcm_playback_silence(substream, new_hw_ptr);
439 438
439 if (in_interrupt) {
440 runtime->hw_ptr_interrupt = new_hw_ptr -
441 (new_hw_ptr % runtime->period_size);
442 }
440 runtime->hw_ptr_base = hw_base; 443 runtime->hw_ptr_base = hw_base;
441 runtime->status->hw_ptr = new_hw_ptr; 444 runtime->status->hw_ptr = new_hw_ptr;
442 runtime->hw_ptr_jiffies = jiffies; 445 runtime->hw_ptr_jiffies = jiffies;
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index b53fa845004d..b79c777d2118 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1252,6 +1252,8 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
1252 if (err < 0) 1252 if (err < 0)
1253 return err; 1253 return err;
1254 runtime->hw_ptr_base = 0; 1254 runtime->hw_ptr_base = 0;
1255 runtime->hw_ptr_interrupt = runtime->status->hw_ptr -
1256 runtime->status->hw_ptr % runtime->period_size;
1255 runtime->silence_start = runtime->status->hw_ptr; 1257 runtime->silence_start = runtime->status->hw_ptr;
1256 runtime->silence_filled = 0; 1258 runtime->silence_filled = 0;
1257 return 0; 1259 return 0;
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index cecd3c108990..865715e3f938 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -2458,6 +2458,12 @@ static struct hda_verb ad1988_spdif_init_verbs[] = {
2458 { } 2458 { }
2459}; 2459};
2460 2460
2461static struct hda_verb ad1988_spdif_in_init_verbs[] = {
2462 /* unmute SPDIF input pin */
2463 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2464 { }
2465};
2466
2461/* AD1989 has no ADC -> SPDIF route */ 2467/* AD1989 has no ADC -> SPDIF route */
2462static struct hda_verb ad1989_spdif_init_verbs[] = { 2468static struct hda_verb ad1989_spdif_init_verbs[] = {
2463 /* SPDIF-1 out pin */ 2469 /* SPDIF-1 out pin */
@@ -3193,8 +3199,11 @@ static int patch_ad1988(struct hda_codec *codec)
3193 ad1988_spdif_init_verbs; 3199 ad1988_spdif_init_verbs;
3194 } 3200 }
3195 } 3201 }
3196 if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) 3202 if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3197 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers; 3203 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3204 spec->init_verbs[spec->num_init_verbs++] =
3205 ad1988_spdif_in_init_verbs;
3206 }
3198 3207
3199 codec->patch_ops = ad198x_patch_ops; 3208 codec->patch_ops = ad198x_patch_ops;
3200 switch (board_config) { 3209 switch (board_config) {