All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: Bernard Urban <Bernard.Urban@meteo.fr>
Cc: alsa-devel@lists.sourceforge.net
Subject: Re: Requested: CMI8330 testers?
Date: Wed, 08 Jan 2003 17:17:17 +0100	[thread overview]
Message-ID: <s5h1y3naa5u.wl@alsa2.suse.de> (raw)
In-Reply-To: <s5h65szajak.wl@alsa2.suse.de>

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

Hi, it's me again.

At Wed, 08 Jan 2003 14:00:03 +0100,
I wrote:
> 
> > And guess what, bingo, I got PCM sound ! But an horrible sound, very
> > distorted, so something is still working badly. This
> > was just after removing the 0.5 driver and installing the modified 0.9 one.
> > After rebooting the machine with the 0.9 running, no more sound!
>  
> ok, it explains the hardware init problem.
> i'll check the difference between 0.5 and 0.9.

please try the attached patch.
it will add the SB mixers (all new ones starting "SB xxx" except for
tone controls) and initializes the SB-mixer reg bit (as default).

the first step is to check whether and which SB mixer has influence to
what output/input.  there are also CMI8330-native controls, namely the
controls without "SB" prefix.  whether these controls affect the
playback.  the SB mixers can be disabled (removed) by commenting out
ENABLE_SB_MIXER definition in the source.

the next step is to switch playback and capture by commenting out the
definition PLAYBACK_ON_SB at the beginning of the code.  then the
playback will be done through AD1848 and capture will be on SB16.
check again which mixer elements work for what.


ciao,

Takashi

[-- Attachment #2: cmi8330-test.dif --]
[-- Type: application/octet-stream, Size: 10517 bytes --]

Index: alsa-kernel/isa/cmi8330.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/isa/cmi8330.c,v
retrieving revision 1.11
diff -u -r1.11 cmi8330.c
--- alsa-kernel/isa/cmi8330.c	7 Jan 2003 10:29:35 -0000	1.11
+++ alsa-kernel/isa/cmi8330.c	8 Jan 2003 16:13:30 -0000
@@ -57,6 +57,13 @@
 #define SNDRV_GET_ID
 #include <sound/initval.h>
 
+/*
+ */
+#define ENABLE_SB_MIXER
+#define PLAYBACK_ON_SB
+
+/*
+ */
 MODULE_AUTHOR("George Talusan <gstalusan@uwaterloo.ca>");
 MODULE_DESCRIPTION("C-Media CMI8330");
 MODULE_LICENSE("GPL");
@@ -129,8 +136,12 @@
 
 static unsigned char snd_cmi8330_image[((CMI8330_CDINGAIN)-16) + 1] =
 {
-	0x0,			/* 16 - recording mux */
-	0x40,			/* 17 - mute mux */
+	0x40,			/* 16 - recording mux (SB-mixer-enabled) */
+#ifdef ENABLE_SB_MIXER
+	0x40,			/* 17 - mute mux (Mode2) */
+#else
+	0x0,			/* 17 - mute mux */
+#endif
 	0x0,			/* 18 - vol */
 	0x0,			/* 19 - master volume */
 	0x0,			/* 20 - line-in volume */
@@ -152,10 +163,11 @@
 	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 *);
+	struct snd_cmi8330_stream {
+		snd_pcm_ops_t ops;
+		int (*open)(snd_pcm_substream_t *);
+		void *private_data; /* sb or wss */
+	} streams[2];
 };
 
 static snd_card_t *snd_cmi8330_cards[SNDRV_CARDS] = SNDRV_DEFAULT_PTR;
@@ -210,6 +222,24 @@
 AD1848_SINGLE("FM Playback Switch", 0, CMI8330_RECMUX, 3, 1, 1),
 AD1848_SINGLE("IEC958 Input Capture Switch", 0, CMI8330_RMUX3D, 7, 1, 1),
 AD1848_SINGLE("IEC958 Input Playback Switch", 0, CMI8330_MUTEMUX, 7, 1, 1),
