Skip to contentSkip to conversation

cs46xx: variable period size support, Santa Cruz rear output fixes

PATCH In review Benny Sjostrand 2 participants 3 messages Nov 3, 2002 – Nov 4, 2002

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 cs46xx: variable period size support, Santa Cruz rear output fixes

Hi!

A new bunch of changes on cs46xx driver. This patch should fix the problems with the Santa Cruz rear output, and the DSP hang (8 khz tone) related to the SPDIF output.

New is that now the cs46xx driver supports variable period byte sizes on playback and capture, supported period sizes are 32, 64, 128, 256, 512, 1024 ,2048.

I've tested play around with alsaplayer, arecord, things seems to work as expected. But jackd got a inifinite amount of xruns,
and wont start with 1024 and 2048 period sizes with
"ALSA lib pcm_mmap.c:350:(snd_pcm_mmap) mmap failed: Invalid argument" error message. I hope some of you can find a explication to that. About the xruns I dont known if it's just that my Dual PIII is not fast enough to serve jack ...

About the AC3 stuff, I've been doing some experiments with xine trying to pass AC3 through the IEC958 port with no success yet. My receiver dont wont to interpret it as other thing that PCM, wich just results in a lot of unpleasant noise. Something is left to setup in the DSP SPDIF controller, I dont known exaclty what. You are welcome to experiment with this.

Summary of changes:
- DSP is started after initializing AC97 codecs, to fix the Santa Cruz problem.
- Rewrite SPDIF output stuff, to prevent the DSP hang and make it possible to live together with the IEC958 PCM channel.
- Variable period size support on playback and capture
- some minor procfs bug fixes
- code cleanup.

/Benny

PS. I've fixed my emacs settings, this patch should not contain any blank space -:)

cvs/alsa-kernel/include/cs46xx.h renamed from include/cs46xx.h +1 -0
diff --exclude=CVS -Naur alsa-kernel/include/cs46xx.h ../cvs/alsa-kernel/include/cs46xx.h
@@ -1766,6 +1766,7 @@
 int snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
 int snd_cs46xx_mixer(cs46xx_t *chip);
 int snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rmidi);
+int snd_cs46xx_start_dsp(cs46xx_t *chip);
 void snd_cs46xx_gameport(cs46xx_t *chip);
 
 #ifdef CONFIG_PM
cvs/alsa-kernel/include/cs46xx_dsp_spos.h renamed from include/cs46xx_dsp_spos.h +11 -7
diff --exclude=CVS -Naur alsa-kernel/include/cs46xx_dsp_spos.h ../cvs/alsa-kernel/include/cs46xx_dsp_spos.h
@@ -36,20 +36,20 @@
 #define SEGTYPE_SP_COEFFICIENT          0x00000004
 
 #define DSP_SPOS_UU      0x0deadul     /* unused */
-#define DSP_SPOS_DC      0x0badul     /* dont care */
-#define DSP_SPOS_DC_DC   0x0bad0badul     /* dont care */
+#define DSP_SPOS_DC      0x0badul      /* dont care */
+#define DSP_SPOS_DC_DC   0x0bad0badul  /* dont care */
 #define DSP_SPOS_UUUU    0xdeadc0edul  /* unused */
 #define DSP_SPOS_UUHI    0xdeadul
 #define DSP_SPOS_UULO    0xc0edul
-#define DSP_SPOS_DCDC    0x0badf1d0ul /* dont care */
+#define DSP_SPOS_DCDC    0x0badf1d0ul  /* dont care */
 #define DSP_SPOS_DCDCHI  0x0badul
 #define DSP_SPOS_DCDCLO  0xf1d0ul
 
-#define DSP_MAX_TASK_NAME 60
+#define DSP_MAX_TASK_NAME   60
 #define DSP_MAX_SYMBOL_NAME 100
