From: Takashi Iwai <tiwai@suse.de>
To: alsa-devel@lists.sourceforge.net
Cc: alsa-user@lists.sourceforge.net
Subject: Requested: CMI8330 testers?
Date: Mon, 16 Dec 2002 16:15:41 +0100 [thread overview]
Message-ID: <s5hy96qro4i.wl@alsa2.suse.de> (raw)
[-- 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);
next reply other threads:[~2002-12-16 15:15 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-12-16 15:15 Takashi Iwai [this message]
2002-12-27 9:19 ` Requested: CMI8330 testers? 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=s5hy96qro4i.wl@alsa2.suse.de \
--to=tiwai@suse.de \
--cc=alsa-devel@lists.sourceforge.net \
--cc=alsa-user@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox