All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] aureon.c - adc mux, master vol
@ 2004-07-03 15:46 Christoph Haderer
  2004-07-05 10:00 ` Takashi Iwai
  0 siblings, 1 reply; 6+ messages in thread
From: Christoph Haderer @ 2004-07-03 15:46 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel

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

The attached patch fixes a problem in adc_mux_put (without these
changes, wrong values a written to the right input mux);
it also reverts the changes of dac_vol_get and dac_vol_put which where
introduced in revision 1.11, because in the current version changing the
Master Volume control affects only DAC1 volume (IMHO WM_DAC_MASTER_ATTEN
is the right location - not WM_DAC_ATTEN).

Regards,
Christoph Haderer


[-- Attachment #2: aureon.c-patch --]
[-- Type: text/plain, Size: 1520 bytes --]

--- aureon.c.old	2004-07-03 14:13:05.000000000 +0200
+++ aureon.c	2004-07-03 17:18:40.000000000 +0200
@@ -227,7 +227,10 @@
 	unsigned short vol;
 
 	down(&ice->gpio_mutex);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_DAC_ATTEN;
+	if (kcontrol->private_value)
+		idx = WM_DAC_MASTER_ATTEN;
+	else
+		idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_DAC_ATTEN;
 	vol = wm_get(ice, idx) & 0x7f;
 	if (vol <= 0x1a)
 		ucontrol->value.integer.value[0] = 0;
@@ -245,7 +248,10 @@
 	int change;
 
 	snd_ice1712_save_gpio_status(ice);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_DAC_ATTEN;
+	if (kcontrol->private_value)
+		idx = WM_DAC_MASTER_ATTEN;
+	else
+		idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_DAC_ATTEN;
 	nvol = ucontrol->value.integer.value[0] + 0x1a;
 	ovol = wm_get(ice, idx) & 0x7f;
 	change = (ovol != nvol);
@@ -374,8 +380,7 @@
 
 	down(&ice->gpio_mutex);
 	val = wm_get(ice, WM_ADC_MUX);
-	ucontrol->value.integer.value[0] = val & 7;
-	ucontrol->value.integer.value[1] = (val >> 4) & 7;
+	ucontrol->value.integer.value = val & 7;
 	up(&ice->gpio_mutex);
 	return 0;
 }
@@ -389,8 +394,8 @@
 	snd_ice1712_save_gpio_status(ice);
 	oval = wm_get(ice, WM_ADC_MUX);
 	nval = oval & ~0x77;
-	nval |= ucontrol->value.integer.value[0] & 7;
-	nval |= (ucontrol->value.integer.value[1] & 7) << 4;
+	nval |= ucontrol->value.integer.value & 7;
+	nval |= (ucontrol->value.integer.value & 7) << 4;
 	change = (oval != nval);
 	if (change)
 		wm_put(ice, WM_ADC_MUX, nval);

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

* Re: [PATCH] aureon.c - adc mux, master vol
  2004-07-03 15:46 [PATCH] aureon.c - adc mux, master vol Christoph Haderer
@ 2004-07-05 10:00 ` Takashi Iwai
  2004-07-07  1:05   ` Apostolos Dimitromanolakis
  0 siblings, 1 reply; 6+ messages in thread
From: Takashi Iwai @ 2004-07-05 10:00 UTC (permalink / raw)
  To: Christoph Haderer; +Cc: alsa-devel

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

Hi Chirstoph,

At Sat, 03 Jul 2004 17:46:24 +0200,
Christoph Haderer wrote:
> 
> [1  <text/plain; us-ascii (7bit)>]
> The attached patch fixes a problem in adc_mux_put (without these
> changes, wrong values a written to the right input mux);
> it also reverts the changes of dac_vol_get and dac_vol_put which where
> introduced in revision 1.11, because in the current version changing the
> Master Volume control affects only DAC1 volume (IMHO WM_DAC_MASTER_ATTEN
> is the right location - not WM_DAC_ATTEN).

Thanks for the patch.  Looks like I forgot to remove/change some
things.  It would be nice if you can test aureon boards with the
latest changes.

The below is the completely rewritten patch.  It includes

- Removal of 'Master Playback Volume', which is bogus
  (it forces to change all DAC volumes)

- Split 'DAC Volumes' to Front/Rear/Center/LFE/Side volumes.
  Please test whether the volume element really corresponds to the
  assigned output.  Rear and Center/LFE might be swapped.
- Fix ADC capture mutx for stereo.


thanks,

Takashi

[-- Attachment #2: Type: text/plain, Size: 9919 bytes --]

Index: alsa-kernel/pci/ice1712/aureon.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/pci/ice1712/aureon.c,v
retrieving revision 1.15
diff -u -r1.15 aureon.c
--- alsa-kernel/pci/ice1712/aureon.c	28 Jun 2004 14:02:08 -0000	1.15
+++ alsa-kernel/pci/ice1712/aureon.c	5 Jul 2004 09:58:54 -0000
@@ -168,9 +168,8 @@
 }
 
 /*
- * DAC mute control
  */
-static int wm_dac_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int aureon_mono_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -179,6 +178,11 @@
 	return 0;
 }
 
+/*
+ * DAC mute control
+ */
+#define wm_dac_mute_info	aureon_mono_bool_info
+
 static int wm_dac_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
@@ -213,8 +217,9 @@
  */
 static int wm_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
+	int voices = kcontrol->private_value >> 8;
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 1;
+	uinfo->count = voices;
 	uinfo->value.integer.min = 0;		/* mute */
 	uinfo->value.integer.max = 101;		/* 0dB */
 	return 0;
@@ -223,16 +228,20 @@
 static int wm_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx;
+	int i, idx, ofs, voices;
 	unsigned short vol;
 
+	voices = kcontrol->private_value >> 8;
+	ofs = kcontrol->private_value & 0xff;
 	down(&ice->gpio_mutex);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_DAC_ATTEN;
-	vol = wm_get(ice, idx) & 0x7f;
-	if (vol <= 0x1a)
-		ucontrol->value.integer.value[0] = 0;
-	else
-		ucontrol->value.integer.value[0] = vol - 0x1a;
+	for (i = 0; i < voices; i++) {
+		idx  = WM_DAC_ATTEN + ofs + i;
+		vol = wm_get(ice, idx) & 0x7f;
+		if (vol <= 0x1a)
+			ucontrol->value.integer.value[i] = 0;
+		else
+			ucontrol->value.integer.value[i] = vol - 0x1a;
+	}
 	up(&ice->gpio_mutex);
 	return 0;
 }
@@ -240,21 +249,23 @@
 static int wm_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx;
+	int i, idx, ofs, voices;
 	unsigned short ovol, nvol;
-	int change;
+	int change = 0;
 
+	voices = kcontrol->private_value >> 8;
+	ofs = kcontrol->private_value & 0xff;
 	snd_ice1712_save_gpio_status(ice);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_DAC_ATTEN;
-	nvol = ucontrol->value.integer.value[0] + 0x1a;
-	ovol = wm_get(ice, idx) & 0x7f;
-	change = (ovol != nvol);
-	if (change) {
-		if (nvol <= 0x1a && ovol <= 0x1a)
-			change = 0;
-		else {
+	for (i = 0; i < 2; i++) {
+		idx  = WM_DAC_ATTEN + ofs + i;
+		nvol = ucontrol->value.integer.value[i] + 0x1a;
+		ovol = wm_get(ice, idx) & 0x7f;
+		if (ovol != nvol) {
+			if (nvol <= 0x1a && ovol <= 0x1a)
+				continue;
 			wm_put(ice, idx, nvol | 0x80); /* zero-detect, prelatch */
 			wm_put_nocache(ice, idx, nvol | 0x180); /* update */
+			change = 1;
 		}
 	}
 	snd_ice1712_restore_gpio_status(ice);
@@ -264,14 +275,7 @@
 /*
  * ADC mute control
  */
-static int wm_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-	uinfo->count = 1;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 1;
-	return 0;
-}
+#define wm_adc_mute_info	aureon_mono_bool_info
 
 static int wm_adc_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
@@ -308,7 +312,7 @@
 static int wm_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 1;
+	uinfo->count = 2;
 	uinfo->value.integer.min = 0;		/* -12dB */
 	uinfo->value.integer.max = 0x1f;	/* 19dB */
 	return 0;
@@ -317,13 +321,15 @@
 static int wm_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx;
+	int i, idx;
 	unsigned short vol;
 
 	down(&ice->gpio_mutex);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_ADC_GAIN;
-	vol = wm_get(ice, idx) & 0x1f;
-	ucontrol->value.integer.value[0] = vol;
+	for (i = 0; i < 2; i++) {
+		idx = WM_ADC_GAIN + i;
+		vol = wm_get(ice, idx) & 0x1f;
+		ucontrol->value.integer.value[i] = vol;
+	}
 	up(&ice->gpio_mutex);
 	return 0;
 }
@@ -331,17 +337,20 @@
 static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx;
+	int i, idx;
 	unsigned short ovol, nvol;
-	int change;
+	int change = 0;
 
 	snd_ice1712_save_gpio_status(ice);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_ADC_GAIN;
-	nvol = ucontrol->value.integer.value[0];
-	ovol = wm_get(ice, idx);
-	change = ((ovol & 0x1f)  != nvol);
-	if (change)
-		wm_put(ice, idx, nvol | (ovol & ~0x1f));
+	for (i = 0; i < 2; i++) {
+		idx  = WM_ADC_GAIN + i;
+		nvol = ucontrol->value.integer.value[i];
+		ovol = wm_get(ice, idx);
+		if ((ovol & 0x1f) != nvol) {
+			wm_put(ice, idx, nvol | (ovol & ~0x1f));
+			change = 1;
+		}
+	}
 	snd_ice1712_restore_gpio_status(ice);
 	return change;
 }
@@ -359,7 +368,7 @@
 		"AC97"		//AIN5
 	};
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
+	uinfo->count = 2;
 	uinfo->value.enumerated.items = 5;
 	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
 		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
@@ -424,14 +433,7 @@
 	return ( tmp & AUREON_HP_SEL )!= 0;
 }
 
-static int aureon_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-	uinfo->count = 1;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 1;
-	return 0;
-}
+#define aureon_hpamp_info	aureon_mono_bool_info
 
 static int aureon_hpamp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
@@ -452,6 +454,9 @@
 /*
  * Deemphasis
  */
+
+#define aureon_deemp_info	aureon_mono_bool_info
+
 static int aureon_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
@@ -523,44 +528,60 @@
  * mixers
  */
 
-static snd_kcontrol_new_t aureon51_dac_control __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "DAC Volume",
-	.count = 6,
-	.info = wm_dac_vol_info,
-	.get = wm_dac_vol_get,
-	.put = wm_dac_vol_put,
-};
-
-static snd_kcontrol_new_t aureon71_dac_control __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "DAC Volume",
-	.count = 8,
-	.info = wm_dac_vol_info,
-	.get = wm_dac_vol_get,
-	.put = wm_dac_vol_put,
-};
-
-static snd_kcontrol_new_t wm_controls[] __devinitdata = {
+static snd_kcontrol_new_t aureon_dac_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Master Playback Switch",
-		.info = wm_dac_mute_info,
-		.get = wm_dac_mute_get,
-		.put = wm_dac_mute_put,
+		.name = "Front Playback Volume",
+		.info = wm_dac_vol_info,
+		.get = wm_dac_vol_get,
+		.put = wm_dac_vol_put,
+		.private_value = (2 << 8) | 0
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Rear Playback Volume",
+		.info = wm_dac_vol_info,
+		.get = wm_dac_vol_get,
+		.put = wm_dac_vol_put,
+		.private_value = (2 << 8) | 2
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Center Playback Volume",
+		.info = wm_dac_vol_info,
+		.get = wm_dac_vol_get,
+		.put = wm_dac_vol_put,
+		.private_value = (1 << 8) | 4
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Master Playback Volume",
+		.name = "LFE Playback Volume",
 		.info = wm_dac_vol_info,
 		.get = wm_dac_vol_get,
 		.put = wm_dac_vol_put,
-		.private_value = 1,
+		.private_value = (1 << 8) | 5
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "ADC Switch",
-		.count = 2,
+		.name = "Side Playback Volume",
+		.info = wm_dac_vol_info,
+		.get = wm_dac_vol_get,
+		.put = wm_dac_vol_put,
+		.private_value = (2 << 8) | 6
+	}
+};
+
+static snd_kcontrol_new_t wm_controls[] __devinitdata = {
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Switch",
+		.info = wm_dac_mute_info,
+		.get = wm_dac_mute_get,
+		.put = wm_dac_mute_put,
+ 	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Switch",
 		.info = wm_adc_mute_info,
 		.get = wm_adc_mute_get,
 		.put = wm_adc_mute_put,
@@ -568,15 +589,14 @@
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "ADC Volume",
-		.count = 2,
+		.name = "Capture Volume",
 		.info = wm_adc_vol_info,
 		.get = wm_adc_vol_get,
 		.put = wm_adc_vol_put,
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Capture Route",
+		.name = "Capture Source",
 		.info = wm_adc_mux_info,
 		.get = wm_adc_mux_get,
 		.put = wm_adc_mux_put,
@@ -584,14 +604,14 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Headphone Amplifier Switch",
-		.info = aureon_bool_info,
+		.info = aureon_hpamp_info,
 		.get = aureon_hpamp_get,
 		.put = aureon_hpamp_put
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "DAC Deemphasis Switch",
-		.info = aureon_bool_info,
+		.info = aureon_deemp_info,
 		.get = aureon_deemp_get,
 		.put = aureon_deemp_put
 	},
@@ -607,15 +627,17 @@
 
 static int __devinit aureon_add_controls(ice1712_t *ice)
 {
-	unsigned int i;
+	unsigned int i, counts;
 	int err;
 
+	counts = ARRAY_SIZE(aureon_dac_controls);
 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon51_dac_control, ice));
-	else
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon71_dac_control, ice));
-	if (err < 0)
-		return err;
+		counts--; /* no side */
+	for (i = 0; i < counts; i++) {
+		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
+		if (err < 0)
+			return err;
+	}
 
 	for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
 		err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));

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

* Re: [PATCH] aureon.c - adc mux, master vol
  2004-07-05 10:00 ` Takashi Iwai
@ 2004-07-07  1:05   ` Apostolos Dimitromanolakis
  2004-07-15 15:39     ` Takashi Iwai
  0 siblings, 1 reply; 6+ messages in thread
From: Apostolos Dimitromanolakis @ 2004-07-07  1:05 UTC (permalink / raw)
  To: alsa-devel


I think it would be convenient for the end user  to keep the Master
volume attenuation on Aureon & Prodigy.  There are seperate analog and
digital volume controls on the chip and since each DAC has it's analog
volume control as a mixer element, why not have the master digital
volume as another control?

Minor change one could say but imagine someone trying to adjust the
volume of his 5.1 speaker system while playing a DVD.

Apostolos


Takashi Iwai wrote:

>Thanks for the patch.  Looks like I forgot to remove/change some
>things.  It would be nice if you can test aureon boards with the
>latest changes.
>
>The below is the completely rewritten patch.  It includes
>
>- Removal of 'Master Playback Volume', which is bogus
>  (it forces to change all DAC volumes)
>
>- Split 'DAC Volumes' to Front/Rear/Center/LFE/Side volumes.
>  Please test whether the volume element really corresponds to the
>  assigned output.  Rear and Center/LFE might be swapped.
>- Fix ADC capture mutx for stereo.
>
>
>thanks,
>
>Takashi
>  
>




