aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Courtier-Dutton <James@superbug.co.uk>2005-04-09 17:38:25 -0400
committerJaroslav Kysela <perex@suse.cz>2005-05-29 03:58:49 -0400
commit001f758990d685e7023008763795f1970ef56614 (patch)
treee460f23636ebf2aa45e185b5936243400e8b68b4
parentdf34140a9c15d4be8833f7977dca277a03ab87b0 (diff)
[ALSA] Improve SPDIF playback via the P16V/CA0151 chip.
EMU10K1/EMU10K2 driver Although we can set 44100 as the output rate, the SPDIF can do it, but the Analog output cannot. The SPDIF has the bug, whereby the Left channel arrives one sample late, so although we don't do any resampling, it is not good for AC3 non-audio output. Signed-off-by: James Courtier-Dutton <James@superbug.co.uk>
-rw-r--r--include/sound/emu10k1.h1
-rw-r--r--sound/pci/emu10k1/emumixer.c2
-rw-r--r--sound/pci/emu10k1/emuproc.c21
-rw-r--r--sound/pci/emu10k1/p16v.c16
4 files changed, 31 insertions, 9 deletions
diff --git a/include/sound/emu10k1.h b/include/sound/emu10k1.h
index f5babd3f8452..61a3f418f302 100644
--- a/include/sound/emu10k1.h
+++ b/include/sound/emu10k1.h
@@ -747,6 +747,7 @@
747 /* Assumes sample lock */ 747 /* Assumes sample lock */
748 748
749/* These three bitfields apply to CDSRCS, GPSRCS, and (except as noted) ZVSRCS. */ 749/* These three bitfields apply to CDSRCS, GPSRCS, and (except as noted) ZVSRCS. */
750#define SRCS_SPDIFVALID 0x04000000 /* SPDIF stream valid */
750#define SRCS_SPDIFLOCKED 0x02000000 /* SPDIF stream locked */ 751#define SRCS_SPDIFLOCKED 0x02000000 /* SPDIF stream locked */
751#define SRCS_RATELOCKED 0x01000000 /* Sample rate locked */ 752#define SRCS_RATELOCKED 0x01000000 /* Sample rate locked */
752#define SRCS_ESTSAMPLERATE 0x0007ffff /* Do not modify this field. */ 753#define SRCS_ESTSAMPLERATE 0x0007ffff /* Do not modify this field. */
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index d0b296587cc0..b544c2582663 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -935,10 +935,12 @@ int __devinit snd_emu10k1_mixer(emu10k1_t *emu)
935 return -ENOMEM; 935 return -ENOMEM;
936 if ((err = snd_ctl_add(card, kctl))) 936 if ((err = snd_ctl_add(card, kctl)))
937 return err; 937 return err;
938#if 0
938 if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL) 939 if ((kctl = snd_ctl_new1(&snd_audigy_spdif_output_rate, emu)) == NULL)
939 return -ENOMEM; 940 return -ENOMEM;
940 if ((err = snd_ctl_add(card, kctl))) 941 if ((err = snd_ctl_add(card, kctl)))
941 return err; 942 return err;
943#endif
942 } else if (! emu->card_capabilities->ecard) { 944 } else if (! emu->card_capabilities->ecard) {
943 /* sb live! */ 945 /* sb live! */
944 if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL) 946 if ((kctl = snd_ctl_new1(&snd_emu10k1_shared_spdif, emu)) == NULL)
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index 187a4e60a5fe..356fb7104253 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -30,6 +30,7 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <sound/core.h> 31#include <sound/core.h>
32#include <sound/emu10k1.h> 32#include <sound/emu10k1.h>
33#include "p16v.h"
33 34
34static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu, 35static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu,
35 snd_info_buffer_t * buffer, 36 snd_info_buffer_t * buffer,
@@ -62,6 +63,7 @@ static void snd_emu10k1_proc_spdif_status(emu10k1_t * emu,
62 63
63 if (rate_reg > 0) { 64 if (rate_reg > 0) {
64 rate = snd_emu10k1_ptr_read(emu, rate_reg, 0); 65 rate = snd_emu10k1_ptr_read(emu, rate_reg, 0);
66 snd_iprintf(buffer, "S/PDIF Valid : %s\n", rate & SRCS_SPDIFVALID ? "on" : "off");
65 snd_iprintf(buffer, "S/PDIF Locked : %s\n", rate & SRCS_SPDIFLOCKED ? "on" : "off"); 67 snd_iprintf(buffer, "S/PDIF Locked : %s\n", rate & SRCS_SPDIFLOCKED ? "on" : "off");
66 snd_iprintf(buffer, "Rate Locked : %s\n", rate & SRCS_RATELOCKED ? "on" : "off"); 68 snd_iprintf(buffer, "Rate Locked : %s\n", rate & SRCS_RATELOCKED ? "on" : "off");
67 /* From ((Rate * 48000 ) / 262144); */ 69 /* From ((Rate * 48000 ) / 262144); */
@@ -244,6 +246,21 @@ static void snd_emu10k1_proc_spdif_read(snd_info_entry_t *entry,
244#endif 246#endif
245} 247}
246 248
249static void snd_emu10k1_proc_rates_read(snd_info_entry_t *entry,
250 snd_info_buffer_t * buffer)
251{
252 static int samplerate[8] = { 44100, 48000, 96000, 192000, 4, 5, 6, 7 };
253 emu10k1_t *emu = entry->private_data;
254 unsigned int val, tmp, n;
255 val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0);
256 tmp = (val >> 16) & 0x8;
257 for (n=0;n<4;n++) {
258 tmp = val >> (16 + (n*4));
259 if (tmp & 0x8) snd_iprintf(buffer, "Channel %d: Rate=%d\n", n, samplerate[tmp & 0x7]);
260 else snd_iprintf(buffer, "Channel %d: No input\n", n);
261 }
262}
263
247static void snd_emu10k1_proc_acode_read(snd_info_entry_t *entry, 264static void snd_emu10k1_proc_acode_read(snd_info_entry_t *entry,
248 snd_info_buffer_t * buffer) 265 snd_info_buffer_t * buffer)
249{ 266{
@@ -540,6 +557,10 @@ int __devinit snd_emu10k1_proc_init(emu10k1_t * emu)
540 if (! snd_card_proc_new(emu->card, "spdif-in", &entry)) 557 if (! snd_card_proc_new(emu->card, "spdif-in", &entry))
541 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_spdif_read); 558 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_spdif_read);
542 } 559 }
560 if (emu->card_capabilities->ca0151_chip) {
561 if (! snd_card_proc_new(emu->card, "capture-rates", &entry))
562 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_rates_read);
563 }
543 564
544 if (! snd_card_proc_new(emu->card, "voices", &entry)) 565 if (! snd_card_proc_new(emu->card, "voices", &entry))
545 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_voices_read); 566 snd_info_set_text_ops(entry, emu, 2048, snd_emu10k1_proc_voices_read);
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index dd6ce9927e10..8dd87838fb22 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -119,8 +119,8 @@ static snd_pcm_hardware_t snd_p16v_playback_hw = {
119 SNDRV_PCM_INFO_BLOCK_TRANSFER | 119 SNDRV_PCM_INFO_BLOCK_TRANSFER |
120 SNDRV_PCM_INFO_MMAP_VALID), 120 SNDRV_PCM_INFO_MMAP_VALID),
121 .formats = SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */ 121 .formats = SNDRV_PCM_FMTBIT_S32_LE, /* Only supports 24-bit samples padded to 32 bits. */
122 .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 , 122 .rates = SNDRV_PCM_RATE_192000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100,
123 .rate_min = 48000, 123 .rate_min = 44100,
124 .rate_max = 192000, 124 .rate_max = 192000,
125 .channels_min = 8, 125 .channels_min = 8,
126 .channels_max = 8, 126 .channels_max = 8,
@@ -324,19 +324,17 @@ static int snd_p16v_pcm_prepare_playback(snd_pcm_substream_t *substream)
324 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel); 324 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, channel);
325 switch (runtime->rate) { 325 switch (runtime->rate) {
326 case 44100: 326 case 44100:
327 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x8000); /* FIXME: This will change the capture rate as well! */ 327 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x8080);
328 break;
329 case 48000:
330 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x0000); /* FIXME: This will change the capture rate as well! */
331 break; 328 break;
332 case 96000: 329 case 96000:
333 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x4000); /* FIXME: This will change the capture rate as well! */ 330 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x4040);
334 break; 331 break;
335 case 192000: 332 case 192000:
336 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe000) | 0x2000); /* FIXME: This will change the capture rate as well! */ 333 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x2020);
337 break; 334 break;
335 case 48000:
338 default: 336 default:
339 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, 0x0000); /* FIXME: This will change the capture rate as well! */ 337 snd_emu10k1_ptr_write(emu, A_SPDIF_SAMPLERATE, channel, (tmp & ~0xe0e0) | 0x0000);
340 break; 338 break;
341 } 339 }
342 /* FIXME: Check emu->buffer.size before actually writing to it. */ 340 /* FIXME: Check emu->buffer.size before actually writing to it. */