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 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.