-#define DSP_MAX_SCB_NAME  60
-#define DSP_MAX_SCB_DESC  200
-#define DSP_MAX_TASK_DESC 50
+#define DSP_MAX_SCB_NAME    60
+#define DSP_MAX_SCB_DESC    200
+#define DSP_MAX_TASK_DESC   50
 
 #define DSP_MAX_PCM_CHANNELS 32
 #define DSP_MAX_SRC_NR       6
@@ -59,6 +59,10 @@
 #define DSP_PCM_CENTER_CHANNEL  3
 #define DSP_PCM_LFE_CHANNEL     4
 #define DSP_IEC958_CHANNEL      5
+
+#define DSP_SDPIF_STATUS_OUTPUT_ENABLED 1
+#define DSP_SDPIF_STATUS_PLAYBACK_OPEN  2
+#define DSP_SDPIF_STATUS_HW_ENABLED     4
 
 struct _dsp_module_desc_t;
 
cvs/alsa-kernel/pci/cs46xx/cs46xx.c renamed from pci/cs46xx/cs46xx.c +16 -8
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/cs46xx.c ../cvs/alsa-kernel/pci/cs46xx/cs46xx.c
@@ -110,14 +110,16 @@
 		snd_card_free(card);
 		return err;
 	}
-    if ((err = snd_cs46xx_pcm_rear(chip,1, NULL)) < 0) {
-        snd_card_free(card);
-        return err;
-    }
-    if ((err = snd_cs46xx_pcm_iec958(chip,2,NULL)) < 0) {
-        snd_card_free(card);
-        return err;
-    }
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+	if ((err = snd_cs46xx_pcm_rear(chip,1, NULL)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	if ((err = snd_cs46xx_pcm_iec958(chip,2,NULL)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+#endif
 	if ((err = snd_cs46xx_mixer(chip)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -126,6 +128,12 @@
 		snd_card_free(card);
 		return err;
 	}
+	if ((err = snd_cs46xx_start_dsp(chip)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+
 	snd_cs46xx_gameport(chip);
 
 	strcpy(card->driver, "CS46xx");
cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.c renamed from pci/cs46xx/cs46xx_lib.c +115 -54

450 lines not on this page · raw message

cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.h renamed from pci/cs46xx/cs46xx_lib.h +20 -6
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/cs46xx_lib.h ../cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.h
@@ -35,9 +35,17 @@
 #define CS46XX_BA1_REG_SIZE	  0x0100
 
 
-#define CS46XX_PERIOD_SIZE 2048
+
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+#define CS46XX_MIN_PERIOD_SIZE 1
+#define CS46XX_MAX_PERIOD_SIZE 1024*1024
+#else
+#define CS46XX_MIN_PERIOD_SIZE 2048
+#define CS46XX_MAX_PERIOD_SIZE 2048
+#endif
+
 #define CS46XX_FRAGS 2
-#define CS46XX_BUFFER_SIZE CS46XX_PERIOD_SIZE * CS46XX_FRAGS
+/* #define CS46XX_BUFFER_SIZE CS46XX_MAX_PERIOD_SIZE * CS46XX_FRAGS */
 
 #define SCB_NO_PARENT             0
 #define SCB_ON_PARENT_NEXT_SCB    1
@@ -100,6 +108,7 @@
                                             unsigned long len);
 int                    snd_cs46xx_clear_BA1(cs46xx_t *chip,unsigned long offset,unsigned long len);
 int                    cs46xx_dsp_enable_spdif_out (cs46xx_t *chip);
+int                    cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip);
 int                    cs46xx_dsp_disable_spdif_out (cs46xx_t *chip);
 int                    cs46xx_dsp_enable_spdif_in (cs46xx_t *chip);
 int                    cs46xx_dsp_disable_spdif_in (cs46xx_t *chip);
@@ -199,8 +208,13 @@
 int                        cs46xx_dsp_pcm_link (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel);
 dsp_scb_descriptor_t *     cs46xx_add_record_source (cs46xx_t *chip,dsp_scb_descriptor_t * source,
                                                      u16 addr,char * scb_name);
-int                         cs46xx_src_unlink(cs46xx_t *chip,dsp_scb_descriptor_t * src);
-int                         cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t * src);
-int                         cs46xx_iec958_pre_open (cs46xx_t *chip);
-int                         cs46xx_iec958_post_close (cs46xx_t *chip);
+int                        cs46xx_src_unlink(cs46xx_t *chip,dsp_scb_descriptor_t * src);
+int                        cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t * src);
+int                        cs46xx_iec958_pre_open (cs46xx_t *chip);
+int                        cs46xx_iec958_post_close (cs46xx_t *chip);
+int                        cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
+							       pcm_channel_descriptor_t * pcm_channel,
+							       int period_size);
+int                        cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
+							      int period_size);
 #endif /* __CS46XX_LIB_H__ */
cvs/alsa-kernel/pci/cs46xx/dsp_spos.c renamed from pci/cs46xx/dsp_spos.c +18 -51

128 lines not on this page · raw message

cvs/alsa-kernel/pci/cs46xx/dsp_spos.h renamed from pci/cs46xx/dsp_spos.h +9 -0
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/dsp_spos.h ../cvs/alsa-kernel/pci/cs46xx/dsp_spos.h
@@ -183,5 +183,14 @@
 #define SP_SPDOUT_CONTROL 0x804D
 #define SP_SPDOUT_CSUV    0x808E
 
+static inline void cs46xx_dsp_spos_update_scb (cs46xx_t * chip,dsp_scb_descriptor_t * scb) 
+{
+	/* update nextSCB and subListPtr in SCB */
+	snd_cs46xx_poke(chip,
+			(scb->address + SCBsubListPtr) << 2,
+			(scb->sub_list_ptr->address << 0x10) |
+			(scb->next_scb_ptr->address));	
+}
+
 #endif /* __DSP_SPOS_H__ */
 #endif /* CONFIG_SND_CS46XX_NEW_DSP  */
cvs/alsa-kernel/pci/cs46xx/dsp_spos_scb_lib.c renamed from pci/cs46xx/dsp_spos_scb_lib.c +200 -45

304 lines not on this page · raw message

#1 lore raw

Just forget about the last patch, I've discovered a serious bug in the variable period size implementation. Everything got an explication, well and
now jackd behaves correctly, no more infinite amount of xruns.

I hope that should work OK now ...

/Benny

cvs/alsa-kernel/include/cs46xx.h renamed from include/cs46xx.h +1 -0
diff --exclude=CVS -Naur alsa-kernel/include/cs46xx.h ../cvs/alsa-kernel/include/cs46xx.h
@@ -1766,6 +1766,7 @@
 int snd_cs46xx_pcm_iec958(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
 int snd_cs46xx_mixer(cs46xx_t *chip);
 int snd_cs46xx_midi(cs46xx_t *chip, int device, snd_rawmidi_t **rmidi);
+int snd_cs46xx_start_dsp(cs46xx_t *chip);
 void snd_cs46xx_gameport(cs46xx_t *chip);
 
 #ifdef CONFIG_PM
cvs/alsa-kernel/include/cs46xx_dsp_spos.h renamed from include/cs46xx_dsp_spos.h +11 -7
diff --exclude=CVS -Naur alsa-kernel/include/cs46xx_dsp_spos.h ../cvs/alsa-kernel/include/cs46xx_dsp_spos.h
@@ -36,20 +36,20 @@
 #define SEGTYPE_SP_COEFFICIENT          0x00000004
 
 #define DSP_SPOS_UU      0x0deadul     /* unused */
-#define DSP_SPOS_DC      0x0badul     /* dont care */
-#define DSP_SPOS_DC_DC   0x0bad0badul     /* dont care */
+#define DSP_SPOS_DC      0x0badul      /* dont care */
+#define DSP_SPOS_DC_DC   0x0bad0badul  /* dont care */
 #define DSP_SPOS_UUUU    0xdeadc0edul  /* unused */
 #define DSP_SPOS_UUHI    0xdeadul
 #define DSP_SPOS_UULO    0xc0edul
-#define DSP_SPOS_DCDC    0x0badf1d0ul /* dont care */
+#define DSP_SPOS_DCDC    0x0badf1d0ul  /* dont care */
 #define DSP_SPOS_DCDCHI  0x0badul
 #define DSP_SPOS_DCDCLO  0xf1d0ul
 
-#define DSP_MAX_TASK_NAME 60
+#define DSP_MAX_TASK_NAME   60
 #define DSP_MAX_SYMBOL_NAME 100
-#define DSP_MAX_SCB_NAME  60
-#define DSP_MAX_SCB_DESC  200
-#define DSP_MAX_TASK_DESC 50
+#define DSP_MAX_SCB_NAME    60
+#define DSP_MAX_SCB_DESC    200
+#define DSP_MAX_TASK_DESC   50
 
 #define DSP_MAX_PCM_CHANNELS 32
 #define DSP_MAX_SRC_NR       6
@@ -59,6 +59,10 @@
 #define DSP_PCM_CENTER_CHANNEL  3
 #define DSP_PCM_LFE_CHANNEL     4
 #define DSP_IEC958_CHANNEL      5
+
+#define DSP_SDPIF_STATUS_OUTPUT_ENABLED 1
+#define DSP_SDPIF_STATUS_PLAYBACK_OPEN  2
+#define DSP_SDPIF_STATUS_HW_ENABLED     4
 
 struct _dsp_module_desc_t;
 
cvs/alsa-kernel/pci/cs46xx/cs46xx.c renamed from pci/cs46xx/cs46xx.c +16 -8
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/cs46xx.c ../cvs/alsa-kernel/pci/cs46xx/cs46xx.c
@@ -110,14 +110,16 @@
 		snd_card_free(card);
 		return err;
 	}
-    if ((err = snd_cs46xx_pcm_rear(chip,1, NULL)) < 0) {
-        snd_card_free(card);
-        return err;
-    }
-    if ((err = snd_cs46xx_pcm_iec958(chip,2,NULL)) < 0) {
-        snd_card_free(card);
-        return err;
-    }
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+	if ((err = snd_cs46xx_pcm_rear(chip,1, NULL)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+	if ((err = snd_cs46xx_pcm_iec958(chip,2,NULL)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+#endif
 	if ((err = snd_cs46xx_mixer(chip)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -126,6 +128,12 @@
 		snd_card_free(card);
 		return err;
 	}
+	if ((err = snd_cs46xx_start_dsp(chip)) < 0) {
+		snd_card_free(card);
+		return err;
+	}
+
+
 	snd_cs46xx_gameport(chip);
 
 	strcpy(card->driver, "CS46xx");
cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.c renamed from pci/cs46xx/cs46xx_lib.c +117 -54

452 lines not on this page · raw message

cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.h renamed from pci/cs46xx/cs46xx_lib.h +20 -6
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/cs46xx_lib.h ../cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.h
@@ -35,9 +35,17 @@
 #define CS46XX_BA1_REG_SIZE	  0x0100
 
 
-#define CS46XX_PERIOD_SIZE 2048
+
+#ifdef CONFIG_SND_CS46XX_NEW_DSP
+#define CS46XX_MIN_PERIOD_SIZE 1
+#define CS46XX_MAX_PERIOD_SIZE 1024*1024
+#else
+#define CS46XX_MIN_PERIOD_SIZE 2048
+#define CS46XX_MAX_PERIOD_SIZE 2048
+#endif
+
 #define CS46XX_FRAGS 2
-#define CS46XX_BUFFER_SIZE CS46XX_PERIOD_SIZE * CS46XX_FRAGS
+/* #define CS46XX_BUFFER_SIZE CS46XX_MAX_PERIOD_SIZE * CS46XX_FRAGS */
 
 #define SCB_NO_PARENT             0
 #define SCB_ON_PARENT_NEXT_SCB    1
@@ -100,6 +108,7 @@
                                             unsigned long len);
 int                    snd_cs46xx_clear_BA1(cs46xx_t *chip,unsigned long offset,unsigned long len);
 int                    cs46xx_dsp_enable_spdif_out (cs46xx_t *chip);
+int                    cs46xx_dsp_enable_spdif_hw (cs46xx_t *chip);
 int                    cs46xx_dsp_disable_spdif_out (cs46xx_t *chip);
 int                    cs46xx_dsp_enable_spdif_in (cs46xx_t *chip);
 int                    cs46xx_dsp_disable_spdif_in (cs46xx_t *chip);
@@ -199,8 +208,13 @@
 int                        cs46xx_dsp_pcm_link (cs46xx_t * chip,pcm_channel_descriptor_t * pcm_channel);
 dsp_scb_descriptor_t *     cs46xx_add_record_source (cs46xx_t *chip,dsp_scb_descriptor_t * source,
                                                      u16 addr,char * scb_name);
-int                         cs46xx_src_unlink(cs46xx_t *chip,dsp_scb_descriptor_t * src);
-int                         cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t * src);
-int                         cs46xx_iec958_pre_open (cs46xx_t *chip);
-int                         cs46xx_iec958_post_close (cs46xx_t *chip);
+int                        cs46xx_src_unlink(cs46xx_t *chip,dsp_scb_descriptor_t * src);
+int                        cs46xx_src_link(cs46xx_t *chip,dsp_scb_descriptor_t * src);
+int                        cs46xx_iec958_pre_open (cs46xx_t *chip);
+int                        cs46xx_iec958_post_close (cs46xx_t *chip);
+int                        cs46xx_dsp_pcm_channel_set_period (cs46xx_t * chip,
+							       pcm_channel_descriptor_t * pcm_channel,
+							       int period_size);
+int                        cs46xx_dsp_pcm_ostream_set_period (cs46xx_t * chip,
+							      int period_size);
 #endif /* __CS46XX_LIB_H__ */
cvs/alsa-kernel/pci/cs46xx/dsp_spos.c renamed from pci/cs46xx/dsp_spos.c +18 -51

128 lines not on this page · raw message

cvs/alsa-kernel/pci/cs46xx/dsp_spos.h renamed from pci/cs46xx/dsp_spos.h +9 -0
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/dsp_spos.h ../cvs/alsa-kernel/pci/cs46xx/dsp_spos.h
@@ -183,5 +183,14 @@
 #define SP_SPDOUT_CONTROL 0x804D
 #define SP_SPDOUT_CSUV    0x808E
 
+static inline void cs46xx_dsp_spos_update_scb (cs46xx_t * chip,dsp_scb_descriptor_t * scb) 
+{
+	/* update nextSCB and subListPtr in SCB */
+	snd_cs46xx_poke(chip,
+			(scb->address + SCBsubListPtr) << 2,
+			(scb->sub_list_ptr->address << 0x10) |
+			(scb->next_scb_ptr->address));	
+}
+
 #endif /* __DSP_SPOS_H__ */
 #endif /* CONFIG_SND_CS46XX_NEW_DSP  */
cvs/alsa-kernel/pci/cs46xx/dsp_spos_scb_lib.c renamed from pci/cs46xx/dsp_spos_scb_lib.c +200 -45

304 lines not on this page · raw message

#2 lore raw

At Mon, 04 Nov 2002 02:13:33 +0100,

Quoted 8 lines · Benny Sjostrand

[1 <text/plain; us-ascii (7bit)>]
Just forget about the last patch, I've discovered a serious bug in the variable period
size implementation. Everything got an explication, well and now jackd behaves correctly, no more infinite amount of xruns.

I hope that should work OK now ...

thanks, now on cvs.
could you check whether i forgot the commission of some files again? :)

Takashi

-------------------------------------------------------
This SF.net email is sponsored by: ApacheCon, November 18-21 in Las Vegas (supported by COMDEX), the only Apache event to be fully supported by the ASF. http://www.apachecon.com