Alsa-Devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Requested: CMI8330 testers?
@ 2002-12-16 15:15 Takashi Iwai
  2002-12-27  9:19 ` Bernard Urban
  0 siblings, 1 reply; 12+ messages in thread
From: Takashi Iwai @ 2002-12-16 15:15 UTC (permalink / raw)
  To: alsa-devel; +Cc: alsa-user

[-- Attachment #1: Type: text/plain, Size: 396 bytes --]

Hi,

can anyone who owns the CMI8330 ISA test the attached patch?
the patch will change the pcm interface of this soundchip as a more
reasonable way.  the playback and capture are combined into one pcm.
it's for the latest cvs version.  not sure whether it's applicable to
rc6.

please check whether the full-duplex works.  it's enough to run aplay
and arecord simultaneously.


thanks,

Takashi

[-- Attachment #2: cmi8330-pcm-fix.dif --]
[-- Type: application/octet-stream, Size: 11118 bytes --]

Index: alsa-kernel/core/pcm.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/core/pcm.c,v
retrieving revision 1.20
diff -u -r1.20 pcm.c
--- alsa-kernel/core/pcm.c	4 Dec 2002 09:37:21 -0000	1.20
+++ alsa-kernel/core/pcm.c	16 Dec 2002 14:04:21 -0000
@@ -774,6 +774,7 @@
 	runtime->status->state = SNDRV_PCM_STATE_OPEN;
 
 	substream->runtime = runtime;
+	substream->private_data = pcm->private_data;
 	pstr->substream_opened++;
 	*rsubstream = substream;
 	return 0;
Index: alsa-kernel/include/ad1848.h
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/include/ad1848.h,v
retrieving revision 1.4
diff -u -r1.4 ad1848.h
--- alsa-kernel/include/ad1848.h	13 Aug 2002 16:17:06 -0000	1.4
+++ alsa-kernel/include/ad1848.h	16 Dec 2002 14:35:52 -0000
@@ -162,6 +162,7 @@
 		      ad1848_t ** chip);
 
 int snd_ad1848_pcm(ad1848_t * chip, int device, snd_pcm_t **rpcm);
+const snd_pcm_ops_t *snd_ad1848_get_pcm_ops(int direction);
 int snd_ad1848_mixer(ad1848_t * chip);
 void snd_ad1848_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
Index: alsa-kernel/include/pcm.h
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/include/pcm.h,v
retrieving revision 1.21
diff -u -r1.21 pcm.h
--- alsa-kernel/include/pcm.h	2 Dec 2002 09:25:18 -0000	1.21
+++ alsa-kernel/include/pcm.h	16 Dec 2002 14:03:06 -0000
@@ -50,7 +50,7 @@
 typedef struct sndrv_pcm_mmap_control snd_pcm_mmap_control_t;
 typedef struct sndrv_mask snd_mask_t;
 
-#define _snd_pcm_substream_chip(substream) ((substream)->pcm->private_data)
+#define _snd_pcm_substream_chip(substream) ((substream)->private_data)
 #define snd_pcm_substream_chip(substream) snd_magic_cast1(chip_t, _snd_pcm_substream_chip(substream), return -ENXIO)
 #define _snd_pcm_chip(pcm) ((pcm)->private_data)
 #define snd_pcm_chip(pcm) snd_magic_cast1(chip_t, _snd_pcm_chip(pcm), return -ENXIO)
@@ -363,6 +363,7 @@
 struct _snd_pcm_substream {
 	snd_pcm_t *pcm;
 	snd_pcm_str_t *pstr;
+	void *private_data;		/* copied from pcm->private_data */
 	int number;
 	char name[32];			/* substream name */
 	int stream;			/* stream (direction) */
Index: alsa-kernel/include/sb.h
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/include/sb.h,v
retrieving revision 1.7
diff -u -r1.7 sb.h
--- alsa-kernel/include/sb.h	9 Dec 2002 10:52:24 -0000	1.7
+++ alsa-kernel/include/sb.h	16 Dec 2002 14:36:01 -0000
@@ -305,6 +305,7 @@
 
 /* sb16_init.c */
 int snd_sb16dsp_pcm(sb_t *chip, int device, snd_pcm_t ** rpcm);
+const snd_pcm_ops_t *snd_sb16dsp_get_pcm_ops(int direction);
 int snd_sb16dsp_configure(sb_t *chip);
 /* sb16.c */
 void snd_sb16dsp_interrupt(int irq, void *dev_id, struct pt_regs *regs);
Index: alsa-kernel/isa/cmi8330.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/isa/cmi8330.c,v
retrieving revision 1.10
diff -u -r1.10 cmi8330.c
--- alsa-kernel/isa/cmi8330.c	22 Oct 2002 09:37:24 -0000	1.10
+++ alsa-kernel/isa/cmi8330.c	16 Dec 2002 15:01:19 -0000
@@ -147,6 +147,15 @@
 	struct isapnp_dev *cap;
 	struct isapnp_dev *play;
 #endif
+	snd_card_t *card;
+	ad1848_t *wss;
+	sb_t *sb;
+
+	snd_pcm_t *pcm;
+	snd_pcm_ops_t playback_ops;
+	int (*playback_open)(snd_pcm_substream_t *);
+	snd_pcm_ops_t capture_ops;
+	int (*capture_open)(snd_pcm_substream_t *);
 };
 
 static snd_card_t *snd_cmi8330_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
@@ -294,6 +303,79 @@
 }
 #endif
 
+/*
+ * PCM interface
+ *
+ * since we call the different chip interfaces for playback and capture
+ * directions, we need a trick.
+ *
+ * - copy the ops for each direction into a local record.
+ * - replace the open callback with the new one, which replaces the
+ *   substream->private_data with the corresponding chip instance
+ *   and calls again the original open callback of the chip.
+ *
+ */
+
+static int snd_cmi8330_playback_open(snd_pcm_substream_t * substream)
+{
+	struct snd_cmi8330 *chip = (struct snd_cmi8330 *)_snd_pcm_substream_chip(substream);
+
+	/* replace the private_data and call the original open callback */
+	substream->private_data = chip->sb;
+	return chip->playback_open(substream);
+}
+
+static int snd_cmi8330_capture_open(snd_pcm_substream_t * substream)
+{
+	struct snd_cmi8330 *chip = (struct snd_cmi8330 *)_snd_pcm_substream_chip(substream);
+
+	/* replace the private_data and call the original open callback */
+	substream->private_data = chip->wss;
+	return chip->capture_open(substream);
+}
+
+static void snd_cmi8330_pcm_free(snd_pcm_t *pcm)
+{
+	snd_pcm_lib_preallocate_free_for_all(pcm);
+}
+
+static int __init snd_cmi8330_pcm(snd_card_t *card, struct snd_cmi8330 *chip)
+{
+	snd_pcm_t *pcm;
+	const snd_pcm_ops_t *ops;
+	int err;
+	
+	if ((err = snd_pcm_new(card, "CMI8330", 0, 1, 1, &pcm)) < 0)
+		return err;
+	strcpy(pcm->name, "CMI8330");
+	pcm->private_data = chip;
+	pcm->private_free = snd_cmi8330_pcm_free;
+	
+	/* playback - SB16 */
+	ops = snd_sb16dsp_get_pcm_ops(SNDRV_PCM_STREAM_PLAYBACK);
+	chip->playback_ops = *ops;
+	chip->playback_open = ops->open;
+	chip->playback_ops.open = snd_cmi8330_playback_open;
+
+	/* capture - AD1848 */
+	ops = snd_ad1848_get_pcm_ops(SNDRV_PCM_STREAM_CAPTURE);
+	chip->capture_ops = *ops;
+	chip->capture_open = ops->open;
+	chip->capture_ops.open = snd_cmi8330_capture_open;
+
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &chip->playback_ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &chip->capture_ops);
+
+	snd_pcm_lib_preallocate_isa_pages_for_all(pcm, 64*1024, 128*1024);
+	chip->pcm = pcm;
+
+	return 0;
+}
+
+
+/*
+ */
+
 static void snd_cmi8330_free(snd_card_t *card)
 {
 	struct snd_cmi8330 *acard = (struct snd_cmi8330 *)card->private_data;
@@ -309,12 +391,8 @@
 {
 	snd_card_t *card;
 	struct snd_cmi8330 *acard;
-	ad1848_t *chip_wss;
-	sb_t *chip_sb;
 	unsigned long flags;
 	int i, err;
-	snd_pcm_t *pcm, *wss_pcm, *sb_pcm;
-	snd_pcm_str_t *pstr;
 
 #ifdef __ISAPNP__
 	if (!isapnp[dev]) {
@@ -337,6 +415,7 @@
 		return -ENOMEM;
 	}
 	acard = (struct snd_cmi8330 *)card->private_data;
+	acard->card = card;
 	card->private_free = snd_cmi8330_free;
 
 #ifdef __ISAPNP__
@@ -352,83 +431,60 @@
 				     wssirq[dev],
 				     wssdma[dev],
 				     AD1848_HW_DETECT,
-				     &chip_wss)) < 0) {
+				     &acard->wss)) < 0) {
 		snd_printk("(AD1848) device busy??\n");
 		snd_card_free(card);
 		return err;
 	}
-	if (chip_wss->hardware != AD1848_HW_CMI8330) {
+	if (acard->wss->hardware != AD1848_HW_CMI8330) {
 		snd_printk("(AD1848) not found during probe\n");
 		snd_card_free(card);
 		return -ENODEV;
 	}
-	if ((err = snd_ad1848_pcm(chip_wss, 0, &wss_pcm)) < 0) {
-		snd_printk("(AD1848) no enough memory??\n");
-		snd_card_free(card);
-		return err;
-	}
 
 	if ((err = snd_sbdsp_create(card, sbport[dev],
 				    sbirq[dev],
 				    snd_sb16dsp_interrupt,
 				    sbdma8[dev],
 				    sbdma16[dev],
-				    SB_HW_AUTO, &chip_sb)) < 0) {
+				    SB_HW_AUTO, &acard->sb)) < 0) {
 		snd_printk("(SB16) device busy??\n");
 		snd_card_free(card);
 		return err;
 	}
-	if ((err = snd_sb16dsp_pcm(chip_sb, 1, &sb_pcm)) < 0) {
-		snd_printk("(SB16) no enough memory??\n");
-		snd_card_free(card);
-		return err;
-	}
-
-	if (chip_sb->hardware != SB_HW_16) {
+	if (acard->sb->hardware != SB_HW_16) {
 		snd_printk("(SB16) not found during probe\n");
 		snd_card_free(card);
 		return -ENODEV;
 	}
+	memcpy(&acard->wss->image[16], &snd_cmi8330_image, sizeof(snd_cmi8330_image));
 
-	memcpy(&chip_wss->image[16], &snd_cmi8330_image, sizeof(snd_cmi8330_image));
+	spin_lock_irqsave(&acard->wss->reg_lock, flags);
+	snd_ad1848_out(acard->wss, AD1848_MISC_INFO,	/* switch on MODE2 */
+		       acard->wss->image[AD1848_MISC_INFO] |= 0x40);
+	spin_unlock_irqrestore(&acard->wss->reg_lock, flags);
 
-	spin_lock_irqsave(&chip_wss->reg_lock, flags);
-	snd_ad1848_out(chip_wss, AD1848_MISC_INFO,	/* switch on MODE2 */
-		       chip_wss->image[AD1848_MISC_INFO] |= 0x40);
-	spin_unlock_irqrestore(&chip_wss->reg_lock, flags);
-
-	if ((err = snd_cmi8330_mixer(card, chip_wss)) < 0) {
+	if ((err = snd_cmi8330_mixer(card, acard->wss)) < 0) {
 		snd_printk("failed to create mixers\n");
 		snd_card_free(card);
 		return err;
 	}
-	spin_lock_irqsave(&chip_wss->reg_lock, flags);
+	spin_lock_irqsave(&acard->wss->reg_lock, flags);
 	for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++)
-		snd_ad1848_out(chip_wss, i, chip_wss->image[i]);
-	spin_unlock_irqrestore(&chip_wss->reg_lock, flags);
+		snd_ad1848_out(acard->wss, i, acard->wss->image[i]);
+	spin_unlock_irqrestore(&acard->wss->reg_lock, flags);
 
-	/*
-	 * KLUDGE ALERT
-	 *  disable AD1848 playback
-	 *  disable SB16 capture
-	 */
-	pcm = wss_pcm;
-	pstr = &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK];
-	snd_magic_kfree(pstr->substream);
-	pstr->substream = 0;
-	pstr->substream_count = 0;
-
-	pcm = sb_pcm;
-	pstr = &pcm->streams[SNDRV_PCM_STREAM_CAPTURE];
-	snd_magic_kfree(pstr->substream);
-	pstr->substream = 0;
-	pstr->substream_count = 0;
+	if ((err = snd_cmi8330_pcm(card, acard)) < 0) {
+		snd_printk("failed to create pcms\n");
+		snd_card_free(card);
+		return err;
+	}
 
 	strcpy(card->driver, "CMI8330/C3D");
 	strcpy(card->shortname, "C-Media CMI8330/C3D");
 	sprintf(card->longname, "%s at 0x%lx, irq %d, dma %d",
-		wss_pcm->name,
-		chip_wss->port,
+		card->shortname,
+		acard->wss->port,
 		wssirq[dev],
 		wssdma[dev]);
 
Index: alsa-kernel/isa/ad1848/ad1848_lib.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/isa/ad1848/ad1848_lib.c,v
retrieving revision 1.17
diff -u -r1.17 ad1848_lib.c
--- alsa-kernel/isa/ad1848/ad1848_lib.c	25 Nov 2002 10:13:55 -0000	1.17
+++ alsa-kernel/isa/ad1848/ad1848_lib.c	16 Dec 2002 14:35:39 -0000
@@ -936,6 +936,12 @@
 	return 0;
 }
 
+const snd_pcm_ops_t *snd_ad1848_get_pcm_ops(int direction)
+{
+	return direction == SNDRV_PCM_STREAM_PLAYBACK ?
+		&snd_ad1848_playback_ops : &snd_ad1848_capture_ops;
+}
+
 /*
  *  MIXER part
  */
@@ -1160,6 +1166,7 @@
 EXPORT_SYMBOL(snd_ad1848_interrupt);
 EXPORT_SYMBOL(snd_ad1848_create);
 EXPORT_SYMBOL(snd_ad1848_pcm);
+EXPORT_SYMBOL(snd_ad1848_get_pcm_ops);
 EXPORT_SYMBOL(snd_ad1848_mixer);
 EXPORT_SYMBOL(snd_ad1848_info_single);
 EXPORT_SYMBOL(snd_ad1848_get_single);
Index: alsa-kernel/isa/sb/sb16_main.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/isa/sb/sb16_main.c,v
retrieving revision 1.11
diff -u -r1.11 sb16_main.c
--- alsa-kernel/isa/sb/sb16_main.c	25 Nov 2002 10:13:56 -0000	1.11
+++ alsa-kernel/isa/sb/sb16_main.c	16 Dec 2002 14:35:02 -0000
@@ -887,7 +887,14 @@
 	return 0;
 }
 
+const snd_pcm_ops_t *snd_sb16dsp_get_pcm_ops(int direction)
+{
+	return direction == SNDRV_PCM_STREAM_PLAYBACK ?
+		&snd_sb16_playback_ops : &snd_sb16_capture_ops;
+}
+
 EXPORT_SYMBOL(snd_sb16dsp_pcm);
+EXPORT_SYMBOL(snd_sb16dsp_get_pcm_ops);
 EXPORT_SYMBOL(snd_sb16dsp_configure);
 EXPORT_SYMBOL(snd_sb16dsp_interrupt);
 

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2003-01-21 10:16 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-12-16 15:15 Requested: CMI8330 testers? Takashi Iwai
2002-12-27  9:19 ` Bernard Urban
2003-01-08 13:00   ` Takashi Iwai
2003-01-08 16:17     ` Takashi Iwai
2003-01-09 10:55       ` Takashi Iwai
     [not found]         ` <873cnxz8pz.fsf@merceron.meteo.fr>
     [not found]           ` <s5hel7hwf4p.wl@alsa2.suse.de>
     [not found]             ` <87ptqy3ij6.fsf_-_@merceron.meteo.fr>
2003-01-17 13:54               ` CMI8330: success ! Bernard Urban
2003-01-20  9:43                 ` Bernard Urban
2003-01-20  9:56                   ` Takashi Iwai
2003-01-21 10:11                     ` Bernard Urban
2003-01-21 10:16                       ` Takashi Iwai
2003-01-09 15:00     ` Requested: CMI8330 testers? Bernard Urban
2003-01-10 13:29       ` SB 16 driver OSS emulation Bernard Urban

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox