Skip to contentSkip to conversation

cs46xx, independant rear PCM channel, IEC958 PCM channel

PATCH In review Benny Sjostrand 3 participants 4 messages Oct 29, 2002 – Oct 30, 2002

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 cs46xx, independant rear PCM channel, IEC958 PCM channel

Hi!

First, this stuff is still very experimental, it should work very well with a Game Theater XP course that's card I've got and the only cs46xx sound card I can test with.

I've got some reports that stuffs dont seems to work very well with the Santa Cruz card, course for some unknown reason the driver dont manage to raise GPIO 7 and 9 on the secondary codec that enables the rear output, you probably will see the message "cs46xx_setup_eapd_slot() Failure to write the GPIO pins for slot 12. " and that will probably freeze you computer for a while too.

In this patch, for the Santa Cruz the amplifier and the GPIO's are setup on init, then not touched anymore, like it's done for the Hercules XP card with hope and a little of luck maybe that works better.

Finally, this patch contains the following changes:
- Rear PCM channel
- IEC958 PCM channel, in hope that I'm close to get raw AC3 working soon
- Turn on Amplifier and setup EGPIO for Santa Cruz card on init
- Cleanup's in voyectra_setup_eapd_slot(...) (hope it's not broken ...)

PS. If you have time to help testing this patch, dont forget to turn on all debuging stuff, that always helps to find bugs ...

/Benny

cvs/alsa-kernel/include/cs46xx.h renamed from include/cs46xx.h +7 -75
diff --exclude=CVS -Naur alsa-kernel/include/cs46xx.h ../cvs/alsa-kernel/include/cs46xx.h
@@ -196,80 +196,6 @@
 #define BA1_OMNI_MEM                            0x000E0000
 
 
-
-
-/*
- * The following define the offsets of the AC97 shadow registers, which appear
- * as a virtual extension to the base address register zero memory range.
- */
-#define AC97_REG_OFFSET_MASK                    0x0000007EL
-#define AC97_CODEC_NUMBER_MASK                  0x00003000L
-
-#define BA0_AC97_RESET                          0x00001000L
-#define BA0_AC97_MASTER_VOLUME                  0x00001002L
-#define BA0_AC97_HEADPHONE_VOLUME               0x00001004L
-#define BA0_AC97_MASTER_VOLUME_MONO             0x00001006L
-#define BA0_AC97_MASTER_TONE                    0x00001008L
-#define BA0_AC97_PC_BEEP_VOLUME                 0x0000100AL
-#define BA0_AC97_PHONE_VOLUME                   0x0000100CL
-#define BA0_AC97_MIC_VOLUME                     0x0000100EL
-#define BA0_AC97_LINE_IN_VOLUME                 0x00001010L
-#define BA0_AC97_CD_VOLUME                      0x00001012L
-#define BA0_AC97_VIDEO_VOLUME                   0x00001014L
-#define BA0_AC97_AUX_VOLUME                     0x00001016L
-#define BA0_AC97_PCM_OUT_VOLUME                 0x00001018L
-#define BA0_AC97_RECORD_SELECT                  0x0000101AL
-#define BA0_AC97_RECORD_GAIN                    0x0000101CL
-#define BA0_AC97_RECORD_GAIN_MIC                0x0000101EL
-#define BA0_AC97_GENERAL_PURPOSE                0x00001020L
-#define BA0_AC97_3D_CONTROL                     0x00001022L
-#define BA0_AC97_MODEM_RATE                     0x00001024L
-#define BA0_AC97_POWERDOWN                      0x00001026L
-#define BA0_AC97_EXT_AUDIO_ID                   0x00001028L
-#define BA0_AC97_EXT_AUDIO_POWER                0x0000102AL
-#define BA0_AC97_PCM_FRONT_DAC_RATE             0x0000102CL
-#define BA0_AC97_PCM_SURR_DAC_RATE              0x0000102EL
-#define BA0_AC97_PCM_LFE_DAC_RATE               0x00001030L
-#define BA0_AC97_PCM_LR_ADC_RATE                0x00001032L
-#define BA0_AC97_MIC_ADC_RATE                   0x00001034L
-#define BA0_AC97_6CH_VOL_C_LFE                  0x00001036L
-#define BA0_AC97_6CH_VOL_SURROUND               0x00001038L
-#define BA0_AC97_RESERVED_3A                    0x0000103AL
-#define BA0_AC97_EXT_MODEM_ID                   0x0000103CL
-#define BA0_AC97_EXT_MODEM_POWER                0x0000103EL
-#define BA0_AC97_LINE1_CODEC_RATE               0x00001040L
-#define BA0_AC97_LINE2_CODEC_RATE               0x00001042L
-#define BA0_AC97_HANDSET_CODEC_RATE             0x00001044L
-#define BA0_AC97_LINE1_CODEC_LEVEL              0x00001046L
-#define BA0_AC97_LINE2_CODEC_LEVEL              0x00001048L
-#define BA0_AC97_HANDSET_CODEC_LEVEL            0x0000104AL
-#define BA0_AC97_GPIO_PIN_CONFIG                0x0000104CL
-#define BA0_AC97_GPIO_PIN_TYPE                  0x0000104EL
-#define BA0_AC97_GPIO_PIN_STICKY                0x00001050L
-#define BA0_AC97_GPIO_PIN_WAKEUP                0x00001052L
-#define BA0_AC97_GPIO_PIN_STATUS                0x00001054L
-#define BA0_AC97_MISC_MODEM_AFE_STAT            0x00001056L
-#define BA0_AC97_RESERVED_58                    0x00001058L
-#define BA0_AC97_CRYSTAL_REV_N_FAB_ID           0x0000105AL
-#define BA0_AC97_TEST_AND_MISC_CTRL             0x0000105CL
-#define BA0_AC97_AC_MODE                        0x0000105EL
-#define BA0_AC97_MISC_CRYSTAL_CONTROL           0x00001060L
-#define BA0_AC97_LINE1_HYPRID_CTRL              0x00001062L
-#define BA0_AC97_VENDOR_RESERVED_64             0x00001064L
-#define BA0_AC97_VENDOR_RESERVED_66             0x00001066L
-#define BA0_AC97_SPDIF_CONTROL                  0x00001068L
-#define BA0_AC97_VENDOR_RESERVED_6A             0x0000106AL
-#define BA0_AC97_VENDOR_RESERVED_6C             0x0000106CL
-#define BA0_AC97_VENDOR_RESERVED_6E             0x0000106EL
-#define BA0_AC97_VENDOR_RESERVED_70             0x00001070L
-#define BA0_AC97_VENDOR_RESERVED_72             0x00001072L
-#define BA0_AC97_VENDOR_RESERVED_74             0x00001074L
-#define BA0_AC97_CAL_ADDRESS                    0x00001076L
-#define BA0_AC97_CAL_DATA                       0x00001078L
-#define BA0_AC97_VENDOR_RESERVED_7A             0x0000107AL
-#define BA0_AC97_VENDOR_ID1                     0x0000107CL
-#define BA0_AC97_VENDOR_ID2                     0x0000107EL
-
 /*
  *  The following defines are for the flags in the host interrupt status
  *  register.
@@ -1790,6 +1716,7 @@
 	struct pci_dev *pci;
 	snd_card_t *card;
 	snd_pcm_t *pcm;
+
 	snd_rawmidi_t *rmidi;
 	snd_rawmidi_substream_t *midi_input;
 	snd_rawmidi_substream_t *midi_output;
@@ -1814,12 +1741,15 @@
 	struct pm_dev *pm_dev;
 #endif
 #ifdef CONFIG_SND_CS46XX_DEBUG_GPIO
-  int current_gpio;
+    int current_gpio;
 #endif
 #ifdef CONFIG_SND_CS46XX_NEW_DSP
 	struct semaphore spos_mutex;
 
 	dsp_spos_instance_t * dsp_spos_instance;
+
+	snd_pcm_t *pcm_rear;
+	snd_pcm_t *pcm_iec958;
 #else /* for compatibility */
 	cs46xx_pcm_t *playback_pcm;
 	unsigned int play_ctl;
@@ -1832,6 +1762,8 @@
 		      cs46xx_t **rcodec);
 
 int snd_cs46xx_pcm(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
+int snd_cs46xx_pcm_rear(cs46xx_t *chip, int device, snd_pcm_t **rpcm);
+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);
 void snd_cs46xx_gameport(cs46xx_t *chip);
cvs/alsa-kernel/include/cs46xx_dsp_spos.h renamed from include/cs46xx_dsp_spos.h +19 -1
diff --exclude=CVS -Naur alsa-kernel/include/cs46xx_dsp_spos.h ../cvs/alsa-kernel/include/cs46xx_dsp_spos.h
@@ -54,6 +54,12 @@
 #define DSP_MAX_PCM_CHANNELS 32
 #define DSP_MAX_SRC_NR       6
 
+#define DSP_PCM_MAIN_CHANNEL    1
+#define DSP_PCM_REAR_CHANNEL    2
+#define DSP_PCM_CENTER_CHANNEL  3
+#define DSP_PCM_LFE_CHANNEL     4
+#define DSP_IEC958_CHANNEL      5
+
 struct _dsp_module_desc_t;
 
 typedef struct _symbol_entry_t {
@@ -129,6 +135,8 @@
 	u32 unlinked;
 	dsp_scb_descriptor_t * pcm_reader_scb;
 	dsp_scb_descriptor_t * src_scb;
+	dsp_scb_descriptor_t * mixer_scb;
+    int pcm_channel_id;
 
 	void * private_data;
 } pcm_channel_descriptor_t;
@@ -141,8 +149,12 @@
 
 	segment_desc_t code;
 
-	/* PCM playback */
+	/* Main PCM playback mixer */
 	dsp_scb_descriptor_t * master_mix_scb;
+
+    /* Rear PCM playback mixer */
+    dsp_scb_descriptor_t * rear_mix_scb;
+
 	int npcm_channels;
 	int nsrc_scb;
 	pcm_channel_descriptor_t pcm_channels[DSP_MAX_PCM_CHANNELS];
@@ -190,6 +202,12 @@
 
 	/* reference snooper */
 	dsp_scb_descriptor_t * ref_snoop_scb;
+
+	/* SPDIF output  PCM reference  */
+	dsp_scb_descriptor_t * spdif_pcm_input_scb;
+
+    /* asynch TX task */
+    dsp_scb_descriptor_t * asynch_tx_scb;
 
 	/* record sources */
 	dsp_scb_descriptor_t * pcm_input;
cvs/alsa-kernel/pci/ac97/ac97_codec.c renamed from pci/ac97/ac97_codec.c +1 -1
diff --exclude=CVS -Naur alsa-kernel/pci/ac97/ac97_codec.c ../cvs/alsa-kernel/pci/ac97/ac97_codec.c
@@ -966,7 +966,7 @@
 		reg = AC97_CENTER_LFE_MASTER;
 		mask = 0x0080;
 		break;
-	case AC97_SURROUND_MASTER:
+	case AC97_SURROUND_MASTER:      
 		if ((ac97->ext_id & 0x80) == 0)
 			return 0;
 		break;
cvs/alsa-kernel/pci/cs46xx/cs46xx.c renamed from pci/cs46xx/cs46xx.c +9 -0
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/cs46xx.c ../cvs/alsa-kernel/pci/cs46xx/cs46xx.c
@@ -110,6 +110,14 @@
 		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;
+    }
 	if ((err = snd_cs46xx_mixer(chip)) < 0) {
 		snd_card_free(card);
 		return err;
@@ -132,6 +140,7 @@
 		snd_card_free(card);
 		return err;
 	}
+
 	pci_set_drvdata(pci, chip);
 	dev++;
 	return 0;
cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.c renamed from pci/cs46xx/cs46xx_lib.c +287 -18

477 lines not on this page · raw message

cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.h renamed from pci/cs46xx/cs46xx_lib.h +8 -1
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/cs46xx_lib.h ../cvs/alsa-kernel/pci/cs46xx/cs46xx_lib.h
@@ -51,6 +51,10 @@
 extern snd_pcm_ops_t snd_cs46xx_playback_indirect_ops;
 extern snd_pcm_ops_t snd_cs46xx_capture_ops;
 extern snd_pcm_ops_t snd_cs46xx_capture_indirect_ops;
