All of 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.