+
+#ifdef ENABLE_SB_MIXER
+SB_DOUBLE("SB Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31),
+SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15),
+SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15),
+SB_DOUBLE("SB PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31),
+SB_DOUBLE("SB Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31),
+SB_DOUBLE("SB CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
+SB_DOUBLE("SB CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31),
+SB_DOUBLE("SB Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
+SB_DOUBLE("SB Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31),
+SB_SINGLE("SB Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
+SB_SINGLE("SB Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
+SB_SINGLE("SB PC Speaker Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
+SB_DOUBLE("SB Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3),
+SB_DOUBLE("SB Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3),
+SB_SINGLE("SB Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1),
+#endif
 };
 
 static int __init snd_cmi8330_mixer(snd_card_t *card, ad1848_t *chip)
@@ -316,13 +346,21 @@
  *
  */
 
+#ifdef PLAYBACK_ON_SB
+#define CMI_SB_STREAM	SNDRV_PCM_STREAM_PLAYBACK
+#define CMI_AD_STREAM	SNDRV_PCM_STREAM_CAPTURE
+#else
+#define CMI_SB_STREAM	SNDRV_PCM_STREAM_CAPTURE
+#define CMI_AD_STREAM	SNDRV_PCM_STREAM_PLAYBACK
+#endif
+
 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);
+	substream->private_data = chip->streams[SNDRV_PCM_STREAM_PLAYBACK].private_data;
+	return chip->streams[SNDRV_PCM_STREAM_PLAYBACK].open(substream);
 }
 
 static int snd_cmi8330_capture_open(snd_pcm_substream_t * substream)
@@ -330,8 +368,8 @@
 	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);
+	substream->private_data = chip->streams[SNDRV_PCM_STREAM_CAPTURE].private_data;
+	return chip->streams[SNDRV_PCM_STREAM_CAPTURE].open(substream);
 }
 
 static void snd_cmi8330_pcm_free(snd_pcm_t *pcm)
@@ -344,27 +382,33 @@
 	snd_pcm_t *pcm;
 	const snd_pcm_ops_t *ops;
 	int err;
-	
+	static int (*cmi_open_callbacks)(snd_pcm_substream_t *)[2] = {
+		snd_cmi8330_playback_open,
+		snd_cmi8330_capture_open
+	};
+
 	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;
+	/* SB16 */
+	ops = snd_sb16dsp_get_pcm_ops(CMI_SB_STREAM);
+	chip->streams[CMI_SB_STREAM].ops = *ops;
+	chip->streams[CMI_SB_STREAM].open = ops->open;
+	chip->streams[CMI_SB_STREAM].ops.open = cmi_open_callbacks[CMI_SB_STREAM];
+	chip->streams[CMI_SB_STREAM].private_data = chip->sb;
+
+	/* AD1848 */
+	ops = snd_ad1848_get_pcm_ops(CMI_AD_STREAM);
+	chip->streams[CMI_AD_STREAM].ops = *ops;
+	chip->streams[CMI_AD_STREAM].open = ops->open;
+	chip->streams[CMI_AD_STREAM].ops.open = cmi_open_callbacks[CMI_AD_STREAM];
+	chip->streams[CMI_AD_STREAM].private_data = chip->wss;
 
-	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_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &chip->streams[SNDRV_PCM_STREAM_PLAYBACK].ops);
+	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &chip->streams[SNDRV_PCM_STREAM_CAPTURE].ops);
 
 	snd_pcm_lib_preallocate_isa_pages_for_all(pcm, 64*1024, 128*1024);
 	chip->pcm = pcm;
@@ -457,11 +501,11 @@
 		snd_card_free(card);
 		return -ENODEV;
 	}
-	memcpy(&acard->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);
+	snd_ad1848_out(acard->wss, AD1848_MISC_INFO, 0x40); /* switch on MODE2 */
+	for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++)
+		snd_ad1848_out(acard->wss, i, snd_cmi8330_image[i - CMI8330_RMUX3D]);
 	spin_unlock_irqrestore(&acard->wss->reg_lock, flags);
 
 	if ((err = snd_cmi8330_mixer(card, acard->wss)) < 0) {
@@ -469,10 +513,6 @@
 		snd_card_free(card);
 		return err;
 	}
-	spin_lock_irqsave(&acard->wss->reg_lock, flags);
-	for (i = CMI8330_RMUX3D; i <= CMI8330_CDINGAIN; i++)
-		snd_ad1848_out(acard->wss, i, acard->wss->image[i]);
-	spin_unlock_irqrestore(&acard->wss->reg_lock, flags);
 
 	if ((err = snd_cmi8330_pcm(card, acard)) < 0) {
 		snd_printk("failed to create pcms\n");
Index: alsa-kernel/isa/sb/sb_common.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/isa/sb/sb_common.c,v
retrieving revision 1.14
diff -u -r1.14 sb_common.c
--- alsa-kernel/isa/sb/sb_common.c	25 Nov 2002 10:13:56 -0000	1.14
+++ alsa-kernel/isa/sb/sb_common.c	8 Jan 2003 15:58:00 -0000
@@ -298,6 +298,13 @@
 EXPORT_SYMBOL(snd_sbmixer_read);
 EXPORT_SYMBOL(snd_sbmixer_new);
 
+EXPORT_SYMBOL(snd_sbmixer_info_single);
+EXPORT_SYMBOL(snd_sbmixer_get_single);
+EXPORT_SYMBOL(snd_sbmixer_put_single);
+EXPORT_SYMBOL(snd_sbmixer_info_double);
+EXPORT_SYMBOL(snd_sbmixer_get_double);
+EXPORT_SYMBOL(snd_sbmixer_put_double);
+
 /*
  *  INIT part
  */
Index: alsa-kernel/isa/sb/sb_mixer.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/isa/sb/sb_mixer.c,v
retrieving revision 1.9
diff -u -r1.9 sb_mixer.c
--- alsa-kernel/isa/sb/sb_mixer.c	7 Jan 2003 10:39:16 -0000	1.9
+++ alsa-kernel/isa/sb/sb_mixer.c	8 Jan 2003 15:57:24 -0000
@@ -60,15 +60,7 @@
  * Single channel mixer element
  */
 
-#define SB_SINGLE(xname, reg, shift, mask) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .info = snd_sbmixer_info_single, \
-  .get = snd_sbmixer_get_single, \
-  .put = snd_sbmixer_put_single, \
-  .private_value = reg | (shift << 16) | (mask << 24) }
-
-static int snd_sbmixer_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+int snd_sbmixer_info_single(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -79,7 +71,7 @@
 	return 0;
 }
 
-static int snd_sbmixer_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_sbmixer_get_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	sb_t *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -95,7 +87,7 @@
 	return 0;
 }
 
-static int snd_sbmixer_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_sbmixer_put_single(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	sb_t *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -120,15 +112,7 @@
  * Double channel mixer element
  */
 
-#define SB_DOUBLE(xname, left_reg, right_reg, left_shift, right_shift, mask) \
-{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
-  .name = xname, \
-  .info = snd_sbmixer_info_double, \
-  .get = snd_sbmixer_get_double, \
-  .put = snd_sbmixer_put_double, \
-  .private_value = left_reg | (right_reg << 8) | (left_shift << 16) | (right_shift << 19) | (mask << 24) }
-
-static int snd_sbmixer_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+int snd_sbmixer_info_double(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
 {
 	int mask = (kcontrol->private_value >> 24) & 0xff;
 
@@ -139,7 +123,7 @@
 	return 0;
 }
 
-static int snd_sbmixer_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_sbmixer_get_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	sb_t *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;
@@ -159,7 +143,7 @@
 	return 0;
 }
 
-static int snd_sbmixer_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
+int snd_sbmixer_put_double(snd_kcontrol_t * kcontrol, snd_ctl_elem_value_t * ucontrol)
 {
 	sb_t *sb = snd_kcontrol_chip(kcontrol);
 	unsigned long flags;

  reply	other threads:[~2003-01-08 16:17 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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=s5h1y3naa5u.wl@alsa2.suse.de \
    --to=tiwai@suse.de \
    --cc=Bernard.Urban@meteo.fr \
    --cc=alsa-devel@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.