+extern snd_pcm_ops_t snd_cs46xx_playback_rear_ops;
+extern snd_pcm_ops_t snd_cs46xx_playback_indirect_rear_ops;
+extern snd_pcm_ops_t snd_cs46xx_playback_iec958_ops;
+extern snd_pcm_ops_t snd_cs46xx_playback_indirect_iec958_ops;
 
 
 /*
@@ -185,7 +189,8 @@
                                                           dsp_scb_descriptor_t * snoop_scb,
                                                           dsp_scb_descriptor_t * parent_scb,
                                                           int scb_child_type);
-pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,u32 sample_rate, void * private_data, u32 hw_dma_addr);
+pcm_channel_descriptor_t * cs46xx_dsp_create_pcm_channel (cs46xx_t * chip,u32 sample_rate, void * private_data, u32 hw_dma_addr,
+                                                          int pcm_channel_id);
 void                       cs46xx_dsp_destroy_pcm_channel (cs46xx_t * chip,
                                                            pcm_channel_descriptor_t * pcm_channel);
 void                       cs46xx_dsp_set_src_sample_rate(cs46xx_t * chip,dsp_scb_descriptor_t * src, 
@@ -196,4 +201,6 @@
                                                      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);
 #endif /* __CS46XX_LIB_H__ */
cvs/alsa-kernel/pci/cs46xx/dsp_spos.c renamed from pci/cs46xx/dsp_spos.c +17 -4
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/dsp_spos.c ../cvs/alsa-kernel/pci/cs46xx/dsp_spos.c
@@ -1017,6 +1017,7 @@
 	dsp_scb_descriptor_t * codec_in_scb;
 	dsp_scb_descriptor_t * src_task_scb;
 	dsp_scb_descriptor_t * master_mix_scb;
+	dsp_scb_descriptor_t * rear_mix_scb;
 	dsp_scb_descriptor_t * record_mix_scb;
 	dsp_scb_descriptor_t * write_back_scb;
 	dsp_scb_descriptor_t * vari_decimate_scb;
@@ -1309,18 +1310,29 @@
 
 	/* create secondary CODEC output */
 	sec_codec_out_scb = cs46xx_dsp_create_codec_out_scb(chip,"CodecOutSCB_II",0x0010,0x0040,
-							    OUTPUTSNOOP_SCB_ADDR,
+							    REAR_MIXER_SCB_ADDR,
 							    SEC_CODECOUT_SCB_ADDR,codec_in_scb,
 							    SCB_ON_PARENT_NEXT_SCB);
 	if (!sec_codec_out_scb) goto _fail_end;
 
+
+	/* create the rear PCM channel  mixer SCB */
+	rear_mix_scb = cs46xx_dsp_create_mix_only_scb(chip,"RearMixerSCB",
+                                                  MIX_SAMPLE_BUF3,
+                                                  REAR_MIXER_SCB_ADDR,
+                                                  sec_codec_out_scb,
+                                                  SCB_ON_PARENT_SUBLIST_SCB);
+	ins->rear_mix_scb = rear_mix_scb;
+	if (!rear_mix_scb) goto _fail_end;
+
 	/* the magic snooper */
 	magic_snoop_scb = cs46xx_dsp_create_magic_snoop_scb (chip,"MagicSnoopSCB_I",OUTPUTSNOOP_SCB_ADDR,
 							     OUTPUT_SNOOP_BUFFER,
 							     codec_out_scb,
 							     sec_codec_out_scb,
-							     SCB_ON_PARENT_SUBLIST_SCB);
+							     SCB_ON_PARENT_NEXT_SCB);
 
+    
 	if (!magic_snoop_scb) goto _fail_end;
 	ins->ref_snoop_scb = magic_snoop_scb;
 
@@ -1329,10 +1341,11 @@
 	asynch_tx_scb = cs46xx_dsp_create_asynch_fg_tx_scb(chip,"AsynchFGTxSCB",ASYNCTX_SCB_ADDR,
 							   SPDIFO_SCB_INST,
 							   SPDIFO_IP_OUTPUT_BUFFER1,
-							   magic_snoop_scb,
+							   master_mix_scb,
 							   SCB_ON_PARENT_NEXT_SCB);
 
 	if (!asynch_tx_scb) goto _fail_end;
+    ins->asynch_tx_scb = asynch_tx_scb;
 
 	/* pcm input */
 	pcm_serial_input_task = cs46xx_dsp_create_pcm_serial_input_scb(chip,"PCMSerialInput_II",
@@ -1341,13 +1354,13 @@
 								       SCB_ON_PARENT_SUBLIST_SCB);
   
 	if (!pcm_serial_input_task) goto _fail_end;
+    ins->spdif_pcm_input_scb = pcm_serial_input_task; 
 
 	/* SP IO access */
 	if (!cs46xx_dsp_create_spio_write_scb(chip,"SPIOWriteSCB",SPIOWRITE_SCB_ADDR,
 					      asynch_tx_scb,
 					      SCB_ON_PARENT_NEXT_SCB))
 		goto _fail_end;
-
 
 	/* SPDIF input sampel rate converter */
 	src_task_scb = cs46xx_dsp_create_src_task_scb(chip,"SrcTaskSCB_SPDIFI",
cvs/alsa-kernel/pci/cs46xx/dsp_spos.h renamed from pci/cs46xx/dsp_spos.h +5 -1
diff --exclude=CVS -Naur alsa-kernel/pci/cs46xx/dsp_spos.h ../cvs/alsa-kernel/pci/cs46xx/dsp_spos.h
@@ -73,7 +73,9 @@
 #define SPDIFI_IP_OUTPUT_BUFFER1 0x0E00
 #define SPDIFO_IP_OUTPUT_BUFFER1 0x1000
 #define MIX_SAMPLE_BUF1          0x1400
-#define MIX_SAMPLE_BUF2          0x3000
+#define MIX_SAMPLE_BUF2          0x2D00
+#define MIX_SAMPLE_BUF3          0x2E00
+#define MIX_SAMPLE_BUF4          0x2F00
 
 /* Task stack address */
 #define HFG_STACK                0x066A
@@ -104,6 +106,8 @@
 #define OUTPUTSNOOPII_SCB_ADDR   0x150
 #define PCMSERIALIN_PCM_SCB_ADDR 0x160
 #define RECORD_MIXER_SCB_ADDR    0x170
+#define REAR_MIXER_SCB_ADDR      0x180
+#define SPDIF_MIXER_SCB_ADDR     0x190
 
 /* hyperforground SCB's*/
 #define HFG_TREE_SCB             0xBA0
cvs/alsa-kernel/pci/cs46xx/dsp_spos_scb_lib.c renamed from pci/cs46xx/dsp_spos_scb_lib.c +72 -7

122 lines not on this page · raw message

#1 lore raw
Quoted 7 lines · On 2002.10.28 23:55 Benny Sjostrand wrote:

I've got some reports that stuffs dont seems to work very well with the Santa Cruz card, course for some unknown reason the driver dont manage to raise GPIO 7 and 9 on the secondary codec that enables the rear output, you probably will see the message "cs46xx_setup_eapd_slot() Failure to write the GPIO pins for slot 12. " and that will probably freeze you computer for a while too.

I should clarify that the freezing only happened while I was
testing the driver by removing the GPIO write-complete check. This caused the function to be called multiple times in a row, which was what caused the temporary freeze. I've had no problems with freezing
with the current driver. (So don't let that statement scare you.) ;-)

-- Peter Heatwole
"Murphy was just a well known pessimist."

-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

#2 lore raw
In reply to Benny Sjostrand

Hi Benny,

the changes look ok, but i'd like to ask your favor before applying this patch.

could you move the SCB initialization part in cs46xx_playback_prepare() into hw_params callback?
i found that the mutex is not allowed in prepare callback since it's protected by spinlock (at the very entry of prepare action). this caused oops on 2.5.x kernels, as you might have seen a report on alsa-devel ML.

please note that hw_params callback may be called also not only once, so you'll need to check whether the SCB was already initialized, and release the old allocation before re-initializing.

also, it would be appreciated if you fix the whitespaces :)

ciao,

Takashi

-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf

#3 lore raw
Quoted 4 lines

also, it would be appreciated if you fix the whitespaces :)

I just let emacs do the indenting job, <tab> <tab> <tab> ... so maybe someone like to sendme a .emacs file with the apropiate settings -;)

/Benny

-------------------------------------------------------
This sf.net email is sponsored by: Influence the future of Java(TM) technology. Join the Java Community Process(SM) (JCP(SM)) program now. http://ads.sourceforge.net/cgi-bin/redirect.pl?sunm0004en