-------------------------------------------------------
This SF.Net email sponsored by Black Hat Briefings & Training.
Attend Black Hat Briefings & Training, Las Vegas July 24-29 - 
digital self defense, top technical experts, no vendor pitches, 
unmatched networking opportunities. Visit www.blackhat.com

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

* Re: [PATCH] aureon.c - adc mux, master vol
  2004-07-07  1:05   ` Apostolos Dimitromanolakis
@ 2004-07-15 15:39     ` Takashi Iwai
  2004-07-15 17:40       ` Apostolos Dimitromanolakis
  0 siblings, 1 reply; 6+ messages in thread
From: Takashi Iwai @ 2004-07-15 15:39 UTC (permalink / raw)
  To: Apostolos Dimitromanolakis; +Cc: alsa-devel

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

Hi,

it seems that my last post didn't go out properly...

At Tue, 06 Jul 2004 21:05:44 -0400,
Apostolos Dimitromanolakis wrote:
> 
> 
> I think it would be convenient for the end user  to keep the Master
> volume attenuation on Aureon & Prodigy.  There are seperate analog and
> digital volume controls on the chip and since each DAC has it's analog
> volume control as a mixer element, why not have the master digital
> volume as another control?

The master volume control on WM codec seems not to be a real 'master
control'.  It's no independent control but just modifies the all DAC
volumes at once.

If we keep this, the DAC volumes must be updated and the changes must
be notified.  But then the question is how to handle master volume
when only a DAC volume is changed?


BTW, the attached patch is to use more intuitive control names for
volume and capture controls.  The bogus master volume is removed.
Could aureon/prodigy owners can test it?

It's to the latest CVS.


thanks,

Takashi

[-- Attachment #2: Type: text/plain, Size: 11066 bytes --]

Index: alsa-kernel/pci/ice1712/aureon.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/pci/ice1712/aureon.c,v
retrieving revision 1.15
diff -u -r1.15 aureon.c
--- alsa-kernel/pci/ice1712/aureon.c	28 Jun 2004 14:02:08 -0000	1.15
+++ alsa-kernel/pci/ice1712/aureon.c	15 Jul 2004 12:35:55 -0000
@@ -168,9 +168,8 @@
 }
 
 /*
- * DAC mute control
  */
-static int wm_dac_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int aureon_mono_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -179,6 +178,11 @@
 	return 0;
 }
 
+/*
+ * DAC mute control
+ */
+#define wm_dac_mute_info	aureon_mono_bool_info
+
 static int wm_dac_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
@@ -213,8 +217,9 @@
  */
 static int wm_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
+	int voices = kcontrol->private_value >> 8;
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 1;
+	uinfo->count = voices;
 	uinfo->value.integer.min = 0;		/* mute */
 	uinfo->value.integer.max = 101;		/* 0dB */
 	return 0;
@@ -223,16 +228,20 @@
 static int wm_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx;
+	int i, idx, ofs, voices;
 	unsigned short vol;
 
+	voices = kcontrol->private_value >> 8;
+	ofs = kcontrol->private_value & 0xff;
 	down(&ice->gpio_mutex);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_DAC_ATTEN;
-	vol = wm_get(ice, idx) & 0x7f;
-	if (vol <= 0x1a)
-		ucontrol->value.integer.value[0] = 0;
-	else
-		ucontrol->value.integer.value[0] = vol - 0x1a;
+	for (i = 0; i < voices; i++) {
+		idx  = WM_DAC_ATTEN + ofs + i;
+		vol = wm_get(ice, idx) & 0x7f;
+		if (vol <= 0x1a)
+			ucontrol->value.integer.value[i] = 0;
+		else
+			ucontrol->value.integer.value[i] = vol - 0x1a;
+	}
 	up(&ice->gpio_mutex);
 	return 0;
 }
@@ -240,21 +249,23 @@
 static int wm_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx;
+	int i, idx, ofs, voices;
 	unsigned short ovol, nvol;
-	int change;
+	int change = 0;
 
+	voices = kcontrol->private_value >> 8;
+	ofs = kcontrol->private_value & 0xff;
 	snd_ice1712_save_gpio_status(ice);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_DAC_ATTEN;
-	nvol = ucontrol->value.integer.value[0] + 0x1a;
-	ovol = wm_get(ice, idx) & 0x7f;
-	change = (ovol != nvol);
-	if (change) {
-		if (nvol <= 0x1a && ovol <= 0x1a)
-			change = 0;
-		else {
+	for (i = 0; i < 2; i++) {
+		idx  = WM_DAC_ATTEN + ofs + i;
+		nvol = ucontrol->value.integer.value[i] + 0x1a;
+		ovol = wm_get(ice, idx) & 0x7f;
+		if (ovol != nvol) {
+			if (nvol <= 0x1a && ovol <= 0x1a)
+				continue;
 			wm_put(ice, idx, nvol | 0x80); /* zero-detect, prelatch */
 			wm_put_nocache(ice, idx, nvol | 0x180); /* update */
+			change = 1;
 		}
 	}
 	snd_ice1712_restore_gpio_status(ice);
@@ -264,10 +275,10 @@
 /*
  * ADC mute control
  */
-static int wm_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int wm_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-	uinfo->count = 1;
+	uinfo->count = 2;
 	uinfo->value.integer.min = 0;
 	uinfo->value.integer.max = 1;
 	return 0;
@@ -277,10 +288,13 @@
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
+	int i;
 
 	down(&ice->gpio_mutex);
-	val = wm_get(ice, snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)+WM_ADC_GAIN);
-	ucontrol->value.integer.value[0] = ~val>>5 & 0x1;
+	for (i = 0; i < 2; i++) {
+		val = wm_get(ice, WM_ADC_GAIN + i);
+		ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
+	}
 	up(&ice->gpio_mutex);
 	return 0;
 }
@@ -289,14 +303,17 @@
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short new, old;
-	int change;
+	int i, change = 0;
 
 	snd_ice1712_save_gpio_status(ice);
-	old = wm_get(ice, snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)+WM_ADC_GAIN);
-	new = (~ucontrol->value.integer.value[0]<<5&0x20) | (old&~0x20);
-	change = (new != old);
-	if (change)
-		wm_put(ice, snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)+WM_ADC_GAIN, new);
+	for (i = 0; i < 2; i++) {
+		old = wm_get(ice, WM_ADC_GAIN + i);
+		new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
+		if (new != old) {
+			wm_put(ice, snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)+WM_ADC_GAIN, new);
+			change = 1;
+		}
+	}
 	snd_ice1712_restore_gpio_status(ice);
 
 	return change;
@@ -308,7 +325,7 @@
 static int wm_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 1;
+	uinfo->count = 2;
 	uinfo->value.integer.min = 0;		/* -12dB */
 	uinfo->value.integer.max = 0x1f;	/* 19dB */
 	return 0;
@@ -317,13 +334,15 @@
 static int wm_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx;
+	int i, idx;
 	unsigned short vol;
 
 	down(&ice->gpio_mutex);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_ADC_GAIN;
-	vol = wm_get(ice, idx) & 0x1f;
-	ucontrol->value.integer.value[0] = vol;
+	for (i = 0; i < 2; i++) {
+		idx = WM_ADC_GAIN + i;
+		vol = wm_get(ice, idx) & 0x1f;
+		ucontrol->value.integer.value[i] = vol;
+	}
 	up(&ice->gpio_mutex);
 	return 0;
 }
@@ -331,17 +350,20 @@
 static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx;
+	int i, idx;
 	unsigned short ovol, nvol;
-	int change;
+	int change = 0;
 
 	snd_ice1712_save_gpio_status(ice);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_ADC_GAIN;
-	nvol = ucontrol->value.integer.value[0];
-	ovol = wm_get(ice, idx);
-	change = ((ovol & 0x1f)  != nvol);
-	if (change)
-		wm_put(ice, idx, nvol | (ovol & ~0x1f));
+	for (i = 0; i < 2; i++) {
+		idx  = WM_ADC_GAIN + i;
+		nvol = ucontrol->value.integer.value[i];
+		ovol = wm_get(ice, idx);
+		if ((ovol & 0x1f) != nvol) {
+			wm_put(ice, idx, nvol | (ovol & ~0x1f));
+			change = 1;
+		}
+	}
 	snd_ice1712_restore_gpio_status(ice);
 	return change;
 }
@@ -359,7 +381,7 @@
 		"AC97"		//AIN5
 	};
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
+	uinfo->count = 2;
 	uinfo->value.enumerated.items = 5;
 	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
 		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
@@ -424,14 +446,7 @@
 	return ( tmp & AUREON_HP_SEL )!= 0;
 }
 
-static int aureon_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-	uinfo->count = 1;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 1;
-	return 0;
-}
+#define aureon_hpamp_info	aureon_mono_bool_info
 
 static int aureon_hpamp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
@@ -452,6 +467,9 @@
 /*
  * Deemphasis
  */
+
+#define aureon_deemp_info	aureon_mono_bool_info
+
 static int aureon_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
@@ -523,44 +541,60 @@
  * mixers
  */
 
-static snd_kcontrol_new_t aureon51_dac_control __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "DAC Volume",
-	.count = 6,
-	.info = wm_dac_vol_info,
-	.get = wm_dac_vol_get,
-	.put = wm_dac_vol_put,
-};
-
-static snd_kcontrol_new_t aureon71_dac_control __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "DAC Volume",
-	.count = 8,
-	.info = wm_dac_vol_info,
-	.get = wm_dac_vol_get,
-	.put = wm_dac_vol_put,
-};
-
-static snd_kcontrol_new_t wm_controls[] __devinitdata = {
+static snd_kcontrol_new_t aureon_dac_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Master Playback Switch",
-		.info = wm_dac_mute_info,
-		.get = wm_dac_mute_get,
-		.put = wm_dac_mute_put,
+		.name = "Front Playback Volume",
+		.info = wm_dac_vol_info,
+		.get = wm_dac_vol_get,
+		.put = wm_dac_vol_put,
+		.private_value = (2 << 8) | 0
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Rear Playback Volume",
+		.info = wm_dac_vol_info,
+		.get = wm_dac_vol_get,
+		.put = wm_dac_vol_put,
+		.private_value = (2 << 8) | 2
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Center Playback Volume",
+		.info = wm_dac_vol_info,
+		.get = wm_dac_vol_get,
+		.put = wm_dac_vol_put,
+		.private_value = (1 << 8) | 4
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Master Playback Volume",
+		.name = "LFE Playback Volume",
 		.info = wm_dac_vol_info,
 		.get = wm_dac_vol_get,
 		.put = wm_dac_vol_put,
-		.private_value = 1,
+		.private_value = (1 << 8) | 5
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "ADC Switch",
-		.count = 2,
+		.name = "Side Playback Volume",
+		.info = wm_dac_vol_info,
+		.get = wm_dac_vol_get,
+		.put = wm_dac_vol_put,
+		.private_value = (2 << 8) | 6
+	}
+};
+
+static snd_kcontrol_new_t wm_controls[] __devinitdata = {
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Switch",
+		.info = wm_dac_mute_info,
+		.get = wm_dac_mute_get,
+		.put = wm_dac_mute_put,
+ 	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Switch",
 		.info = wm_adc_mute_info,
 		.get = wm_adc_mute_get,
 		.put = wm_adc_mute_put,
@@ -568,15 +602,14 @@
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "ADC Volume",
-		.count = 2,
+		.name = "Capture Volume",
 		.info = wm_adc_vol_info,
 		.get = wm_adc_vol_get,
 		.put = wm_adc_vol_put,
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Capture Route",
+		.name = "Capture Source",
 		.info = wm_adc_mux_info,
 		.get = wm_adc_mux_get,
 		.put = wm_adc_mux_put,
@@ -584,14 +617,14 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Headphone Amplifier Switch",
-		.info = aureon_bool_info,
+		.info = aureon_hpamp_info,
 		.get = aureon_hpamp_get,
 		.put = aureon_hpamp_put
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "DAC Deemphasis Switch",
-		.info = aureon_bool_info,
+		.info = aureon_deemp_info,
 		.get = aureon_deemp_get,
 		.put = aureon_deemp_put
 	},
@@ -607,15 +640,17 @@
 
 static int __devinit aureon_add_controls(ice1712_t *ice)
 {
-	unsigned int i;
+	unsigned int i, counts;
 	int err;
 
+	counts = ARRAY_SIZE(aureon_dac_controls);
 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon51_dac_control, ice));
-	else
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon71_dac_control, ice));
-	if (err < 0)
-		return err;
+		counts--; /* no side */
+	for (i = 0; i < counts; i++) {
+		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
+		if (err < 0)
+			return err;
+	}
 
 	for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
 		err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));

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

* Re: [PATCH] aureon.c - adc mux, master vol
  2004-07-15 15:39     ` Takashi Iwai
@ 2004-07-15 17:40       ` Apostolos Dimitromanolakis
  2004-07-16  9:43         ` Takashi Iwai
  0 siblings, 1 reply; 6+ messages in thread
From: Apostolos Dimitromanolakis @ 2004-07-15 17:40 UTC (permalink / raw)
  To: Takashi Iwai, alsa-devel


Yeah you are right about the master volume as it is implemented but I 
think there are seperate analog & digital volume control so it could be 
possible to use analog for the master and the digital for the DAC channels.

I will be away from my computer so I can't test the patch right now but 
I will have a look at the driver again soon.

Apostolos

Takashi Iwai wrote:

>Hi,
>
>it seems that my last post didn't go out properly...
>
>At Tue, 06 Jul 2004 21:05:44 -0400,
>Apostolos Dimitromanolakis wrote:
>  
>
>>I think it would be convenient for the end user  to keep the Master
>>volume attenuation on Aureon & Prodigy.  There are seperate analog and
>>digital volume controls on the chip and since each DAC has it's analog
>>volume control as a mixer element, why not have the master digital
>>volume as another control?
>>    
>>
>
>The master volume control on WM codec seems not to be a real 'master
>control'.  It's no independent control but just modifies the all DAC
>volumes at once.
>
>If we keep this, the DAC volumes must be updated and the changes must
>be notified.  But then the question is how to handle master volume
>when only a DAC volume is changed?
>
>
>BTW, the attached patch is to use more intuitive control names for
>volume and capture controls.  The bogus master volume is removed.
>Could aureon/prodigy owners can test it?
>
>It's to the latest CVS.
>
>
>thanks,
>
>Takashi
>  
>



-------------------------------------------------------
This SF.Net email is sponsored by BEA Weblogic Workshop
FREE Java Enterprise J2EE developer tools!
Get your free copy of BEA WebLogic Workshop 8.1 today.
http://ads.osdn.com/?ad_id=4721&alloc_id=10040&op=click

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

* Re: [PATCH] aureon.c - adc mux, master vol
  2004-07-15 17:40       ` Apostolos Dimitromanolakis
@ 2004-07-16  9:43         ` Takashi Iwai
  0 siblings, 0 replies; 6+ messages in thread
From: Takashi Iwai @ 2004-07-16  9:43 UTC (permalink / raw)
  To: Apostolos Dimitromanolakis; +Cc: alsa-devel

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

At Thu, 15 Jul 2004 13:40:49 -0400,
Apostolos Dimitromanolakis wrote:
> 
> 
> Yeah you are right about the master volume as it is implemented but I 
> think there are seperate analog & digital volume control so it could be 
> possible to use analog for the master and the digital for the DAC channels.

Oh, that's a good point.

The attached is a new patch including the master digital volume.
Please let me know if it works.


Takashi

[-- Attachment #2: Type: text/plain, Size: 13003 bytes --]

Index: alsa-kernel/pci/ice1712/aureon.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/pci/ice1712/aureon.c,v
retrieving revision 1.15
diff -u -r1.15 aureon.c
--- alsa-kernel/pci/ice1712/aureon.c	28 Jun 2004 14:02:08 -0000	1.15
+++ alsa-kernel/pci/ice1712/aureon.c	16 Jul 2004 09:40:58 -0000
@@ -75,7 +75,7 @@
 #define WM_DAC_ATTEN		0x00	/* DAC1-8 analog attenuation */
 #define WM_DAC_MASTER_ATTEN	0x08	/* DAC master analog attenuation */
 #define WM_DAC_DIG_ATTEN	0x09	/* DAC1-8 digital attenuation */
-#define WM_DAC_DIG_MATER_ATTEN	0x11	/* DAC master digital attenuation */
+#define WM_DAC_DIG_MASTER_ATTEN	0x11	/* DAC master digital attenuation */
 #define WM_PHASE_SWAP		0x12	/* DAC phase */
 #define WM_DAC_CTRL1		0x13	/* DAC control bits */
 #define WM_MUTE			0x14	/* mute controls */
@@ -168,9 +168,8 @@
 }
 
 /*
- * DAC mute control
  */
-static int wm_dac_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int aureon_mono_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 	uinfo->count = 1;
@@ -179,6 +178,11 @@
 	return 0;
 }
 
+/*
+ * DAC mute control
+ */
+#define wm_dac_mute_info	aureon_mono_bool_info
+
 static int wm_dac_mute_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
@@ -213,9 +217,10 @@
  */
 static int wm_dac_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
+	int voices = kcontrol->private_value >> 8;
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 1;
-	uinfo->value.integer.min = 0;		/* mute */
+	uinfo->count = voices;
+	uinfo->value.integer.min = 0;		/* mute (-101dB) */
 	uinfo->value.integer.max = 101;		/* 0dB */
 	return 0;
 }
@@ -223,16 +228,20 @@
 static int wm_dac_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx;
+	int i, idx, ofs, voices;
 	unsigned short vol;
 
+	voices = kcontrol->private_value >> 8;
+	ofs = kcontrol->private_value & 0xff;
 	down(&ice->gpio_mutex);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_DAC_ATTEN;
-	vol = wm_get(ice, idx) & 0x7f;
-	if (vol <= 0x1a)
-		ucontrol->value.integer.value[0] = 0;
-	else
-		ucontrol->value.integer.value[0] = vol - 0x1a;
+	for (i = 0; i < voices; i++) {
+		idx  = WM_DAC_ATTEN + ofs + i;
+		vol = wm_get(ice, idx) & 0x7f;
+		if (vol <= 0x1a)
+			ucontrol->value.integer.value[i] = 0;
+		else
+			ucontrol->value.integer.value[i] = vol - 0x1a;
+	}
 	up(&ice->gpio_mutex);
 	return 0;
 }
@@ -240,34 +249,76 @@
 static int wm_dac_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx;
+	int i, idx, ofs, voices;
 	unsigned short ovol, nvol;
-	int change;
+	int change = 0;
 
+	voices = kcontrol->private_value >> 8;
+	ofs = kcontrol->private_value & 0xff;
 	snd_ice1712_save_gpio_status(ice);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_DAC_ATTEN;
-	nvol = ucontrol->value.integer.value[0] + 0x1a;
-	ovol = wm_get(ice, idx) & 0x7f;
-	change = (ovol != nvol);
-	if (change) {
-		if (nvol <= 0x1a && ovol <= 0x1a)
-			change = 0;
-		else {
+	for (i = 0; i < 2; i++) {
+		idx  = WM_DAC_ATTEN + ofs + i;
+		nvol = ucontrol->value.integer.value[i] + 0x1a;
+		ovol = wm_get(ice, idx) & 0x7f;
+		if (ovol != nvol) {
+			if (nvol <= 0x1a && ovol <= 0x1a)
+				continue;
 			wm_put(ice, idx, nvol | 0x80); /* zero-detect, prelatch */
 			wm_put_nocache(ice, idx, nvol | 0x180); /* update */
+			change = 1;
 		}
 	}
 	snd_ice1712_restore_gpio_status(ice);
 	return change;
 }
 
+/* digital master volume */
+static int wm_master_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+	uinfo->count = 1;
+	uinfo->value.integer.min = 0;		/* mute (-127.5dB) */
+	uinfo->value.integer.max = 0xff;	/* 0dB */
+	return 0;
+}
+
+static int wm_master_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned short vol;
+
+	down(&ice->gpio_mutex);
+	vol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
+	ucontrol->value.integer.value[0] = 0xff - vol;
+	up(&ice->gpio_mutex);
+	return 0;
+}
+
+static int wm_master_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
+{
+	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
+	unsigned short ovol, nvol;
+	int change = 0;
+
+	snd_ice1712_save_gpio_status(ice);
+	nvol = 0xff - ucontrol->value.integer.value[0];
+	ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
+	if (ovol != nvol) {
+		wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */
+		wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */
+		change = 1;
+	}
+	snd_ice1712_restore_gpio_status(ice);
+	return change;
+}
+
 /*
  * ADC mute control
  */
-static int wm_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t * uinfo)
+static int wm_adc_mute_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-	uinfo->count = 1;
+	uinfo->count = 2;
 	uinfo->value.integer.min = 0;
 	uinfo->value.integer.max = 1;
 	return 0;
@@ -277,10 +328,13 @@
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short val;
+	int i;
 
 	down(&ice->gpio_mutex);
-	val = wm_get(ice, snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)+WM_ADC_GAIN);
-	ucontrol->value.integer.value[0] = ~val>>5 & 0x1;
+	for (i = 0; i < 2; i++) {
+		val = wm_get(ice, WM_ADC_GAIN + i);
+		ucontrol->value.integer.value[i] = ~val>>5 & 0x1;
+	}
 	up(&ice->gpio_mutex);
 	return 0;
 }
@@ -289,14 +343,17 @@
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
 	unsigned short new, old;
-	int change;
+	int i, change = 0;
 
 	snd_ice1712_save_gpio_status(ice);
-	old = wm_get(ice, snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)+WM_ADC_GAIN);
-	new = (~ucontrol->value.integer.value[0]<<5&0x20) | (old&~0x20);
-	change = (new != old);
-	if (change)
-		wm_put(ice, snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)+WM_ADC_GAIN, new);
+	for (i = 0; i < 2; i++) {
+		old = wm_get(ice, WM_ADC_GAIN + i);
+		new = (~ucontrol->value.integer.value[i]<<5&0x20) | (old&~0x20);
+		if (new != old) {
+			wm_put(ice, snd_ctl_get_ioffidx(kcontrol, &ucontrol->id)+WM_ADC_GAIN, new);
+			change = 1;
+		}
+	}
 	snd_ice1712_restore_gpio_status(ice);
 
 	return change;
@@ -308,7 +365,7 @@
 static int wm_adc_vol_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo)
 {
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	uinfo->count = 1;
+	uinfo->count = 2;
 	uinfo->value.integer.min = 0;		/* -12dB */
 	uinfo->value.integer.max = 0x1f;	/* 19dB */
 	return 0;
@@ -317,13 +374,15 @@
 static int wm_adc_vol_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx;
+	int i, idx;
 	unsigned short vol;
 
 	down(&ice->gpio_mutex);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_ADC_GAIN;
-	vol = wm_get(ice, idx) & 0x1f;
-	ucontrol->value.integer.value[0] = vol;
+	for (i = 0; i < 2; i++) {
+		idx = WM_ADC_GAIN + i;
+		vol = wm_get(ice, idx) & 0x1f;
+		ucontrol->value.integer.value[i] = vol;
+	}
 	up(&ice->gpio_mutex);
 	return 0;
 }
@@ -331,17 +390,20 @@
 static int wm_adc_vol_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
-	int idx;
+	int i, idx;
 	unsigned short ovol, nvol;
-	int change;
+	int change = 0;
 
 	snd_ice1712_save_gpio_status(ice);
-	idx  = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + WM_ADC_GAIN;
-	nvol = ucontrol->value.integer.value[0];
-	ovol = wm_get(ice, idx);
-	change = ((ovol & 0x1f)  != nvol);
-	if (change)
-		wm_put(ice, idx, nvol | (ovol & ~0x1f));
+	for (i = 0; i < 2; i++) {
+		idx  = WM_ADC_GAIN + i;
+		nvol = ucontrol->value.integer.value[i];
+		ovol = wm_get(ice, idx);
+		if ((ovol & 0x1f) != nvol) {
+			wm_put(ice, idx, nvol | (ovol & ~0x1f));
+			change = 1;
+		}
+	}
 	snd_ice1712_restore_gpio_status(ice);
 	return change;
 }
@@ -359,7 +421,7 @@
 		"AC97"		//AIN5
 	};
 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
-	uinfo->count = 1;
+	uinfo->count = 2;
 	uinfo->value.enumerated.items = 5;
 	if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
 		uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
@@ -424,14 +486,7 @@
 	return ( tmp & AUREON_HP_SEL )!= 0;
 }
 
-static int aureon_bool_info(snd_kcontrol_t *k, snd_ctl_elem_info_t *uinfo)
-{
-	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
-	uinfo->count = 1;
-	uinfo->value.integer.min = 0;
-	uinfo->value.integer.max = 1;
-	return 0;
-}
+#define aureon_hpamp_info	aureon_mono_bool_info
 
 static int aureon_hpamp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
@@ -452,6 +507,9 @@
 /*
  * Deemphasis
  */
+
+#define aureon_deemp_info	aureon_mono_bool_info
+
 static int aureon_deemp_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol)
 {
 	ice1712_t *ice = snd_kcontrol_chip(kcontrol);
@@ -523,44 +581,67 @@
  * mixers
  */
 
-static snd_kcontrol_new_t aureon51_dac_control __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "DAC Volume",
-	.count = 6,
-	.info = wm_dac_vol_info,
-	.get = wm_dac_vol_get,
-	.put = wm_dac_vol_put,
-};
-
-static snd_kcontrol_new_t aureon71_dac_control __devinitdata = {
-	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-	.name = "DAC Volume",
-	.count = 8,
-	.info = wm_dac_vol_info,
-	.get = wm_dac_vol_get,
-	.put = wm_dac_vol_put,
-};
-
-static snd_kcontrol_new_t wm_controls[] __devinitdata = {
+static snd_kcontrol_new_t aureon_dac_controls[] __devinitdata = {
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Master Playback Switch",
-		.info = wm_dac_mute_info,
-		.get = wm_dac_mute_get,
-		.put = wm_dac_mute_put,
+		.name = "Front Playback Volume",
+		.info = wm_dac_vol_info,
+		.get = wm_dac_vol_get,
+		.put = wm_dac_vol_put,
+		.private_value = (2 << 8) | 0
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Master Playback Volume",
+		.name = "Rear Playback Volume",
+		.info = wm_dac_vol_info,
+		.get = wm_dac_vol_get,
+		.put = wm_dac_vol_put,
+		.private_value = (2 << 8) | 2
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Center Playback Volume",
 		.info = wm_dac_vol_info,
 		.get = wm_dac_vol_get,
 		.put = wm_dac_vol_put,
-		.private_value = 1,
+		.private_value = (1 << 8) | 4
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "ADC Switch",
-		.count = 2,
+		.name = "LFE Playback Volume",
+		.info = wm_dac_vol_info,
+		.get = wm_dac_vol_get,
+		.put = wm_dac_vol_put,
+		.private_value = (1 << 8) | 5
+	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Side Playback Volume",
+		.info = wm_dac_vol_info,
+		.get = wm_dac_vol_get,
+		.put = wm_dac_vol_put,
+		.private_value = (2 << 8) | 6
+	}
+};
+
+static snd_kcontrol_new_t wm_controls[] __devinitdata = {
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Switch",
+		.info = wm_dac_mute_info,
+		.get = wm_dac_mute_get,
+		.put = wm_dac_mute_put,
+ 	},
+ 	{
+ 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Master Playback Volume",
+		.info = wm_master_vol_info,
+		.get = wm_master_vol_get,
+		.put = wm_master_vol_put,
+ 	},
+	{
+		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+		.name = "Capture Switch",
 		.info = wm_adc_mute_info,
 		.get = wm_adc_mute_get,
 		.put = wm_adc_mute_put,
@@ -568,15 +649,14 @@
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "ADC Volume",
-		.count = 2,
+		.name = "Capture Volume",
 		.info = wm_adc_vol_info,
 		.get = wm_adc_vol_get,
 		.put = wm_adc_vol_put,
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
-		.name = "Capture Route",
+		.name = "Capture Source",
 		.info = wm_adc_mux_info,
 		.get = wm_adc_mux_get,
 		.put = wm_adc_mux_put,
@@ -584,14 +664,14 @@
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "Headphone Amplifier Switch",
-		.info = aureon_bool_info,
+		.info = aureon_hpamp_info,
 		.get = aureon_hpamp_get,
 		.put = aureon_hpamp_put
 	},
 	{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name = "DAC Deemphasis Switch",
-		.info = aureon_bool_info,
+		.info = aureon_deemp_info,
 		.get = aureon_deemp_get,
 		.put = aureon_deemp_put
 	},
@@ -607,15 +687,17 @@
 
 static int __devinit aureon_add_controls(ice1712_t *ice)
 {
-	unsigned int i;
+	unsigned int i, counts;
 	int err;
 
+	counts = ARRAY_SIZE(aureon_dac_controls);
 	if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY)
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon51_dac_control, ice));
-	else
-		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon71_dac_control, ice));
-	if (err < 0)
-		return err;
+		counts--; /* no side */
+	for (i = 0; i < counts; i++) {
+		err = snd_ctl_add(ice->card, snd_ctl_new1(&aureon_dac_controls[i], ice));
+		if (err < 0)
+			return err;
+	}
 
 	for (i = 0; i < ARRAY_SIZE(wm_controls); i++) {
 		err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice));

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

end of thread, other threads:[~2004-07-16  9:43 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-03 15:46 [PATCH] aureon.c - adc mux, master vol Christoph Haderer
2004-07-05 10:00 ` Takashi Iwai
2004-07-07  1:05   ` Apostolos Dimitromanolakis
2004-07-15 15:39     ` Takashi Iwai
2004-07-15 17:40       ` Apostolos Dimitromanolakis
2004-07-16  9:43         ` Takashi Iwai

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.