aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ice1712
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-31 18:16:28 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-31 18:16:28 -0500
commite1a9c9872dd004617555dff079b357a6ffd945e9 (patch)
treec34779e59712ff345f8e4ee97e74086a85b34974 /sound/pci/ice1712
parentfcc3ff4f9d695a80dc6e6058e0d631a3026ed4c3 (diff)
parent2ecba4ffbbc6c85fce8c3878514be415edace413 (diff)
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/perex/alsa
* 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/perex/alsa: (299 commits) [ALSA] version 1.0.16rc2 [ALSA] hda: fix Mic in as output [ALSA] emu10k1 - Another EMU0404 Board ID [ALSA] emu10k1 - Fix kthread handling at resume [ALSA] emu10k1: General cleanup, add new locks, fix alsa bug#3501, kernel bug#9304. [ALSA] emu10k1 - Use enum for emu_model types [ALSA] emu10k1 - Don't create emu1010 controls for non-emu boards [ALSA] emu10k1 - 1616(M) cardbus improvements [ALSA] snd:emu10k1: E-Mu updates. Fixes to firmware loading and support for 0404. [ALSA] emu10k1: Add comments regarding E-Mu ins and outs. [ALSA] oxygen: revert SPI clock frequency change for AK4396/WM8785 [ALSA] es1938 - improve capture hw pointer reads [ALSA] HDA-Intel - Add support for Intel SCH [ALSA] hda: Add GPIO mute support to STAC9205 [ALSA] hda-codec - Add Dell T3400 support [ALSA] hda-codec - Add model for HP DV9553EG laptop [ALSA] hda-codec - Control SPDIF as slave [ALSA] hda_intel: ALSA HD Audio patch for Intel ICH10 DeviceID's [ALSA] Fix Oops with PCM OSS sync [ALSA] hda-codec - Add speaker automute to ALC262 HP models ...
Diffstat (limited to 'sound/pci/ice1712')
-rw-r--r--sound/pci/ice1712/Makefile2
-rw-r--r--sound/pci/ice1712/ak4xxx.c1
-rw-r--r--sound/pci/ice1712/amp.c1
-rw-r--r--sound/pci/ice1712/aureon.c133
-rw-r--r--sound/pci/ice1712/delta.c3
-rw-r--r--sound/pci/ice1712/ews.c92
-rw-r--r--sound/pci/ice1712/hoontech.c188
-rw-r--r--sound/pci/ice1712/ice1712.c2
-rw-r--r--sound/pci/ice1712/ice1712.h37
-rw-r--r--sound/pci/ice1712/ice1724.c9
-rw-r--r--sound/pci/ice1712/juli.c23
-rw-r--r--sound/pci/ice1712/phase.c96
-rw-r--r--sound/pci/ice1712/pontis.c1
-rw-r--r--sound/pci/ice1712/prodigy192.c297
-rw-r--r--sound/pci/ice1712/prodigy_hifi.c1210
-rw-r--r--sound/pci/ice1712/prodigy_hifi.h38
-rw-r--r--sound/pci/ice1712/revo.c24
-rw-r--r--sound/pci/ice1712/se.c774
-rw-r--r--sound/pci/ice1712/se.h15
-rw-r--r--sound/pci/ice1712/vt1720_mobo.c1
-rw-r--r--sound/pci/ice1712/wtm.c9
21 files changed, 2547 insertions, 409 deletions
diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
index 65ce66adba5a..f99fe089495d 100644
--- a/sound/pci/ice1712/Makefile
+++ b/sound/pci/ice1712/Makefile
@@ -5,7 +5,7 @@
5 5
6snd-ice17xx-ak4xxx-objs := ak4xxx.o 6snd-ice17xx-ak4xxx-objs := ak4xxx.o
7snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o 7snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o
8snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o juli.o phase.o wtm.o 8snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o prodigy_hifi.o juli.o phase.o wtm.o se.o
9 9
10# Toplevel Module Dependency 10# Toplevel Module Dependency
11obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o 11obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o
diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c
index a1aba0d7d0e4..dab31b2756a6 100644
--- a/sound/pci/ice1712/ak4xxx.c
+++ b/sound/pci/ice1712/ak4xxx.c
@@ -21,7 +21,6 @@
21 * 21 *
22 */ 22 */
23 23
24#include <sound/driver.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c
index 6e13d758bb5d..37564300b50d 100644
--- a/sound/pci/ice1712/amp.c
+++ b/sound/pci/ice1712/amp.c
@@ -21,7 +21,6 @@
21 * 21 *
22 */ 22 */
23 23
24#include <sound/driver.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index ec0699c89952..868ae291b960 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -47,7 +47,6 @@
47 * 47 *
48 */ 48 */
49 49
50#include <sound/driver.h>
51#include <asm/io.h> 50#include <asm/io.h>
52#include <linux/delay.h> 51#include <linux/delay.h>
53#include <linux/interrupt.h> 52#include <linux/interrupt.h>
@@ -62,6 +61,15 @@
62#include "aureon.h" 61#include "aureon.h"
63#include <sound/tlv.h> 62#include <sound/tlv.h>
64 63
64/* AC97 register cache for Aureon */
65struct aureon_spec {
66 unsigned short stac9744[64];
67 unsigned int cs8415_mux;
68 unsigned short master[2];
69 unsigned short vol[8];
70 unsigned char pca9554_out;
71};
72
65/* WM8770 registers */ 73/* WM8770 registers */
66#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */ 74#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
67#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */ 75#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
@@ -205,7 +213,8 @@ static int aureon_universe_inmux_get(struct snd_kcontrol *kcontrol,
205 struct snd_ctl_elem_value *ucontrol) 213 struct snd_ctl_elem_value *ucontrol)
206{ 214{
207 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 215 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
208 ucontrol->value.integer.value[0] = ice->spec.aureon.pca9554_out; 216 struct aureon_spec *spec = ice->spec;
217 ucontrol->value.enumerated.item[0] = spec->pca9554_out;
209 return 0; 218 return 0;
210} 219}
211 220
@@ -213,16 +222,18 @@ static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
213 struct snd_ctl_elem_value *ucontrol) 222 struct snd_ctl_elem_value *ucontrol)
214{ 223{
215 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 224 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
225 struct aureon_spec *spec = ice->spec;
216 unsigned char oval, nval; 226 unsigned char oval, nval;
217 int change; 227 int change;
218 228
229 nval = ucontrol->value.enumerated.item[0];
230 if (nval >= 3)
231 return -EINVAL;
219 snd_ice1712_save_gpio_status(ice); 232 snd_ice1712_save_gpio_status(ice);
220 233 oval = spec->pca9554_out;
221 oval = ice->spec.aureon.pca9554_out;
222 nval = ucontrol->value.integer.value[0];
223 if ((change = (oval != nval))) { 234 if ((change = (oval != nval))) {
224 aureon_pca9554_write(ice, PCA9554_OUT, nval); 235 aureon_pca9554_write(ice, PCA9554_OUT, nval);
225 ice->spec.aureon.pca9554_out = nval; 236 spec->pca9554_out = nval;
226 } 237 }
227 snd_ice1712_restore_gpio_status(ice); 238 snd_ice1712_restore_gpio_status(ice);
228 239
@@ -233,6 +244,7 @@ static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol,
233static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, 244static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
234 unsigned short val) 245 unsigned short val)
235{ 246{
247 struct aureon_spec *spec = ice->spec;
236 unsigned int tmp; 248 unsigned int tmp;
237 249
238 /* Send address to XILINX chip */ 250 /* Send address to XILINX chip */
@@ -280,12 +292,13 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg,
280 udelay(10); 292 udelay(10);
281 293
282 /* Store the data in out private buffer */ 294 /* Store the data in out private buffer */
283 ice->spec.aureon.stac9744[(reg & 0x7F) >> 1] = val; 295 spec->stac9744[(reg & 0x7F) >> 1] = val;
284} 296}
285 297
286static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg) 298static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short reg)
287{ 299{
288 return ice->spec.aureon.stac9744[(reg & 0x7F) >> 1]; 300 struct aureon_spec *spec = ice->spec;
301 return spec->stac9744[(reg & 0x7F) >> 1];
289} 302}
290 303
291/* 304/*
@@ -293,6 +306,7 @@ static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short r
293 */ 306 */
294static int aureon_ac97_init (struct snd_ice1712 *ice) 307static int aureon_ac97_init (struct snd_ice1712 *ice)
295{ 308{
309 struct aureon_spec *spec = ice->spec;
296 int i; 310 int i;
297 static const unsigned short ac97_defaults[] = { 311 static const unsigned short ac97_defaults[] = {
298 0x00, 0x9640, 312 0x00, 0x9640,
@@ -330,9 +344,9 @@ static int aureon_ac97_init (struct snd_ice1712 *ice)
330 snd_ice1712_gpio_write(ice, tmp); 344 snd_ice1712_gpio_write(ice, tmp);
331 udelay(3); 345 udelay(3);
332 346
333 memset(&ice->spec.aureon.stac9744, 0, sizeof(ice->spec.aureon.stac9744)); 347 memset(&spec->stac9744, 0, sizeof(spec->stac9744));
334 for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2) 348 for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2)
335 ice->spec.aureon.stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1]; 349 spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1];
336 350
337 aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770 351 aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770
338 352
@@ -744,27 +758,33 @@ static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
744static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 758static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
745{ 759{
746 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 760 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
761 struct aureon_spec *spec = ice->spec;
747 int i; 762 int i;
748 for (i=0; i<2; i++) 763 for (i=0; i<2; i++)
749 ucontrol->value.integer.value[i] = ice->spec.aureon.master[i] & ~WM_VOL_MUTE; 764 ucontrol->value.integer.value[i] =
765 spec->master[i] & ~WM_VOL_MUTE;
750 return 0; 766 return 0;
751} 767}
752 768
753static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 769static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
754{ 770{
755 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 771 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
772 struct aureon_spec *spec = ice->spec;
756 int ch, change = 0; 773 int ch, change = 0;
757 774
758 snd_ice1712_save_gpio_status(ice); 775 snd_ice1712_save_gpio_status(ice);
759 for (ch = 0; ch < 2; ch++) { 776 for (ch = 0; ch < 2; ch++) {
760 if (ucontrol->value.integer.value[ch] != ice->spec.aureon.master[ch]) { 777 unsigned int vol = ucontrol->value.integer.value[ch];
778 if (vol > WM_VOL_MAX)
779 continue;
780 vol |= spec->master[ch] & WM_VOL_MUTE;
781 if (vol != spec->master[ch]) {
761 int dac; 782 int dac;
762 ice->spec.aureon.master[ch] &= WM_VOL_MUTE; 783 spec->master[ch] = vol;
763 ice->spec.aureon.master[ch] |= ucontrol->value.integer.value[ch];
764 for (dac = 0; dac < ice->num_total_dacs; dac += 2) 784 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
765 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch, 785 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
766 ice->spec.aureon.vol[dac + ch], 786 spec->vol[dac + ch],
767 ice->spec.aureon.master[ch]); 787 spec->master[ch]);
768 change = 1; 788 change = 1;
769 } 789 }
770 } 790 }
@@ -788,18 +808,21 @@ static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *
788static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 808static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
789{ 809{
790 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 810 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
811 struct aureon_spec *spec = ice->spec;
791 int i, ofs, voices; 812 int i, ofs, voices;
792 813
793 voices = kcontrol->private_value >> 8; 814 voices = kcontrol->private_value >> 8;
794 ofs = kcontrol->private_value & 0xff; 815 ofs = kcontrol->private_value & 0xff;
795 for (i = 0; i < voices; i++) 816 for (i = 0; i < voices; i++)
796 ucontrol->value.integer.value[i] = ice->spec.aureon.vol[ofs+i] & ~WM_VOL_MUTE; 817 ucontrol->value.integer.value[i] =
818 spec->vol[ofs+i] & ~WM_VOL_MUTE;
797 return 0; 819 return 0;
798} 820}
799 821
800static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 822static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
801{ 823{
802 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 824 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
825 struct aureon_spec *spec = ice->spec;
803 int i, idx, ofs, voices; 826 int i, idx, ofs, voices;
804 int change = 0; 827 int change = 0;
805 828
@@ -807,12 +830,15 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
807 ofs = kcontrol->private_value & 0xff; 830 ofs = kcontrol->private_value & 0xff;
808 snd_ice1712_save_gpio_status(ice); 831 snd_ice1712_save_gpio_status(ice);
809 for (i = 0; i < voices; i++) { 832 for (i = 0; i < voices; i++) {
810 idx = WM_DAC_ATTEN + ofs + i; 833 unsigned int vol = ucontrol->value.integer.value[i];
811 if (ucontrol->value.integer.value[i] != ice->spec.aureon.vol[ofs+i]) { 834 if (vol > 0x7f)
812 ice->spec.aureon.vol[ofs+i] &= WM_VOL_MUTE; 835 continue;
813 ice->spec.aureon.vol[ofs+i] |= ucontrol->value.integer.value[i]; 836 vol |= spec->vol[ofs+i];
814 wm_set_vol(ice, idx, ice->spec.aureon.vol[ofs+i], 837 if (vol != spec->vol[ofs+i]) {
815 ice->spec.aureon.master[i]); 838 spec->vol[ofs+i] = vol;
839 idx = WM_DAC_ATTEN + ofs + i;
840 wm_set_vol(ice, idx, spec->vol[ofs + i],
841 spec->master[i]);
816 change = 1; 842 change = 1;
817 } 843 }
818 } 844 }
@@ -834,19 +860,22 @@ static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info
834static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 860static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
835{ 861{
836 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 862 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
863 struct aureon_spec *spec = ice->spec;
837 int voices, ofs, i; 864 int voices, ofs, i;
838 865
839 voices = kcontrol->private_value >> 8; 866 voices = kcontrol->private_value >> 8;
840 ofs = kcontrol->private_value & 0xFF; 867 ofs = kcontrol->private_value & 0xFF;
841 868
842 for (i = 0; i < voices; i++) 869 for (i = 0; i < voices; i++)
843 ucontrol->value.integer.value[i] = (ice->spec.aureon.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1; 870 ucontrol->value.integer.value[i] =
871 (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
844 return 0; 872 return 0;
845} 873}
846 874
847static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 875static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
848{ 876{
849 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 877 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
878 struct aureon_spec *spec = ice->spec;
850 int change = 0, voices, ofs, i; 879 int change = 0, voices, ofs, i;
851 880
852 voices = kcontrol->private_value >> 8; 881 voices = kcontrol->private_value >> 8;
@@ -854,13 +883,13 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
854 883
855 snd_ice1712_save_gpio_status(ice); 884 snd_ice1712_save_gpio_status(ice);
856 for (i = 0; i < voices; i++) { 885 for (i = 0; i < voices; i++) {
857 int val = (ice->spec.aureon.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1; 886 int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
858 if (ucontrol->value.integer.value[i] != val) { 887 if (ucontrol->value.integer.value[i] != val) {
859 ice->spec.aureon.vol[ofs + i] &= ~WM_VOL_MUTE; 888 spec->vol[ofs + i] &= ~WM_VOL_MUTE;
860 ice->spec.aureon.vol[ofs + i] |= 889 spec->vol[ofs + i] |=
861 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; 890 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
862 wm_set_vol(ice, ofs + i, ice->spec.aureon.vol[ofs + i], 891 wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
863 ice->spec.aureon.master[i]); 892 spec->master[i]);
864 change = 1; 893 change = 1;
865 } 894 }
866 } 895 }
@@ -877,29 +906,33 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
877static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 906static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
878{ 907{
879 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 908 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
909 struct aureon_spec *spec = ice->spec;
880 910
881 ucontrol->value.integer.value[0] = (ice->spec.aureon.master[0] & WM_VOL_MUTE) ? 0 : 1; 911 ucontrol->value.integer.value[0] =
882 ucontrol->value.integer.value[1] = (ice->spec.aureon.master[1] & WM_VOL_MUTE) ? 0 : 1; 912 (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
913 ucontrol->value.integer.value[1] =
914 (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
883 return 0; 915 return 0;
884} 916}
885 917
886static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 918static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
887{ 919{
888 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 920 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
921 struct aureon_spec *spec = ice->spec;
889 int change = 0, i; 922 int change = 0, i;
890 923
891 snd_ice1712_save_gpio_status(ice); 924 snd_ice1712_save_gpio_status(ice);
892 for (i = 0; i < 2; i++) { 925 for (i = 0; i < 2; i++) {
893 int val = (ice->spec.aureon.master[i] & WM_VOL_MUTE) ? 0 : 1; 926 int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
894 if (ucontrol->value.integer.value[i] != val) { 927 if (ucontrol->value.integer.value[i] != val) {
895 int dac; 928 int dac;
896 ice->spec.aureon.master[i] &= ~WM_VOL_MUTE; 929 spec->master[i] &= ~WM_VOL_MUTE;
897 ice->spec.aureon.master[i] |= 930 spec->master[i] |=
898 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; 931 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
899 for (dac = 0; dac < ice->num_total_dacs; dac += 2) 932 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
900 wm_set_vol(ice, WM_DAC_ATTEN + dac + i, 933 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
901 ice->spec.aureon.vol[dac + i], 934 spec->vol[dac + i],
902 ice->spec.aureon.master[i]); 935 spec->master[i]);
903 change = 1; 936 change = 1;
904 } 937 }
905 } 938 }
@@ -940,8 +973,10 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
940 unsigned short ovol, nvol; 973 unsigned short ovol, nvol;
941 int change = 0; 974 int change = 0;
942 975
943 snd_ice1712_save_gpio_status(ice);
944 nvol = ucontrol->value.integer.value[0]; 976 nvol = ucontrol->value.integer.value[0];
977 if (nvol > PCM_RES)
978 return -EINVAL;
979 snd_ice1712_save_gpio_status(ice);
945 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff; 980 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
946 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; 981 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
947 if (ovol != nvol) { 982 if (ovol != nvol) {
@@ -1031,7 +1066,7 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
1031 snd_ice1712_save_gpio_status(ice); 1066 snd_ice1712_save_gpio_status(ice);
1032 for (i = 0; i < 2; i++) { 1067 for (i = 0; i < 2; i++) {
1033 idx = WM_ADC_GAIN + i; 1068 idx = WM_ADC_GAIN + i;
1034 nvol = ucontrol->value.integer.value[i]; 1069 nvol = ucontrol->value.integer.value[i] & 0x1f;
1035 ovol = wm_get(ice, idx); 1070 ovol = wm_get(ice, idx);
1036 if ((ovol & 0x1f) != nvol) { 1071 if ((ovol & 0x1f) != nvol) {
1037 wm_put(ice, idx, nvol | (ovol & ~0x1f)); 1072 wm_put(ice, idx, nvol | (ovol & ~0x1f));
@@ -1143,10 +1178,11 @@ static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_
1143static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1178static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1144{ 1179{
1145 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1180 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1181 struct aureon_spec *spec = ice->spec;
1146 1182
1147 //snd_ice1712_save_gpio_status(ice); 1183 //snd_ice1712_save_gpio_status(ice);
1148 //val = aureon_cs8415_get(ice, CS8415_CTRL2); 1184 //val = aureon_cs8415_get(ice, CS8415_CTRL2);
1149 ucontrol->value.enumerated.item[0] = ice->spec.aureon.cs8415_mux; 1185 ucontrol->value.enumerated.item[0] = spec->cs8415_mux;
1150 //snd_ice1712_restore_gpio_status(ice); 1186 //snd_ice1712_restore_gpio_status(ice);
1151 return 0; 1187 return 0;
1152} 1188}
@@ -1154,6 +1190,7 @@ static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1154static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 1190static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1155{ 1191{
1156 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1192 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1193 struct aureon_spec *spec = ice->spec;
1157 unsigned short oval, nval; 1194 unsigned short oval, nval;
1158 int change; 1195 int change;
1159 1196
@@ -1165,7 +1202,7 @@ static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
1165 if (change) 1202 if (change)
1166 aureon_cs8415_put(ice, CS8415_CTRL2, nval); 1203 aureon_cs8415_put(ice, CS8415_CTRL2, nval);
1167 snd_ice1712_restore_gpio_status(ice); 1204 snd_ice1712_restore_gpio_status(ice);
1168 ice->spec.aureon.cs8415_mux = ucontrol->value.enumerated.item[0]; 1205 spec->cs8415_mux = ucontrol->value.enumerated.item[0];
1169 return change; 1206 return change;
1170} 1207}
1171 1208
@@ -2001,10 +2038,16 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2001 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */ 2038 0x0605, /* slave, 24bit, MSB on second OSCLK, SDOUT for right channel when OLRCK is high */
2002 (unsigned short)-1 2039 (unsigned short)-1
2003 }; 2040 };
2041 struct aureon_spec *spec;
2004 unsigned int tmp; 2042 unsigned int tmp;
2005 const unsigned short *p; 2043 const unsigned short *p;
2006 int err, i; 2044 int err, i;
2007 2045
2046 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2047 if (!spec)
2048 return -ENOMEM;
2049 ice->spec = spec;
2050
2008 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) { 2051 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
2009 ice->num_total_dacs = 6; 2052 ice->num_total_dacs = 6;
2010 ice->num_total_adcs = 2; 2053 ice->num_total_adcs = 2;
@@ -2055,7 +2098,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2055 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) { 2098 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
2056 for (p = cs_inits; *p != (unsigned short)-1; p++) 2099 for (p = cs_inits; *p != (unsigned short)-1; p++)
2057 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24); 2100 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2058 ice->spec.aureon.cs8415_mux = 1; 2101 spec->cs8415_mux = 1;
2059 2102
2060 aureon_set_headphone_amp(ice, 1); 2103 aureon_set_headphone_amp(ice, 1);
2061 } 2104 }
@@ -2066,11 +2109,11 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2066 aureon_pca9554_write(ice, PCA9554_DIR, 0x00); 2109 aureon_pca9554_write(ice, PCA9554_DIR, 0x00);
2067 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */ 2110 aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */
2068 2111
2069 ice->spec.aureon.master[0] = WM_VOL_MUTE; 2112 spec->master[0] = WM_VOL_MUTE;
2070 ice->spec.aureon.master[1] = WM_VOL_MUTE; 2113 spec->master[1] = WM_VOL_MUTE;
2071 for (i = 0; i < ice->num_total_dacs; i++) { 2114 for (i = 0; i < ice->num_total_dacs; i++) {
2072 ice->spec.aureon.vol[i] = WM_VOL_MUTE; 2115 spec->vol[i] = WM_VOL_MUTE;
2073 wm_set_vol(ice, i, ice->spec.aureon.vol[i], ice->spec.aureon.master[i % 2]); 2116 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
2074 } 2117 }
2075 2118
2076 return 0; 2119 return 0;
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 371f78461db4..efd180b40e56 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -22,7 +22,6 @@
22 * 22 *
23 */ 23 */
24 24
25#include <sound/driver.h>
26#include <asm/io.h> 25#include <asm/io.h>
27#include <linux/delay.h> 26#include <linux/delay.h>
28#include <linux/interrupt.h> 27#include <linux/interrupt.h>
@@ -405,7 +404,7 @@ static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kco
405 if (snd_i2c_sendbytes(ice->cs8427, &reg, 1) != 1) 404 if (snd_i2c_sendbytes(ice->cs8427, &reg, 1) != 1)
406 snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg); 405 snd_printk(KERN_ERR "unable to send register 0x%x byte to CS8427\n", reg);
407 snd_i2c_readbytes(ice->cs8427, &reg, 1); 406 snd_i2c_readbytes(ice->cs8427, &reg, 1);
408 ucontrol->value.integer.value[0] = (reg ? 1 : 0); 407 ucontrol->value.integer.value[0] = (reg & CS8427_UNLOCK) ? 1 : 0;
409 return 0; 408 return 0;
410} 409}
411 410
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index 75e4e5e0f1e4..064760d2a027 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -22,7 +22,6 @@
22 * 22 *
23 */ 23 */
24 24
25#include <sound/driver.h>
26#include <asm/io.h> 25#include <asm/io.h>
27#include <linux/delay.h> 26#include <linux/delay.h>
28#include <linux/interrupt.h> 27#include <linux/interrupt.h>
@@ -45,6 +44,11 @@ enum {
45}; 44};
46 45
47 46
47/* additional i2c devices for EWS boards */
48struct ews_spec {
49 struct snd_i2c_device *i2cdevs[3];
50};
51
48/* 52/*
49 * access via i2c mode (for EWX 24/96, EWS 88MT&D) 53 * access via i2c mode (for EWX 24/96, EWS 88MT&D)
50 */ 54 */
@@ -142,15 +146,17 @@ static struct snd_i2c_bit_ops snd_ice1712_ewx_cs8427_bit_ops = {
142/* AK4524 chip select; address 0x48 bit 0-3 */ 146/* AK4524 chip select; address 0x48 bit 0-3 */
143static int snd_ice1712_ews88mt_chip_select(struct snd_ice1712 *ice, int chip_mask) 147static int snd_ice1712_ews88mt_chip_select(struct snd_ice1712 *ice, int chip_mask)
144{ 148{
149 struct ews_spec *spec = ice->spec;
145 unsigned char data, ndata; 150 unsigned char data, ndata;
146 151
147 snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return -EINVAL); 152 snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return -EINVAL);
148 snd_i2c_lock(ice->i2c); 153 snd_i2c_lock(ice->i2c);
149 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) 154 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1)
150 goto __error; 155 goto __error;
151 ndata = (data & 0xf0) | chip_mask; 156 ndata = (data & 0xf0) | chip_mask;
152 if (ndata != data) 157 if (ndata != data)
153 if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1) 158 if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF2], &ndata, 1)
159 != 1)
154 goto __error; 160 goto __error;
155 snd_i2c_unlock(ice->i2c); 161 snd_i2c_unlock(ice->i2c);
156 return 0; 162 return 0;
@@ -224,6 +230,7 @@ static void dmx6fire_ak4524_lock(struct snd_akm4xxx *ak, int chip)
224 230
225static void snd_ice1712_ews_cs8404_spdif_write(struct snd_ice1712 *ice, unsigned char bits) 231static void snd_ice1712_ews_cs8404_spdif_write(struct snd_ice1712 *ice, unsigned char bits)
226{ 232{
233 struct ews_spec *spec = ice->spec;
227 unsigned char bytes[2]; 234 unsigned char bytes[2];
228 235
229 snd_i2c_lock(ice->i2c); 236 snd_i2c_lock(ice->i2c);
@@ -231,15 +238,18 @@ static void snd_ice1712_ews_cs8404_spdif_write(struct snd_ice1712 *ice, unsigned
231 case ICE1712_SUBDEVICE_EWS88MT: 238 case ICE1712_SUBDEVICE_EWS88MT:
232 case ICE1712_SUBDEVICE_EWS88MT_NEW: 239 case ICE1712_SUBDEVICE_EWS88MT_NEW:
233 case ICE1712_SUBDEVICE_PHASE88: 240 case ICE1712_SUBDEVICE_PHASE88:
234 if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_CS8404], &bits, 1) != 1) 241 if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_CS8404], &bits, 1)
242 != 1)
235 goto _error; 243 goto _error;
236 break; 244 break;
237 case ICE1712_SUBDEVICE_EWS88D: 245 case ICE1712_SUBDEVICE_EWS88D:
238 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], bytes, 2) != 2) 246 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], bytes, 2)
247 != 2)
239 goto _error; 248 goto _error;
240 if (bits != bytes[1]) { 249 if (bits != bytes[1]) {
241 bytes[1] = bits; 250 bytes[1] = bits;
242 if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], bytes, 2) != 2) 251 if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D],
252 bytes, 2) != 2)
243 goto _error; 253 goto _error;
244 } 254 }
245 break; 255 break;
@@ -412,6 +422,7 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
412{ 422{
413 int err; 423 int err;
414 struct snd_akm4xxx *ak; 424 struct snd_akm4xxx *ak;
425 struct ews_spec *spec;
415 426
416 /* set the analog DACs */ 427 /* set the analog DACs */
417 switch (ice->eeprom.subvendor) { 428 switch (ice->eeprom.subvendor) {
@@ -436,6 +447,11 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
436 break; 447 break;
437 } 448 }
438 449
450 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
451 if (!spec)
452 return -ENOMEM;
453 ice->spec = spec;
454
439 /* create i2c */ 455 /* create i2c */
440 if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) { 456 if ((err = snd_i2c_bus_create(ice->card, "ICE1712 GPIO 1", NULL, &ice->i2c)) < 0) {
441 snd_printk(KERN_ERR "unable to create I2C bus\n"); 457 snd_printk(KERN_ERR "unable to create I2C bus\n");
@@ -447,7 +463,10 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
447 /* create i2c devices */ 463 /* create i2c devices */
448 switch (ice->eeprom.subvendor) { 464 switch (ice->eeprom.subvendor) {
449 case ICE1712_SUBDEVICE_DMX6FIRE: 465 case ICE1712_SUBDEVICE_DMX6FIRE:
450 if ((err = snd_i2c_device_create(ice->i2c, "PCF9554", ICE1712_6FIRE_PCF9554_ADDR, &ice->spec.i2cdevs[EWS_I2C_6FIRE])) < 0) { 466 err = snd_i2c_device_create(ice->i2c, "PCF9554",
467 ICE1712_6FIRE_PCF9554_ADDR,
468 &spec->i2cdevs[EWS_I2C_6FIRE]);
469 if (err < 0) {
451 snd_printk(KERN_ERR "PCF9554 initialization failed\n"); 470 snd_printk(KERN_ERR "PCF9554 initialization failed\n");
452 return err; 471 return err;
453 } 472 }
@@ -456,18 +475,30 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
456 case ICE1712_SUBDEVICE_EWS88MT: 475 case ICE1712_SUBDEVICE_EWS88MT:
457 case ICE1712_SUBDEVICE_EWS88MT_NEW: 476 case ICE1712_SUBDEVICE_EWS88MT_NEW:
458 case ICE1712_SUBDEVICE_PHASE88: 477 case ICE1712_SUBDEVICE_PHASE88:
459 if ((err = snd_i2c_device_create(ice->i2c, "CS8404", ICE1712_EWS88MT_CS8404_ADDR, &ice->spec.i2cdevs[EWS_I2C_CS8404])) < 0) 478 err = snd_i2c_device_create(ice->i2c, "CS8404",
479 ICE1712_EWS88MT_CS8404_ADDR,
480 &spec->i2cdevs[EWS_I2C_CS8404]);
481 if (err < 0)
460 return err; 482 return err;
461 if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)", ICE1712_EWS88MT_INPUT_ADDR, &ice->spec.i2cdevs[EWS_I2C_PCF1])) < 0) 483 err = snd_i2c_device_create(ice->i2c, "PCF8574 (1st)",
484 ICE1712_EWS88MT_INPUT_ADDR,
485 &spec->i2cdevs[EWS_I2C_PCF1]);
486 if (err < 0)
462 return err; 487 return err;
463 if ((err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)", ICE1712_EWS88MT_OUTPUT_ADDR, &ice->spec.i2cdevs[EWS_I2C_PCF2])) < 0) 488 err = snd_i2c_device_create(ice->i2c, "PCF8574 (2nd)",
489 ICE1712_EWS88MT_OUTPUT_ADDR,
490 &spec->i2cdevs[EWS_I2C_PCF2]);
491 if (err < 0)
464 return err; 492 return err;
465 /* Check if the front module is connected */ 493 /* Check if the front module is connected */
466 if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0) 494 if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0)
467 return err; 495 return err;
468 break; 496 break;
469 case ICE1712_SUBDEVICE_EWS88D: 497 case ICE1712_SUBDEVICE_EWS88D:
470 if ((err = snd_i2c_device_create(ice->i2c, "PCF8575", ICE1712_EWS88D_PCF_ADDR, &ice->spec.i2cdevs[EWS_I2C_88D])) < 0) 498 err = snd_i2c_device_create(ice->i2c, "PCF8575",
499 ICE1712_EWS88D_PCF_ADDR,
500 &spec->i2cdevs[EWS_I2C_88D]);
501 if (err < 0)
471 return err; 502 return err;
472 break; 503 break;
473 } 504 }
@@ -507,7 +538,7 @@ static int __devinit snd_ice1712_ews_init(struct snd_ice1712 *ice)
507 } 538 }
508 539
509 /* analog section */ 540 /* analog section */
510 ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); 541 ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
511 if (! ak) 542 if (! ak)
512 return -ENOMEM; 543 return -ENOMEM;
513 ice->akm_codecs = 1; 544 ice->akm_codecs = 1;
@@ -605,10 +636,11 @@ static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
605static int snd_ice1712_ews88mt_output_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 636static int snd_ice1712_ews88mt_output_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
606{ 637{
607 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 638 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
639 struct ews_spec *spec = ice->spec;
608 unsigned char data; 640 unsigned char data;
609 641
610 snd_i2c_lock(ice->i2c); 642 snd_i2c_lock(ice->i2c);
611 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) { 643 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
612 snd_i2c_unlock(ice->i2c); 644 snd_i2c_unlock(ice->i2c);
613 return -EIO; 645 return -EIO;
614 } 646 }
@@ -621,15 +653,17 @@ static int snd_ice1712_ews88mt_output_sense_get(struct snd_kcontrol *kcontrol, s
621static int snd_ice1712_ews88mt_output_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 653static int snd_ice1712_ews88mt_output_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
622{ 654{
623 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 655 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
656 struct ews_spec *spec = ice->spec;
624 unsigned char data, ndata; 657 unsigned char data, ndata;
625 658
626 snd_i2c_lock(ice->i2c); 659 snd_i2c_lock(ice->i2c);
627 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) { 660 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) {
628 snd_i2c_unlock(ice->i2c); 661 snd_i2c_unlock(ice->i2c);
629 return -EIO; 662 return -EIO;
630 } 663 }
631 ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0); 664 ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0);
632 if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF2], &ndata, 1) != 1) { 665 if (ndata != data && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF2],
666 &ndata, 1) != 1) {
633 snd_i2c_unlock(ice->i2c); 667 snd_i2c_unlock(ice->i2c);
634 return -EIO; 668 return -EIO;
635 } 669 }
@@ -641,12 +675,13 @@ static int snd_ice1712_ews88mt_output_sense_put(struct snd_kcontrol *kcontrol, s
641static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 675static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
642{ 676{
643 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 677 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
678 struct ews_spec *spec = ice->spec;
644 int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 679 int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
645 unsigned char data; 680 unsigned char data;
646 681
647 snd_assert(channel >= 0 && channel <= 7, return 0); 682 snd_assert(channel >= 0 && channel <= 7, return 0);
648 snd_i2c_lock(ice->i2c); 683 snd_i2c_lock(ice->i2c);
649 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) { 684 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
650 snd_i2c_unlock(ice->i2c); 685 snd_i2c_unlock(ice->i2c);
651 return -EIO; 686 return -EIO;
652 } 687 }
@@ -660,17 +695,19 @@ static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, st
660static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 695static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
661{ 696{
662 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 697 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
698 struct ews_spec *spec = ice->spec;
663 int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 699 int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
664 unsigned char data, ndata; 700 unsigned char data, ndata;
665 701
666 snd_assert(channel >= 0 && channel <= 7, return 0); 702 snd_assert(channel >= 0 && channel <= 7, return 0);
667 snd_i2c_lock(ice->i2c); 703 snd_i2c_lock(ice->i2c);
668 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) { 704 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) {
669 snd_i2c_unlock(ice->i2c); 705 snd_i2c_unlock(ice->i2c);
670 return -EIO; 706 return -EIO;
671 } 707 }
672 ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel)); 708 ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel));
673 if (ndata != data && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_PCF1], &ndata, 1) != 1) { 709 if (ndata != data && snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_PCF1],
710 &ndata, 1) != 1) {
674 snd_i2c_unlock(ice->i2c); 711 snd_i2c_unlock(ice->i2c);
675 return -EIO; 712 return -EIO;
676 } 713 }
@@ -705,12 +742,13 @@ static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata =
705static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 742static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
706{ 743{
707 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 744 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
745 struct ews_spec *spec = ice->spec;
708 int shift = kcontrol->private_value & 0xff; 746 int shift = kcontrol->private_value & 0xff;
709 int invert = (kcontrol->private_value >> 8) & 1; 747 int invert = (kcontrol->private_value >> 8) & 1;
710 unsigned char data[2]; 748 unsigned char data[2];
711 749
712 snd_i2c_lock(ice->i2c); 750 snd_i2c_lock(ice->i2c);
713 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) { 751 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
714 snd_i2c_unlock(ice->i2c); 752 snd_i2c_unlock(ice->i2c);
715 return -EIO; 753 return -EIO;
716 } 754 }
@@ -725,13 +763,14 @@ static int snd_ice1712_ews88d_control_get(struct snd_kcontrol *kcontrol, struct
725static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 763static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
726{ 764{
727 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 765 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
766 struct ews_spec *spec = ice->spec;
728 int shift = kcontrol->private_value & 0xff; 767 int shift = kcontrol->private_value & 0xff;
729 int invert = (kcontrol->private_value >> 8) & 1; 768 int invert = (kcontrol->private_value >> 8) & 1;
730 unsigned char data[2], ndata[2]; 769 unsigned char data[2], ndata[2];
731 int change; 770 int change;
732 771
733 snd_i2c_lock(ice->i2c); 772 snd_i2c_lock(ice->i2c);
734 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) { 773 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
735 snd_i2c_unlock(ice->i2c); 774 snd_i2c_unlock(ice->i2c);
736 return -EIO; 775 return -EIO;
737 } 776 }
@@ -744,7 +783,8 @@ static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct
744 ndata[shift >> 3] |= (1 << (shift & 7)); 783 ndata[shift >> 3] |= (1 << (shift & 7));
745 } 784 }
746 change = (data[shift >> 3] != ndata[shift >> 3]); 785 change = (data[shift >> 3] != ndata[shift >> 3]);
747 if (change && snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_88D], data, 2) != 2) { 786 if (change &&
787 snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_88D], data, 2) != 2) {
748 snd_i2c_unlock(ice->i2c); 788 snd_i2c_unlock(ice->i2c);
749 return -EIO; 789 return -EIO;
750 } 790 }
@@ -778,11 +818,13 @@ static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
778static int snd_ice1712_6fire_read_pca(struct snd_ice1712 *ice, unsigned char reg) 818static int snd_ice1712_6fire_read_pca(struct snd_ice1712 *ice, unsigned char reg)
779{ 819{
780 unsigned char byte; 820 unsigned char byte;
821 struct ews_spec *spec = ice->spec;
822
781 snd_i2c_lock(ice->i2c); 823 snd_i2c_lock(ice->i2c);
782 byte = reg; 824 byte = reg;
783 snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1); 825 snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1);
784 byte = 0; 826 byte = 0;
785 if (snd_i2c_readbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) { 827 if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_6FIRE], &byte, 1) != 1) {
786 snd_i2c_unlock(ice->i2c); 828 snd_i2c_unlock(ice->i2c);
787 printk(KERN_ERR "cannot read pca\n"); 829 printk(KERN_ERR "cannot read pca\n");
788 return -EIO; 830 return -EIO;
@@ -794,10 +836,12 @@ static int snd_ice1712_6fire_read_pca(struct snd_ice1712 *ice, unsigned char reg
794static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data) 836static int snd_ice1712_6fire_write_pca(struct snd_ice1712 *ice, unsigned char reg, unsigned char data)
795{ 837{
796 unsigned char bytes[2]; 838 unsigned char bytes[2];
839 struct ews_spec *spec = ice->spec;
840
797 snd_i2c_lock(ice->i2c); 841 snd_i2c_lock(ice->i2c);
798 bytes[0] = reg; 842 bytes[0] = reg;
799 bytes[1] = data; 843 bytes[1] = data;
800 if (snd_i2c_sendbytes(ice->spec.i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) { 844 if (snd_i2c_sendbytes(spec->i2cdevs[EWS_I2C_6FIRE], bytes, 2) != 2) {
801 snd_i2c_unlock(ice->i2c); 845 snd_i2c_unlock(ice->i2c);
802 return -EIO; 846 return -EIO;
803 } 847 }
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c
index abcfd1da6587..cf5c7c0898fd 100644
--- a/sound/pci/ice1712/hoontech.c
+++ b/sound/pci/ice1712/hoontech.c
@@ -21,7 +21,6 @@
21 * 21 *
22 */ 22 */
23 23
24#include <sound/driver.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
@@ -34,6 +33,12 @@
34#include "ice1712.h" 33#include "ice1712.h"
35#include "hoontech.h" 34#include "hoontech.h"
36 35
36/* Hoontech-specific setting */
37struct hoontech_spec {
38 unsigned char boxbits[4];
39 unsigned int config;
40 unsigned short boxconfig[4];
41};
37 42
38static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte) 43static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, unsigned char byte)
39{ 44{
@@ -50,169 +55,182 @@ static void __devinit snd_ice1712_stdsp24_gpio_write(struct snd_ice1712 *ice, un
50 55
51static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate) 56static void __devinit snd_ice1712_stdsp24_darear(struct snd_ice1712 *ice, int activate)
52{ 57{
58 struct hoontech_spec *spec = ice->spec;
53 mutex_lock(&ice->gpio_mutex); 59 mutex_lock(&ice->gpio_mutex);
54 ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, activate); 60 ICE1712_STDSP24_0_DAREAR(spec->boxbits, activate);
55 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]); 61 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
56 mutex_unlock(&ice->gpio_mutex); 62 mutex_unlock(&ice->gpio_mutex);
57} 63}
58 64
59static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate) 65static void __devinit snd_ice1712_stdsp24_mute(struct snd_ice1712 *ice, int activate)
60{ 66{
67 struct hoontech_spec *spec = ice->spec;
61 mutex_lock(&ice->gpio_mutex); 68 mutex_lock(&ice->gpio_mutex);
62 ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, activate); 69 ICE1712_STDSP24_3_MUTE(spec->boxbits, activate);
63 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); 70 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
64 mutex_unlock(&ice->gpio_mutex); 71 mutex_unlock(&ice->gpio_mutex);
65} 72}
66 73
67static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate) 74static void __devinit snd_ice1712_stdsp24_insel(struct snd_ice1712 *ice, int activate)
68{ 75{
76 struct hoontech_spec *spec = ice->spec;
69 mutex_lock(&ice->gpio_mutex); 77 mutex_lock(&ice->gpio_mutex);
70 ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, activate); 78 ICE1712_STDSP24_3_INSEL(spec->boxbits, activate);
71 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); 79 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
72 mutex_unlock(&ice->gpio_mutex); 80 mutex_unlock(&ice->gpio_mutex);
73} 81}
74 82
75static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate) 83static void __devinit snd_ice1712_stdsp24_box_channel(struct snd_ice1712 *ice, int box, int chn, int activate)
76{ 84{
85 struct hoontech_spec *spec = ice->spec;
86
77 mutex_lock(&ice->gpio_mutex); 87 mutex_lock(&ice->gpio_mutex);
78 88
79 /* select box */ 89 /* select box */
80 ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box); 90 ICE1712_STDSP24_0_BOX(spec->boxbits, box);
81 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]); 91 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
82 92
83 /* prepare for write */ 93 /* prepare for write */
84 if (chn == 3) 94 if (chn == 3)
85 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 0); 95 ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
86 ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, activate); 96 ICE1712_STDSP24_2_MIDI1(spec->boxbits, activate);
87 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); 97 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
88 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); 98 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
89 99
90 ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1); 100 ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
91 ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1); 101 ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
92 ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1); 102 ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
93 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1); 103 ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
94 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]); 104 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
95 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); 105 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
96 udelay(100); 106 udelay(100);
97 if (chn == 3) { 107 if (chn == 3) {
98 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 0); 108 ICE1712_STDSP24_2_CHN4(spec->boxbits, 0);
99 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); 109 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
100 } else { 110 } else {
101 switch (chn) { 111 switch (chn) {
102 case 0: ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 0); break; 112 case 0: ICE1712_STDSP24_1_CHN1(spec->boxbits, 0); break;
103 case 1: ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 0); break; 113 case 1: ICE1712_STDSP24_1_CHN2(spec->boxbits, 0); break;
104 case 2: ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 0); break; 114 case 2: ICE1712_STDSP24_1_CHN3(spec->boxbits, 0); break;
105 } 115 }
106 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]); 116 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
107 } 117 }
108 udelay(100); 118 udelay(100);
109 ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1); 119 ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
110 ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1); 120 ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
111 ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1); 121 ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
112 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1); 122 ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
113 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[1]); 123 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[1]);
114 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); 124 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
115 udelay(100); 125 udelay(100);
116 126
117 ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0); 127 ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
118 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); 128 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
119 129
120 mutex_unlock(&ice->gpio_mutex); 130 mutex_unlock(&ice->gpio_mutex);
121} 131}
122 132
123static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master) 133static void __devinit snd_ice1712_stdsp24_box_midi(struct snd_ice1712 *ice, int box, int master)
124{ 134{
135 struct hoontech_spec *spec = ice->spec;
136
125 mutex_lock(&ice->gpio_mutex); 137 mutex_lock(&ice->gpio_mutex);
126 138
127 /* select box */ 139 /* select box */
128 ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, box); 140 ICE1712_STDSP24_0_BOX(spec->boxbits, box);
129 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[0]); 141 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[0]);
130 142
131 ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1); 143 ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
132 ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, master); 144 ICE1712_STDSP24_2_MIDI1(spec->boxbits, master);
133 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); 145 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
134 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); 146 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
135 147
136 udelay(100); 148 udelay(100);
137 149
138 ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 0); 150 ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 0);
139 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); 151 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
140 152
141 mdelay(10); 153 mdelay(10);
142 154
143 ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1); 155 ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
144 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[2]); 156 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[2]);
145 157
146 mutex_unlock(&ice->gpio_mutex); 158 mutex_unlock(&ice->gpio_mutex);
147} 159}
148 160
149static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate) 161static void __devinit snd_ice1712_stdsp24_midi2(struct snd_ice1712 *ice, int activate)
150{ 162{
163 struct hoontech_spec *spec = ice->spec;
151 mutex_lock(&ice->gpio_mutex); 164 mutex_lock(&ice->gpio_mutex);
152 ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, activate); 165 ICE1712_STDSP24_3_MIDI2(spec->boxbits, activate);
153 snd_ice1712_stdsp24_gpio_write(ice, ice->spec.hoontech.boxbits[3]); 166 snd_ice1712_stdsp24_gpio_write(ice, spec->boxbits[3]);
154 mutex_unlock(&ice->gpio_mutex); 167 mutex_unlock(&ice->gpio_mutex);
155} 168}
156 169
157static int __devinit snd_ice1712_hoontech_init(struct snd_ice1712 *ice) 170static int __devinit snd_ice1712_hoontech_init(struct snd_ice1712 *ice)
158{ 171{
172 struct hoontech_spec *spec;
159 int box, chn; 173 int box, chn;
160 174
161 ice->num_total_dacs = 8; 175 ice->num_total_dacs = 8;
162 ice->num_total_adcs = 8; 176 ice->num_total_adcs = 8;
163 177
164 ice->spec.hoontech.boxbits[0] = 178 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
165 ice->spec.hoontech.boxbits[1] = 179 if (!spec)
166 ice->spec.hoontech.boxbits[2] = 180 return -ENOMEM;
167 ice->spec.hoontech.boxbits[3] = 0; /* should be already */ 181 ice->spec = spec;
168 182
169 ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 0); 183 ICE1712_STDSP24_SET_ADDR(spec->boxbits, 0);
170 ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 0, 1); 184 ICE1712_STDSP24_CLOCK(spec->boxbits, 0, 1);
171 ICE1712_STDSP24_0_BOX(ice->spec.hoontech.boxbits, 0); 185 ICE1712_STDSP24_0_BOX(spec->boxbits, 0);
172 ICE1712_STDSP24_0_DAREAR(ice->spec.hoontech.boxbits, 0); 186 ICE1712_STDSP24_0_DAREAR(spec->boxbits, 0);
173 187
174 ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 1); 188 ICE1712_STDSP24_SET_ADDR(spec->boxbits, 1);
175 ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 1, 1); 189 ICE1712_STDSP24_CLOCK(spec->boxbits, 1, 1);
176 ICE1712_STDSP24_1_CHN1(ice->spec.hoontech.boxbits, 1); 190 ICE1712_STDSP24_1_CHN1(spec->boxbits, 1);
177 ICE1712_STDSP24_1_CHN2(ice->spec.hoontech.boxbits, 1); 191 ICE1712_STDSP24_1_CHN2(spec->boxbits, 1);
178 ICE1712_STDSP24_1_CHN3(ice->spec.hoontech.boxbits, 1); 192 ICE1712_STDSP24_1_CHN3(spec->boxbits, 1);
179 193
180 ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 2); 194 ICE1712_STDSP24_SET_ADDR(spec->boxbits, 2);
181 ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 2, 1); 195 ICE1712_STDSP24_CLOCK(spec->boxbits, 2, 1);
182 ICE1712_STDSP24_2_CHN4(ice->spec.hoontech.boxbits, 1); 196 ICE1712_STDSP24_2_CHN4(spec->boxbits, 1);
183 ICE1712_STDSP24_2_MIDIIN(ice->spec.hoontech.boxbits, 1); 197 ICE1712_STDSP24_2_MIDIIN(spec->boxbits, 1);
184 ICE1712_STDSP24_2_MIDI1(ice->spec.hoontech.boxbits, 0); 198 ICE1712_STDSP24_2_MIDI1(spec->boxbits, 0);
185 199
186 ICE1712_STDSP24_SET_ADDR(ice->spec.hoontech.boxbits, 3); 200 ICE1712_STDSP24_SET_ADDR(spec->boxbits, 3);
187 ICE1712_STDSP24_CLOCK(ice->spec.hoontech.boxbits, 3, 1); 201 ICE1712_STDSP24_CLOCK(spec->boxbits, 3, 1);
188 ICE1712_STDSP24_3_MIDI2(ice->spec.hoontech.boxbits, 0); 202 ICE1712_STDSP24_3_MIDI2(spec->boxbits, 0);
189 ICE1712_STDSP24_3_MUTE(ice->spec.hoontech.boxbits, 1); 203 ICE1712_STDSP24_3_MUTE(spec->boxbits, 1);
190 ICE1712_STDSP24_3_INSEL(ice->spec.hoontech.boxbits, 0); 204 ICE1712_STDSP24_3_INSEL(spec->boxbits, 0);
191 205
192 /* let's go - activate only functions in first box */ 206 /* let's go - activate only functions in first box */
193 ice->spec.hoontech.config = 0; 207 spec->config = 0;
194 /* ICE1712_STDSP24_MUTE | 208 /* ICE1712_STDSP24_MUTE |
195 ICE1712_STDSP24_INSEL | 209 ICE1712_STDSP24_INSEL |
196 ICE1712_STDSP24_DAREAR; */ 210 ICE1712_STDSP24_DAREAR; */
197 ice->spec.hoontech.boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 | 211 spec->boxconfig[0] = ICE1712_STDSP24_BOX_CHN1 |
198 ICE1712_STDSP24_BOX_CHN2 | 212 ICE1712_STDSP24_BOX_CHN2 |
199 ICE1712_STDSP24_BOX_CHN3 | 213 ICE1712_STDSP24_BOX_CHN3 |
200 ICE1712_STDSP24_BOX_CHN4 | 214 ICE1712_STDSP24_BOX_CHN4 |
201 ICE1712_STDSP24_BOX_MIDI1 | 215 ICE1712_STDSP24_BOX_MIDI1 |
202 ICE1712_STDSP24_BOX_MIDI2; 216 ICE1712_STDSP24_BOX_MIDI2;
203 ice->spec.hoontech.boxconfig[1] = 217 spec->boxconfig[1] =
204 ice->spec.hoontech.boxconfig[2] = 218 spec->boxconfig[2] =
205 ice->spec.hoontech.boxconfig[3] = 0; 219 spec->boxconfig[3] = 0;
206 snd_ice1712_stdsp24_darear(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_DAREAR) ? 1 : 0); 220 snd_ice1712_stdsp24_darear(ice,
207 snd_ice1712_stdsp24_mute(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_MUTE) ? 1 : 0); 221 (spec->config & ICE1712_STDSP24_DAREAR) ? 1 : 0);
208 snd_ice1712_stdsp24_insel(ice, (ice->spec.hoontech.config & ICE1712_STDSP24_INSEL) ? 1 : 0); 222 snd_ice1712_stdsp24_mute(ice,
209 for (box = 0; box < 4; box++) { 223 (spec->config & ICE1712_STDSP24_MUTE) ? 1 : 0);
224 snd_ice1712_stdsp24_insel(ice,
225 (spec->config & ICE1712_STDSP24_INSEL) ? 1 : 0);
226 for (box = 0; box < 1; box++) {
227 if (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
228 snd_ice1712_stdsp24_midi2(ice, 1);
210 for (chn = 0; chn < 4; chn++) 229 for (chn = 0; chn < 4; chn++)
211 snd_ice1712_stdsp24_box_channel(ice, box, chn, (ice->spec.hoontech.boxconfig[box] & (1 << chn)) ? 1 : 0); 230 snd_ice1712_stdsp24_box_channel(ice, box, chn,
231 (spec->boxconfig[box] & (1 << chn)) ? 1 : 0);
212 snd_ice1712_stdsp24_box_midi(ice, box, 232 snd_ice1712_stdsp24_box_midi(ice, box,
213 (ice->spec.hoontech.boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) ? 1 : 0); 233 (spec->boxconfig[box] & ICE1712_STDSP24_BOX_MIDI1) ? 1 : 0);
214 if (ice->spec.hoontech.boxconfig[box] & ICE1712_STDSP24_BOX_MIDI2)
215 snd_ice1712_stdsp24_midi2(ice, 1);
216 } 234 }
217 235
218 return 0; 236 return 0;
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 052fc3cb3272..df292af67381 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -47,7 +47,6 @@
47 */ 47 */
48 48
49 49
50#include <sound/driver.h>
51#include <asm/io.h> 50#include <asm/io.h>
52#include <linux/delay.h> 51#include <linux/delay.h>
53#include <linux/interrupt.h> 52#include <linux/interrupt.h>
@@ -2491,6 +2490,7 @@ static int snd_ice1712_free(struct snd_ice1712 *ice)
2491 pci_release_regions(ice->pci); 2490 pci_release_regions(ice->pci);
2492 snd_ice1712_akm4xxx_free(ice); 2491 snd_ice1712_akm4xxx_free(ice);
2493 pci_disable_device(ice->pci); 2492 pci_disable_device(ice->pci);
2493 kfree(ice->spec);
2494 kfree(ice); 2494 kfree(ice);
2495 return 0; 2495 return 0;
2496} 2496}
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index 58640afa5404..303cffe08bd8 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -366,42 +366,7 @@ struct snd_ice1712 {
366 struct mutex gpio_mutex; 366 struct mutex gpio_mutex;
367 367
368 /* other board-specific data */ 368 /* other board-specific data */
369 union { 369 void *spec;
370 /* additional i2c devices for EWS boards */
371 struct snd_i2c_device *i2cdevs[3];
372 /* AC97 register cache for Aureon */
373 struct aureon_spec {
374 unsigned short stac9744[64];
375 unsigned int cs8415_mux;
376 unsigned short master[2];
377 unsigned short vol[8];
378 unsigned char pca9554_out;
379 } aureon;
380 /* AC97 register cache for Phase28 */
381 struct phase28_spec {
382 unsigned short master[2];
383 unsigned short vol[8];
384 } phase28;
385 /* a non-standard I2C device for revo51 */
386 struct revo51_spec {
387 struct snd_i2c_device *dev;
388 struct snd_pt2258 *pt2258;
389 } revo51;
390 /* Hoontech-specific setting */
391 struct hoontech_spec {
392 unsigned char boxbits[4];
393 unsigned int config;
394 unsigned short boxconfig[4];
395 } hoontech;
396 struct {
397 struct ak4114 *ak4114;
398 unsigned int analog: 1;
399 } juli;
400 struct {
401 struct ak4114 *ak4114;
402 } prodigy192;
403 } spec;
404
405}; 370};
406 371
407 372
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 0b0bbb0d96b9..f533850ec6e7 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -22,7 +22,6 @@
22 * 22 *
23 */ 23 */
24 24
25#include <sound/driver.h>
26#include <asm/io.h> 25#include <asm/io.h>
27#include <linux/delay.h> 26#include <linux/delay.h>
28#include <linux/interrupt.h> 27#include <linux/interrupt.h>
@@ -48,9 +47,11 @@
48#include "vt1720_mobo.h" 47#include "vt1720_mobo.h"
49#include "pontis.h" 48#include "pontis.h"
50#include "prodigy192.h" 49#include "prodigy192.h"
50#include "prodigy_hifi.h"
51#include "juli.h" 51#include "juli.h"
52#include "phase.h" 52#include "phase.h"
53#include "wtm.h" 53#include "wtm.h"
54#include "se.h"
54 55
55MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 56MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
56MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)"); 57MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)");
@@ -62,9 +63,11 @@ MODULE_SUPPORTED_DEVICE("{"
62 VT1720_MOBO_DEVICE_DESC 63 VT1720_MOBO_DEVICE_DESC
63 PONTIS_DEVICE_DESC 64 PONTIS_DEVICE_DESC
64 PRODIGY192_DEVICE_DESC 65 PRODIGY192_DEVICE_DESC
66 PRODIGY_HIFI_DEVICE_DESC
65 JULI_DEVICE_DESC 67 JULI_DEVICE_DESC
66 PHASE_DEVICE_DESC 68 PHASE_DEVICE_DESC
67 WTM_DEVICE_DESC 69 WTM_DEVICE_DESC
70 SE_DEVICE_DESC
68 "{VIA,VT1720}," 71 "{VIA,VT1720},"
69 "{VIA,VT1724}," 72 "{VIA,VT1724},"
70 "{ICEnsemble,Generic ICE1724}," 73 "{ICEnsemble,Generic ICE1724},"
@@ -1929,10 +1932,12 @@ static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
1929 snd_vt1724_aureon_cards, 1932 snd_vt1724_aureon_cards,
1930 snd_vt1720_mobo_cards, 1933 snd_vt1720_mobo_cards,
1931 snd_vt1720_pontis_cards, 1934 snd_vt1720_pontis_cards,
1935 snd_vt1724_prodigy_hifi_cards,
1932 snd_vt1724_prodigy192_cards, 1936 snd_vt1724_prodigy192_cards,
1933 snd_vt1724_juli_cards, 1937 snd_vt1724_juli_cards,
1934 snd_vt1724_phase_cards, 1938 snd_vt1724_phase_cards,
1935 snd_vt1724_wtm_cards, 1939 snd_vt1724_wtm_cards,
1940 snd_vt1724_se_cards,
1936 NULL, 1941 NULL,
1937}; 1942};
1938 1943
@@ -1955,6 +1960,7 @@ unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice,
1955 unsigned char val; 1960 unsigned char val;
1956 1961
1957 mutex_lock(&ice->i2c_mutex); 1962 mutex_lock(&ice->i2c_mutex);
1963 wait_i2c_busy(ice);
1958 outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR)); 1964 outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR));
1959 outb(dev & ~VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR)); 1965 outb(dev & ~VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR));
1960 wait_i2c_busy(ice); 1966 wait_i2c_busy(ice);
@@ -2170,6 +2176,7 @@ static int snd_vt1724_free(struct snd_ice1712 *ice)
2170 pci_release_regions(ice->pci); 2176 pci_release_regions(ice->pci);
2171 snd_ice1712_akm4xxx_free(ice); 2177 snd_ice1712_akm4xxx_free(ice);
2172 pci_disable_device(ice->pci); 2178 pci_disable_device(ice->pci);
2179 kfree(ice->spec);
2173 kfree(ice); 2180 kfree(ice);
2174 return 0; 2181 return 0;
2175} 2182}
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 1fbe3ef8e60a..e8038c0ceb72 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -21,7 +21,6 @@
21 * 21 *
22 */ 22 */
23 23
24#include <sound/driver.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
@@ -33,6 +32,11 @@
33#include "envy24ht.h" 32#include "envy24ht.h"
34#include "juli.h" 33#include "juli.h"
35 34
35struct juli_spec {
36 struct ak4114 *ak4114;
37 unsigned int analog: 1;
38};
39
36/* 40/*
37 * chip addresses on I2C bus 41 * chip addresses on I2C bus
38 */ 42 */
@@ -138,12 +142,13 @@ static struct snd_akm4xxx akm_juli_dac __devinitdata = {
138 142
139static int __devinit juli_add_controls(struct snd_ice1712 *ice) 143static int __devinit juli_add_controls(struct snd_ice1712 *ice)
140{ 144{
145 struct juli_spec *spec = ice->spec;
141 int err; 146 int err;
142 err = snd_ice1712_akm4xxx_build_controls(ice); 147 err = snd_ice1712_akm4xxx_build_controls(ice);
143 if (err < 0) 148 if (err < 0)
144 return err; 149 return err;
145 /* only capture SPDIF over AK4114 */ 150 /* only capture SPDIF over AK4114 */
146 err = snd_ak4114_build(ice->spec.juli.ak4114, NULL, 151 err = snd_ak4114_build(spec->ak4114, NULL,
147 ice->pcm_pro->streams[SNDRV_PCM_STREAM_CAPTURE].substream); 152 ice->pcm_pro->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
148 if (err < 0) 153 if (err < 0)
149 return err; 154 return err;
@@ -167,13 +172,19 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
167 0x41, 0x02, 0x2c, 0x00, 0x00 172 0x41, 0x02, 0x2c, 0x00, 0x00
168 }; 173 };
169 int err; 174 int err;
175 struct juli_spec *spec;
170 struct snd_akm4xxx *ak; 176 struct snd_akm4xxx *ak;
171 177
178 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
179 if (!spec)
180 return -ENOMEM;
181 ice->spec = spec;
182
172 err = snd_ak4114_create(ice->card, 183 err = snd_ak4114_create(ice->card,
173 juli_ak4114_read, 184 juli_ak4114_read,
174 juli_ak4114_write, 185 juli_ak4114_write,
175 ak4114_init_vals, ak4114_init_txcsb, 186 ak4114_init_vals, ak4114_init_txcsb,
176 ice, &ice->spec.juli.ak4114); 187 ice, &spec->ak4114);
177 if (err < 0) 188 if (err < 0)
178 return err; 189 return err;
179 190
@@ -181,12 +192,12 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
181 /* it seems that the analog doughter board detection does not work 192 /* it seems that the analog doughter board detection does not work
182 reliably, so force the analog flag; it should be very rare 193 reliably, so force the analog flag; it should be very rare
183 to use Juli@ without the analog doughter board */ 194 to use Juli@ without the analog doughter board */
184 ice->spec.juli.analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1; 195 spec->analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1;
185#else 196#else
186 ice->spec.juli.analog = 1; 197 spec->analog = 1;
187#endif 198#endif
188 199
189 if (ice->spec.juli.analog) { 200 if (spec->analog) {
190 printk(KERN_INFO "juli@: analog I/O detected\n"); 201 printk(KERN_INFO "juli@: analog I/O detected\n");
191 ice->num_total_dacs = 2; 202 ice->num_total_dacs = 2;
192 ice->num_total_adcs = 2; 203 ice->num_total_adcs = 2;
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index 3ac25058bb58..9ab4a9f383cb 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -33,7 +33,6 @@
33 * CDTI may be completely blocked by 74HCT125's gate #1 controlled by GPIO 3 33 * CDTI may be completely blocked by 74HCT125's gate #1 controlled by GPIO 3
34 */ 34 */
35 35
36#include <sound/driver.h>
37#include <asm/io.h> 36#include <asm/io.h>
38#include <linux/delay.h> 37#include <linux/delay.h>
39#include <linux/interrupt.h> 38#include <linux/interrupt.h>
@@ -48,6 +47,12 @@
48#include "phase.h" 47#include "phase.h"
49#include <sound/tlv.h> 48#include <sound/tlv.h>
50 49
50/* AC97 register cache for Phase28 */
51struct phase28_spec {
52 unsigned short master[2];
53 unsigned short vol[8];
54} phase28;
55
51/* WM8770 registers */ 56/* WM8770 registers */
52#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */ 57#define WM_DAC_ATTEN 0x00 /* DAC1-8 analog attenuation */
53#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */ 58#define WM_DAC_MASTER_ATTEN 0x08 /* DAC master analog attenuation */
@@ -313,27 +318,32 @@ static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
313static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 318static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
314{ 319{
315 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 320 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
321 struct phase28_spec *spec = ice->spec;
316 int i; 322 int i;
317 for (i=0; i<2; i++) 323 for (i=0; i<2; i++)
318 ucontrol->value.integer.value[i] = ice->spec.phase28.master[i] & ~WM_VOL_MUTE; 324 ucontrol->value.integer.value[i] = spec->master[i] & ~WM_VOL_MUTE;
319 return 0; 325 return 0;
320} 326}
321 327
322static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 328static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
323{ 329{
324 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 330 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
331 struct phase28_spec *spec = ice->spec;
325 int ch, change = 0; 332 int ch, change = 0;
326 333
327 snd_ice1712_save_gpio_status(ice); 334 snd_ice1712_save_gpio_status(ice);
328 for (ch = 0; ch < 2; ch++) { 335 for (ch = 0; ch < 2; ch++) {
329 if (ucontrol->value.integer.value[ch] != ice->spec.phase28.master[ch]) { 336 unsigned int vol = ucontrol->value.integer.value[ch];
337 if (vol > WM_VOL_MAX)
338 continue;
339 vol |= spec->master[ch] & WM_VOL_MUTE;
340 if (vol != spec->master[ch]) {
330 int dac; 341 int dac;
331 ice->spec.phase28.master[ch] &= WM_VOL_MUTE; 342 spec->master[ch] = vol;
332 ice->spec.phase28.master[ch] |= ucontrol->value.integer.value[ch];
333 for (dac = 0; dac < ice->num_total_dacs; dac += 2) 343 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
334 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch, 344 wm_set_vol(ice, WM_DAC_ATTEN + dac + ch,
335 ice->spec.phase28.vol[dac + ch], 345 spec->vol[dac + ch],
336 ice->spec.phase28.master[ch]); 346 spec->master[ch]);
337 change = 1; 347 change = 1;
338 } 348 }
339 } 349 }
@@ -382,12 +392,18 @@ static int __devinit phase28_init(struct snd_ice1712 *ice)
382 392
383 unsigned int tmp; 393 unsigned int tmp;
384 struct snd_akm4xxx *ak; 394 struct snd_akm4xxx *ak;
395 struct phase28_spec *spec;
385 const unsigned short *p; 396 const unsigned short *p;
386 int i; 397 int i;
387 398
388 ice->num_total_dacs = 8; 399 ice->num_total_dacs = 8;
389 ice->num_total_adcs = 2; 400 ice->num_total_adcs = 2;
390 401
402 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
403 if (!spec)
404 return -ENOMEM;
405 ice->spec = spec;
406
391 // Initialize analog chips 407 // Initialize analog chips
392 ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); 408 ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
393 if (!ak) 409 if (!ak)
@@ -417,11 +433,11 @@ static int __devinit phase28_init(struct snd_ice1712 *ice)
417 433
418 snd_ice1712_restore_gpio_status(ice); 434 snd_ice1712_restore_gpio_status(ice);
419 435
420 ice->spec.phase28.master[0] = WM_VOL_MUTE; 436 spec->master[0] = WM_VOL_MUTE;
421 ice->spec.phase28.master[1] = WM_VOL_MUTE; 437 spec->master[1] = WM_VOL_MUTE;
422 for (i = 0; i < ice->num_total_dacs; i++) { 438 for (i = 0; i < ice->num_total_dacs; i++) {
423 ice->spec.phase28.vol[i] = WM_VOL_MUTE; 439 spec->vol[i] = WM_VOL_MUTE;
424 wm_set_vol(ice, i, ice->spec.phase28.vol[i], ice->spec.phase28.master[i % 2]); 440 wm_set_vol(ice, i, spec->vol[i], spec->master[i % 2]);
425 } 441 }
426 442
427 return 0; 443 return 0;
@@ -443,18 +459,21 @@ static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *
443static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 459static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
444{ 460{
445 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 461 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
462 struct phase28_spec *spec = ice->spec;
446 int i, ofs, voices; 463 int i, ofs, voices;
447 464
448 voices = kcontrol->private_value >> 8; 465 voices = kcontrol->private_value >> 8;
449 ofs = kcontrol->private_value & 0xff; 466 ofs = kcontrol->private_value & 0xff;
450 for (i = 0; i < voices; i++) 467 for (i = 0; i < voices; i++)
451 ucontrol->value.integer.value[i] = ice->spec.phase28.vol[ofs+i] & ~WM_VOL_MUTE; 468 ucontrol->value.integer.value[i] =
469 spec->vol[ofs+i] & ~WM_VOL_MUTE;
452 return 0; 470 return 0;
453} 471}
454 472
455static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 473static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
456{ 474{
457 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 475 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
476 struct phase28_spec *spec = ice->spec;
458 int i, idx, ofs, voices; 477 int i, idx, ofs, voices;
459 int change = 0; 478 int change = 0;
460 479
@@ -462,12 +481,16 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *
462 ofs = kcontrol->private_value & 0xff; 481 ofs = kcontrol->private_value & 0xff;
463 snd_ice1712_save_gpio_status(ice); 482 snd_ice1712_save_gpio_status(ice);
464 for (i = 0; i < voices; i++) { 483 for (i = 0; i < voices; i++) {
465 idx = WM_DAC_ATTEN + ofs + i; 484 unsigned int vol;
466 if (ucontrol->value.integer.value[i] != ice->spec.phase28.vol[ofs+i]) { 485 vol = ucontrol->value.integer.value[i];
467 ice->spec.phase28.vol[ofs+i] &= WM_VOL_MUTE; 486 if (vol > 0x7f)
468 ice->spec.phase28.vol[ofs+i] |= ucontrol->value.integer.value[i]; 487 continue;
469 wm_set_vol(ice, idx, ice->spec.phase28.vol[ofs+i], 488 vol |= spec->vol[ofs+i] & WM_VOL_MUTE;
470 ice->spec.phase28.master[i]); 489 if (vol != spec->vol[ofs+i]) {
490 spec->vol[ofs+i] = vol;
491 idx = WM_DAC_ATTEN + ofs + i;
492 wm_set_vol(ice, idx, spec->vol[ofs+i],
493 spec->master[i]);
471 change = 1; 494 change = 1;
472 } 495 }
473 } 496 }
@@ -489,19 +512,22 @@ static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info
489static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 512static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
490{ 513{
491 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 514 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
515 struct phase28_spec *spec = ice->spec;
492 int voices, ofs, i; 516 int voices, ofs, i;
493 517
494 voices = kcontrol->private_value >> 8; 518 voices = kcontrol->private_value >> 8;
495 ofs = kcontrol->private_value & 0xFF; 519 ofs = kcontrol->private_value & 0xFF;
496 520
497 for (i = 0; i < voices; i++) 521 for (i = 0; i < voices; i++)
498 ucontrol->value.integer.value[i] = (ice->spec.phase28.vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1; 522 ucontrol->value.integer.value[i] =
523 (spec->vol[ofs+i] & WM_VOL_MUTE) ? 0 : 1;
499 return 0; 524 return 0;
500} 525}
501 526
502static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 527static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
503{ 528{
504 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 529 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
530 struct phase28_spec *spec = ice->spec;
505 int change = 0, voices, ofs, i; 531 int change = 0, voices, ofs, i;
506 532
507 voices = kcontrol->private_value >> 8; 533 voices = kcontrol->private_value >> 8;
@@ -509,13 +535,13 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
509 535
510 snd_ice1712_save_gpio_status(ice); 536 snd_ice1712_save_gpio_status(ice);
511 for (i = 0; i < voices; i++) { 537 for (i = 0; i < voices; i++) {
512 int val = (ice->spec.phase28.vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1; 538 int val = (spec->vol[ofs + i] & WM_VOL_MUTE) ? 0 : 1;
513 if (ucontrol->value.integer.value[i] != val) { 539 if (ucontrol->value.integer.value[i] != val) {
514 ice->spec.phase28.vol[ofs + i] &= ~WM_VOL_MUTE; 540 spec->vol[ofs + i] &= ~WM_VOL_MUTE;
515 ice->spec.phase28.vol[ofs + i] |= 541 spec->vol[ofs + i] |=
516 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; 542 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
517 wm_set_vol(ice, ofs + i, ice->spec.phase28.vol[ofs + i], 543 wm_set_vol(ice, ofs + i, spec->vol[ofs + i],
518 ice->spec.phase28.master[i]); 544 spec->master[i]);
519 change = 1; 545 change = 1;
520 } 546 }
521 } 547 }
@@ -532,29 +558,33 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value
532static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 558static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
533{ 559{
534 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 560 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
561 struct phase28_spec *spec = ice->spec;
535 562
536 ucontrol->value.integer.value[0] = (ice->spec.phase28.master[0] & WM_VOL_MUTE) ? 0 : 1; 563 ucontrol->value.integer.value[0] =
537 ucontrol->value.integer.value[1] = (ice->spec.phase28.master[1] & WM_VOL_MUTE) ? 0 : 1; 564 (spec->master[0] & WM_VOL_MUTE) ? 0 : 1;
565 ucontrol->value.integer.value[1] =
566 (spec->master[1] & WM_VOL_MUTE) ? 0 : 1;
538 return 0; 567 return 0;
539} 568}
540 569
541static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 570static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
542{ 571{
543 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 572 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
573 struct phase28_spec *spec = ice->spec;
544 int change = 0, i; 574 int change = 0, i;
545 575
546 snd_ice1712_save_gpio_status(ice); 576 snd_ice1712_save_gpio_status(ice);
547 for (i = 0; i < 2; i++) { 577 for (i = 0; i < 2; i++) {
548 int val = (ice->spec.phase28.master[i] & WM_VOL_MUTE) ? 0 : 1; 578 int val = (spec->master[i] & WM_VOL_MUTE) ? 0 : 1;
549 if (ucontrol->value.integer.value[i] != val) { 579 if (ucontrol->value.integer.value[i] != val) {
550 int dac; 580 int dac;
551 ice->spec.phase28.master[i] &= ~WM_VOL_MUTE; 581 spec->master[i] &= ~WM_VOL_MUTE;
552 ice->spec.phase28.master[i] |= 582 spec->master[i] |=
553 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; 583 ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE;
554 for (dac = 0; dac < ice->num_total_dacs; dac += 2) 584 for (dac = 0; dac < ice->num_total_dacs; dac += 2)
555 wm_set_vol(ice, WM_DAC_ATTEN + dac + i, 585 wm_set_vol(ice, WM_DAC_ATTEN + dac + i,
556 ice->spec.phase28.vol[dac + i], 586 spec->vol[dac + i],
557 ice->spec.phase28.master[i]); 587 spec->master[i]);
558 change = 1; 588 change = 1;
559 } 589 }
560 } 590 }
@@ -595,8 +625,10 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
595 unsigned short ovol, nvol; 625 unsigned short ovol, nvol;
596 int change = 0; 626 int change = 0;
597 627
598 snd_ice1712_save_gpio_status(ice);
599 nvol = ucontrol->value.integer.value[0]; 628 nvol = ucontrol->value.integer.value[0];
629 if (nvol > PCM_RES)
630 return -EINVAL;
631 snd_ice1712_save_gpio_status(ice);
600 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff; 632 nvol = (nvol ? (nvol + PCM_MIN) : 0) & 0xff;
601 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; 633 ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff;
602 if (ovol != nvol) { 634 if (ovol != nvol) {
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index faefd52c1b80..4945c81e8a96 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -21,7 +21,6 @@
21 * 21 *
22 */ 22 */
23 23
24#include <sound/driver.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
index 4180f9739ecb..48cf40a8f32a 100644
--- a/sound/pci/ice1712/prodigy192.c
+++ b/sound/pci/ice1712/prodigy192.c
@@ -54,7 +54,6 @@
54 * 54 *
55 */ 55 */
56 56
57#include <sound/driver.h>
58#include <asm/io.h> 57#include <asm/io.h>
59#include <linux/delay.h> 58#include <linux/delay.h>
60#include <linux/interrupt.h> 59#include <linux/interrupt.h>
@@ -68,6 +67,12 @@
68#include "stac946x.h" 67#include "stac946x.h"
69#include <sound/tlv.h> 68#include <sound/tlv.h>
70 69
70struct prodigy192_spec {
71 struct ak4114 *ak4114;
72 /* rate change needs atomic mute/unmute of all dacs*/
73 struct mutex mute_mutex;
74};
75
71static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val) 76static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val)
72{ 77{
73 snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val); 78 snd_vt1724_write_i2c(ice, PRODIGY192_STAC9460_ADDR, reg, val);
@@ -81,6 +86,24 @@ static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
81/* 86/*
82 * DAC mute control 87 * DAC mute control
83 */ 88 */
89
90/*
91 * idx = STAC9460 volume register number, mute: 0 = mute, 1 = unmute
92 */
93static int stac9460_dac_mute(struct snd_ice1712 *ice, int idx,
94 unsigned char mute)
95{
96 unsigned char new, old;
97 int change;
98 old = stac9460_get(ice, idx);
99 new = (~mute << 7 & 0x80) | (old & ~0x80);
100 change = (new != old);
101 if (change)
102 /*printk ("Volume register 0x%02x: 0x%02x\n", idx, new);*/
103 stac9460_put(ice, idx, new);
104 return change;
105}
106
84#define stac9460_dac_mute_info snd_ctl_boolean_mono_info 107#define stac9460_dac_mute_info snd_ctl_boolean_mono_info
85 108
86static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 109static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
@@ -101,20 +124,19 @@ static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e
101static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 124static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
102{ 125{
103 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 126 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
104 unsigned char new, old; 127 struct prodigy192_spec *spec = ice->spec;
105 int idx; 128 int idx, change;
106 int change;
107 129
108 if (kcontrol->private_value) 130 if (kcontrol->private_value)
109 idx = STAC946X_MASTER_VOLUME; 131 idx = STAC946X_MASTER_VOLUME;
110 else 132 else
111 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME; 133 idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + STAC946X_LF_VOLUME;
112 old = stac9460_get(ice, idx); 134 /* due to possible conflicts with stac9460_set_rate_val, mutexing */
113 new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | (old & ~0x80); 135 mutex_lock(&spec->mute_mutex);
114 change = (new != old); 136 /*printk("Mute put: reg 0x%02x, ctrl value: 0x%02x\n", idx,
115 if (change) 137 ucontrol->value.integer.value[0]);*/
116 stac9460_put(ice, idx, new); 138 change = stac9460_dac_mute(ice, idx, ucontrol->value.integer.value[0]);
117 139 mutex_unlock(&spec->mute_mutex);
118 return change; 140 return change;
119} 141}
120 142
@@ -162,6 +184,8 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
162 ovol = 0x7f - (tmp & 0x7f); 184 ovol = 0x7f - (tmp & 0x7f);
163 change = (ovol != nvol); 185 change = (ovol != nvol);
164 if (change) { 186 if (change) {
187 ovol = (0x7f - nvol) | (tmp & 0x80);
188 /*printk("DAC Volume: reg 0x%02x: 0x%02x\n", idx, ovol);*/
165 stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); 189 stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
166 } 190 }
167 return change; 191 return change;
@@ -241,7 +265,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
241 265
242 for (i = 0; i < 2; ++i) { 266 for (i = 0; i < 2; ++i) {
243 reg = STAC946X_MIC_L_VOLUME + i; 267 reg = STAC946X_MIC_L_VOLUME + i;
244 nvol = ucontrol->value.integer.value[i]; 268 nvol = ucontrol->value.integer.value[i] & 0x0f;
245 ovol = 0x0f - stac9460_get(ice, reg); 269 ovol = 0x0f - stac9460_get(ice, reg);
246 change = ((ovol & 0x0f) != nvol); 270 change = ((ovol & 0x0f) != nvol);
247 if (change) 271 if (change)
@@ -251,121 +275,6 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
251 return change; 275 return change;
252} 276}
253 277
254#if 0
255/*
256 * Headphone Amplifier
257 */
258static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
259{
260 unsigned int tmp, tmp2;
261
262 tmp2 = tmp = snd_ice1712_gpio_read(ice);
263 if (enable)
264 tmp |= AUREON_HP_SEL;
265 else
266 tmp &= ~ AUREON_HP_SEL;
267 if (tmp != tmp2) {
268 snd_ice1712_gpio_write(ice, tmp);
269 return 1;
270 }
271 return 0;
272}
273
274static int aureon_get_headphone_amp(struct snd_ice1712 *ice)
275{
276 unsigned int tmp = snd_ice1712_gpio_read(ice);
277
278 return ( tmp & AUREON_HP_SEL )!= 0;
279}
280
281#define aureon_bool_info snd_ctl_boolean_mono_info
282
283static int aureon_hpamp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
284{
285 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
286
287 ucontrol->value.integer.value[0] = aureon_get_headphone_amp(ice);
288 return 0;
289}
290
291
292static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
293{
294 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
295
296 return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]);
297}
298
299/*
300 * Deemphasis
301 */
302static int aureon_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
303{
304 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
305 ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf;
306 return 0;
307}
308
309static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
310{
311 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
312 int temp, temp2;
313 temp2 = temp = wm_get(ice, WM_DAC_CTRL2);
314 if (ucontrol->value.integer.value[0])
315 temp |= 0xf;
316 else
317 temp &= ~0xf;
318 if (temp != temp2) {
319 wm_put(ice, WM_DAC_CTRL2, temp);
320 return 1;
321 }
322 return 0;
323}
324
325/*
326 * ADC Oversampling
327 */
328static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
329{
330 static char *texts[2] = { "128x", "64x" };
331
332 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
333 uinfo->count = 1;
334 uinfo->value.enumerated.items = 2;
335
336 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
337 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
338 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
339
340 return 0;
341}
342
343static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
344{
345 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
346 ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8;
347 return 0;
348}
349
350static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
351{
352 int temp, temp2;
353 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
354
355 temp2 = temp = wm_get(ice, WM_MASTER);
356
357 if (ucontrol->value.enumerated.item[0])
358 temp |= 0x8;
359 else
360 temp &= ~0x8;
361
362 if (temp != temp2) {
363 wm_put(ice, WM_MASTER, temp);
364 return 1;
365 }
366 return 0;
367}
368#endif
369static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol, 278static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
370 struct snd_ctl_elem_info *uinfo) 279 struct snd_ctl_elem_info *uinfo)
371{ 280{
@@ -407,6 +316,57 @@ static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
407 stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); 316 stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
408 return change; 317 return change;
409} 318}
319/*
320 * Handler for setting correct codec rate - called when rate change is detected
321 */
322static void stac9460_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
323{
324 unsigned char old, new;
325 int idx;
326 unsigned char changed[7];
327 struct snd_ice1712 *ice = ak->private_data[0];
328 struct prodigy192_spec *spec = ice->spec;
329
330 if (rate == 0) /* no hint - S/PDIF input is master, simply return */
331 return;
332 else if (rate <= 48000)
333 new = 0x08; /* 256x, base rate mode */
334 else if (rate <= 96000)
335 new = 0x11; /* 256x, mid rate mode */
336 else
337 new = 0x12; /* 128x, high rate mode */
338 old = stac9460_get(ice, STAC946X_MASTER_CLOCKING);
339 if (old == new)
340 return;
341 /* change detected, setting master clock, muting first */
342 /* due to possible conflicts with mute controls - mutexing */
343 mutex_lock(&spec->mute_mutex);
344 /* we have to remember current mute status for each DAC */
345 for (idx = 0; idx < 7 ; ++idx)
346 changed[idx] = stac9460_dac_mute(ice,
347 STAC946X_MASTER_VOLUME + idx, 0);
348 /*printk("Rate change: %d, new MC: 0x%02x\n", rate, new);*/
349 stac9460_put(ice, STAC946X_MASTER_CLOCKING, new);
350 udelay(10);
351 /* unmuting - only originally unmuted dacs -
352 * i.e. those changed when muting */
353 for (idx = 0; idx < 7 ; ++idx) {
354 if (changed[idx])
355 stac9460_dac_mute(ice, STAC946X_MASTER_VOLUME + idx, 1);
356 }
357 mutex_unlock(&spec->mute_mutex);
358}
359
360/* using akm infrastructure for setting rate of the codec */
361static struct snd_akm4xxx akmlike_stac9460 __devinitdata = {
362 .type = NON_AKM, /* special value */
363 .num_adcs = 6, /* not used in any way, just for completeness */
364 .num_dacs = 2,
365 .ops = {
366 .set_rate_val = stac9460_set_rate_val
367 }
368};
369
410 370
411static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); 371static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0);
412static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); 372static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
@@ -483,39 +443,8 @@ static struct snd_kcontrol_new stac_controls[] __devinitdata = {
483 .put = stac9460_mic_sw_put, 443 .put = stac9460_mic_sw_put,
484 444
485 }, 445 },
486#if 0
487 {
488 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
489 .name = "Capture Route",
490 .info = wm_adc_mux_info,
491 .get = wm_adc_mux_get,
492 .put = wm_adc_mux_put,
493 },
494 {
495 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
496 .name = "Headphone Amplifier Switch",
497 .info = aureon_bool_info,
498 .get = aureon_hpamp_get,
499 .put = aureon_hpamp_put
500 },
501 {
502 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
503 .name = "DAC Deemphasis Switch",
504 .info = aureon_bool_info,
505 .get = aureon_deemp_get,
506 .put = aureon_deemp_put
507 },
508 {
509 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
510 .name = "ADC Oversampling",
511 .info = aureon_oversampling_info,
512 .get = aureon_oversampling_get,
513 .put = aureon_oversampling_put
514 },
515#endif
516}; 446};
517 447
518
519/* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */ 448/* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */
520/* CDTO (pin 32) -- GPIO11 pin 86 449/* CDTO (pin 32) -- GPIO11 pin 86
521 * CDTI (pin 33) -- GPIO10 pin 77 450 * CDTI (pin 33) -- GPIO10 pin 77
@@ -712,16 +641,39 @@ static int prodigy192_ak4114_init(struct snd_ice1712 *ice)
712 static const unsigned char ak4114_init_txcsb[] = { 641 static const unsigned char ak4114_init_txcsb[] = {
713 0x41, 0x02, 0x2c, 0x00, 0x00 642 0x41, 0x02, 0x2c, 0x00, 0x00
714 }; 643 };
644 struct prodigy192_spec *spec = ice->spec;
715 645
716 return snd_ak4114_create(ice->card, 646 return snd_ak4114_create(ice->card,
717 prodigy192_ak4114_read, 647 prodigy192_ak4114_read,
718 prodigy192_ak4114_write, 648 prodigy192_ak4114_write,
719 ak4114_init_vals, ak4114_init_txcsb, 649 ak4114_init_vals, ak4114_init_txcsb,
720 ice, &ice->spec.prodigy192.ak4114); 650 ice, &spec->ak4114);
651}
652
653static void stac9460_proc_regs_read(struct snd_info_entry *entry,
654 struct snd_info_buffer *buffer)
655{
656 struct snd_ice1712 *ice = (struct snd_ice1712 *)entry->private_data;
657 int reg, val;
658 /* registers 0x0 - 0x14 */
659 for (reg = 0; reg <= 0x15; reg++) {
660 val = stac9460_get(ice, reg);
661 snd_iprintf(buffer, "0x%02x = 0x%02x\n", reg, val);
662 }
663}
664
665
666static void stac9460_proc_init(struct snd_ice1712 *ice)
667{
668 struct snd_info_entry *entry;
669 if (!snd_card_proc_new(ice->card, "stac9460_codec", &entry))
670 snd_info_set_text_ops(entry, ice, stac9460_proc_regs_read);
721} 671}
722 672
673
723static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) 674static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
724{ 675{
676 struct prodigy192_spec *spec = ice->spec;
725 unsigned int i; 677 unsigned int i;
726 int err; 678 int err;
727 679
@@ -731,7 +683,7 @@ static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
731 if (err < 0) 683 if (err < 0)
732 return err; 684 return err;
733 } 685 }
734 if (ice->spec.prodigy192.ak4114) { 686 if (spec->ak4114) {
735 /* ak4114 is connected */ 687 /* ak4114 is connected */
736 for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) { 688 for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) {
737 err = snd_ctl_add(ice->card, 689 err = snd_ctl_add(ice->card,
@@ -740,12 +692,13 @@ static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
740 if (err < 0) 692 if (err < 0)
741 return err; 693 return err;
742 } 694 }
743 err = snd_ak4114_build(ice->spec.prodigy192.ak4114, 695 err = snd_ak4114_build(spec->ak4114,
744 NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */ 696 NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */
745 ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); 697 ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream);
746 if (err < 0) 698 if (err < 0)
747 return err; 699 return err;
748 } 700 }
701 stac9460_proc_init(ice);
749 return 0; 702 return 0;
750} 703}
751 704
@@ -778,6 +731,7 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)
778{ 731{
779 static const unsigned short stac_inits_prodigy[] = { 732 static const unsigned short stac_inits_prodigy[] = {
780 STAC946X_RESET, 0, 733 STAC946X_RESET, 0,
734 STAC946X_MASTER_CLOCKING, 0x11,
781/* STAC946X_MASTER_VOLUME, 0, 735/* STAC946X_MASTER_VOLUME, 0,
782 STAC946X_LF_VOLUME, 0, 736 STAC946X_LF_VOLUME, 0,
783 STAC946X_RF_VOLUME, 0, 737 STAC946X_RF_VOLUME, 0,
@@ -789,22 +743,39 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)
789 }; 743 };
790 const unsigned short *p; 744 const unsigned short *p;
791 int err = 0; 745 int err = 0;
746 struct snd_akm4xxx *ak;
747 struct prodigy192_spec *spec;
792 748
793 /* prodigy 192 */ 749 /* prodigy 192 */
794 ice->num_total_dacs = 6; 750 ice->num_total_dacs = 6;
795 ice->num_total_adcs = 2; 751 ice->num_total_adcs = 2;
796 ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */ 752 ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */
797 753
754 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
755 if (!spec)
756 return -ENOMEM;
757 ice->spec = spec;
758 mutex_init(&spec->mute_mutex);
759
798 /* initialize codec */ 760 /* initialize codec */
799 p = stac_inits_prodigy; 761 p = stac_inits_prodigy;
800 for (; *p != (unsigned short)-1; p += 2) 762 for (; *p != (unsigned short)-1; p += 2)
801 stac9460_put(ice, p[0], p[1]); 763 stac9460_put(ice, p[0], p[1]);
764 /* reusing the akm codecs infrastructure,
765 * for setting rate on stac9460 */
766 ak = ice->akm = kmalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
767 if (!ak)
768 return -ENOMEM;
769 ice->akm_codecs = 1;
770 err = snd_ice1712_akm4xxx_init(ak, &akmlike_stac9460, NULL, ice);
771 if (err < 0)
772 return err;
802 773
803 /* MI/ODI/O add on card with AK4114 */ 774 /* MI/ODI/O add on card with AK4114 */
804 if (prodigy192_miodio_exists(ice)) { 775 if (prodigy192_miodio_exists(ice)) {
805 err = prodigy192_ak4114_init(ice); 776 err = prodigy192_ak4114_init(ice);
806 /* from this moment if err = 0 then 777 /* from this moment if err = 0 then
807 * ice->spec.prodigy192.ak4114 should not be null 778 * spec->ak4114 should not be null
808 */ 779 */
809 snd_printdd("AK4114 initialized with status %d\n", err); 780 snd_printdd("AK4114 initialized with status %d\n", err);
810 } else 781 } else
@@ -854,6 +825,10 @@ struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = {
854 .build_controls = prodigy192_add_controls, 825 .build_controls = prodigy192_add_controls,
855 .eeprom_size = sizeof(prodigy71_eeprom), 826 .eeprom_size = sizeof(prodigy71_eeprom),
856 .eeprom_data = prodigy71_eeprom, 827 .eeprom_data = prodigy71_eeprom,
828 /* the current MPU401 code loops infinitely
829 * when opening midi device
830 */
831 .no_mpu401 = 1,
857 }, 832 },
858 { } /* terminator */ 833 { } /* terminator */
859}; 834};
diff --git a/sound/pci/ice1712/prodigy_hifi.c b/sound/pci/ice1712/prodigy_hifi.c
new file mode 100644
index 000000000000..043a93879bd5
--- /dev/null
+++ b/sound/pci/ice1712/prodigy_hifi.c
@@ -0,0 +1,1210 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for Audiotrak Prodigy 7.1 Hifi
5 * based on pontis.c
6 *
7 * Copyright (c) 2007 Julian Scheel <julian@jusst.de>
8 * Copyright (c) 2007 allank
9 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27
28#include <asm/io.h>
29#include <linux/delay.h>
30#include <linux/interrupt.h>
31#include <linux/init.h>
32#include <linux/slab.h>
33#include <linux/mutex.h>
34
35#include <sound/core.h>
36#include <sound/info.h>
37#include <sound/tlv.h>
38
39#include "ice1712.h"
40#include "envy24ht.h"
41#include "prodigy_hifi.h"
42
43struct prodigy_hifi_spec {
44 unsigned short master[2];
45 unsigned short vol[8];
46};
47
48/* I2C addresses */
49#define WM_DEV 0x34
50
51/* WM8776 registers */
52#define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */
53#define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */
54#define WM_HP_MASTER 0x02 /* headphone master (both channels),
55 override LLR */
56#define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */
57#define WM_DAC_ATTEN_R 0x04
58#define WM_DAC_MASTER 0x05
59#define WM_PHASE_SWAP 0x06 /* DAC phase swap */
60#define WM_DAC_CTRL1 0x07
61#define WM_DAC_MUTE 0x08
62#define WM_DAC_CTRL2 0x09
63#define WM_DAC_INT 0x0a
64#define WM_ADC_INT 0x0b
65#define WM_MASTER_CTRL 0x0c
66#define WM_POWERDOWN 0x0d
67#define WM_ADC_ATTEN_L 0x0e
68#define WM_ADC_ATTEN_R 0x0f
69#define WM_ALC_CTRL1 0x10
70#define WM_ALC_CTRL2 0x11
71#define WM_ALC_CTRL3 0x12
72#define WM_NOISE_GATE 0x13
73#define WM_LIMITER 0x14
74#define WM_ADC_MUX 0x15
75#define WM_OUT_MUX 0x16
76#define WM_RESET 0x17
77
78/* Analog Recording Source :- Mic, LineIn, CD/Video, */
79
80/* implement capture source select control for WM8776 */
81
82#define WM_AIN1 "AIN1"
83#define WM_AIN2 "AIN2"
84#define WM_AIN3 "AIN3"
85#define WM_AIN4 "AIN4"
86#define WM_AIN5 "AIN5"
87
88/* GPIO pins of envy24ht connected to wm8766 */
89#define WM8766_SPI_CLK (1<<17) /* CLK, Pin97 on ICE1724 */
90#define WM8766_SPI_MD (1<<16) /* DATA VT1724 -> WM8766, Pin96 */
91#define WM8766_SPI_ML (1<<18) /* Latch, Pin98 */
92
93/* WM8766 registers */
94#define WM8766_DAC_CTRL 0x02 /* DAC Control */
95#define WM8766_INT_CTRL 0x03 /* Interface Control */
96#define WM8766_DAC_CTRL2 0x09
97#define WM8766_DAC_CTRL3 0x0a
98#define WM8766_RESET 0x1f
99#define WM8766_LDA1 0x00
100#define WM8766_LDA2 0x04
101#define WM8766_LDA3 0x06
102#define WM8766_RDA1 0x01
103#define WM8766_RDA2 0x05
104#define WM8766_RDA3 0x07
105#define WM8766_MUTE1 0x0C
106#define WM8766_MUTE2 0x0F
107
108
109/*
110 * Prodigy HD2
111 */
112#define AK4396_ADDR 0x00
113#define AK4396_CSN (1 << 8) /* CSN->GPIO8, pin 75 */
114#define AK4396_CCLK (1 << 9) /* CCLK->GPIO9, pin 76 */
115#define AK4396_CDTI (1 << 10) /* CDTI->GPIO10, pin 77 */
116
117/* ak4396 registers */
118#define AK4396_CTRL1 0x00
119#define AK4396_CTRL2 0x01
120#define AK4396_CTRL3 0x02
121#define AK4396_LCH_ATT 0x03
122#define AK4396_RCH_ATT 0x04
123
124
125/*
126 * get the current register value of WM codec
127 */
128static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
129{
130 reg <<= 1;
131 return ((unsigned short)ice->akm[0].images[reg] << 8) |
132 ice->akm[0].images[reg + 1];
133}
134
135/*
136 * set the register value of WM codec and remember it
137 */
138static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
139{
140 unsigned short cval;
141 cval = (reg << 9) | val;
142 snd_vt1724_write_i2c(ice, WM_DEV, cval >> 8, cval & 0xff);
143}
144
145static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
146{
147 wm_put_nocache(ice, reg, val);
148 reg <<= 1;
149 ice->akm[0].images[reg] = val >> 8;
150 ice->akm[0].images[reg + 1] = val;
151}
152
153/*
154 * write data in the SPI mode
155 */
156
157static void set_gpio_bit(struct snd_ice1712 *ice, unsigned int bit, int val)
158{
159 unsigned int tmp = snd_ice1712_gpio_read(ice);
160 if (val)
161 tmp |= bit;
162 else
163 tmp &= ~bit;
164 snd_ice1712_gpio_write(ice, tmp);
165}
166
167/*
168 * SPI implementation for WM8766 codec - only writing supported, no readback
169 */
170
171static void wm8766_spi_send_word(struct snd_ice1712 *ice, unsigned int data)
172{
173 int i;
174 for (i = 0; i < 16; i++) {
175 set_gpio_bit(ice, WM8766_SPI_CLK, 0);
176 udelay(1);
177 set_gpio_bit(ice, WM8766_SPI_MD, data & 0x8000);
178 udelay(1);
179 set_gpio_bit(ice, WM8766_SPI_CLK, 1);
180 udelay(1);
181 data <<= 1;
182 }
183}
184
185static void wm8766_spi_write(struct snd_ice1712 *ice, unsigned int reg,
186 unsigned int data)
187{
188 unsigned int block;
189
190 snd_ice1712_gpio_set_dir(ice, WM8766_SPI_MD|
191 WM8766_SPI_CLK|WM8766_SPI_ML);
192 snd_ice1712_gpio_set_mask(ice, ~(WM8766_SPI_MD|
193 WM8766_SPI_CLK|WM8766_SPI_ML));
194 /* latch must be low when writing */
195 set_gpio_bit(ice, WM8766_SPI_ML, 0);
196 block = (reg << 9) | (data & 0x1ff);
197 wm8766_spi_send_word(ice, block); /* REGISTER ADDRESS */
198 /* release latch */
199 set_gpio_bit(ice, WM8766_SPI_ML, 1);
200 udelay(1);
201 /* restore */
202 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
203 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
204}
205
206
207/*
208 * serial interface for ak4396 - only writing supported, no readback
209 */
210
211static void ak4396_send_word(struct snd_ice1712 *ice, unsigned int data)
212{
213 int i;
214 for (i = 0; i < 16; i++) {
215 set_gpio_bit(ice, AK4396_CCLK, 0);
216 udelay(1);
217 set_gpio_bit(ice, AK4396_CDTI, data & 0x8000);
218 udelay(1);
219 set_gpio_bit(ice, AK4396_CCLK, 1);
220 udelay(1);
221 data <<= 1;
222 }
223}
224
225static void ak4396_write(struct snd_ice1712 *ice, unsigned int reg,
226 unsigned int data)
227{
228 unsigned int block;
229
230 snd_ice1712_gpio_set_dir(ice, AK4396_CSN|AK4396_CCLK|AK4396_CDTI);
231 snd_ice1712_gpio_set_mask(ice, ~(AK4396_CSN|AK4396_CCLK|AK4396_CDTI));
232 /* latch must be low when writing */
233 set_gpio_bit(ice, AK4396_CSN, 0);
234 block = ((AK4396_ADDR & 0x03) << 14) | (1 << 13) |
235 ((reg & 0x1f) << 8) | (data & 0xff);
236 ak4396_send_word(ice, block); /* REGISTER ADDRESS */
237 /* release latch */
238 set_gpio_bit(ice, AK4396_CSN, 1);
239 udelay(1);
240 /* restore */
241 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask);
242 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
243}
244
245
246/*
247 * ak4396 mixers
248 */
249
250
251
252/*
253 * DAC volume attenuation mixer control (-64dB to 0dB)
254 */
255
256static int ak4396_dac_vol_info(struct snd_kcontrol *kcontrol,
257 struct snd_ctl_elem_info *uinfo)
258{
259 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
260 uinfo->count = 2;
261 uinfo->value.integer.min = 0; /* mute */
262 uinfo->value.integer.max = 0xFF; /* linear */
263 return 0;
264}
265
266static int ak4396_dac_vol_get(struct snd_kcontrol *kcontrol,
267 struct snd_ctl_elem_value *ucontrol)
268{
269 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
270 struct prodigy_hifi_spec *spec = ice->spec;
271 int i;
272
273 for (i = 0; i < 2; i++)
274 ucontrol->value.integer.value[i] = spec->vol[i];
275
276 return 0;
277}
278
279static int ak4396_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
280{
281 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
282 struct prodigy_hifi_spec *spec = ice->spec;
283 int i;
284 int change = 0;
285
286 mutex_lock(&ice->gpio_mutex);
287 for (i = 0; i < 2; i++) {
288 if (ucontrol->value.integer.value[i] != spec->vol[i]) {
289 spec->vol[i] = ucontrol->value.integer.value[i];
290 ak4396_write(ice, AK4396_LCH_ATT + i,
291 spec->vol[i] & 0xff);
292 change = 1;
293 }
294 }
295 mutex_unlock(&ice->gpio_mutex);
296 return change;
297}
298
299static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
300
301static struct snd_kcontrol_new prodigy_hd2_controls[] __devinitdata = {
302 {
303 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
304 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
305 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
306 .name = "Front Playback Volume",
307 .info = ak4396_dac_vol_info,
308 .get = ak4396_dac_vol_get,
309 .put = ak4396_dac_vol_put,
310 .tlv = { .p = db_scale_wm_dac },
311 },
312};
313
314
315/* --------------- */
316
317/*
318 * Logarithmic volume values for WM87*6
319 * Computed as 20 * Log10(255 / x)
320 */
321static const unsigned char wm_vol[256] = {
322 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
323 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
324 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
325 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
326 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
327 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
328 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
329 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
330 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
331 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
332 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
333 0, 0
334};
335
336#define WM_VOL_MAX (sizeof(wm_vol) - 1)
337#define WM_VOL_MUTE 0x8000
338
339
340#define DAC_0dB 0xff
341#define DAC_RES 128
342#define DAC_MIN (DAC_0dB - DAC_RES)
343
344
345static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index,
346 unsigned short vol, unsigned short master)
347{
348 unsigned char nvol;
349
350 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
351 nvol = 0;
352 else {
353 nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128)
354 & WM_VOL_MAX;
355 nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
356 }
357
358 wm_put(ice, index, nvol);
359 wm_put_nocache(ice, index, 0x100 | nvol);
360}
361
362static void wm8766_set_vol(struct snd_ice1712 *ice, unsigned int index,
363 unsigned short vol, unsigned short master)
364{
365 unsigned char nvol;
366
367 if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE))
368 nvol = 0;
369 else {
370 nvol = (((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 128)
371 & WM_VOL_MAX;
372 nvol = (nvol ? (nvol + DAC_MIN) : 0) & 0xff;
373 }
374
375 wm8766_spi_write(ice, index, (0x0100 | nvol));
376}
377
378
379/*
380 * DAC volume attenuation mixer control (-64dB to 0dB)
381 */
382
383static int wm_dac_vol_info(struct snd_kcontrol *kcontrol,
384 struct snd_ctl_elem_info *uinfo)
385{
386 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
387 uinfo->count = 2;
388 uinfo->value.integer.min = 0; /* mute */
389 uinfo->value.integer.max = DAC_RES; /* 0dB, 0.5dB step */
390 return 0;
391}
392
393static int wm_dac_vol_get(struct snd_kcontrol *kcontrol,
394 struct snd_ctl_elem_value *ucontrol)
395{
396 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
397 struct prodigy_hifi_spec *spec = ice->spec;
398 int i;
399
400 for (i = 0; i < 2; i++)
401 ucontrol->value.integer.value[i] =
402 spec->vol[2 + i] & ~WM_VOL_MUTE;
403 return 0;
404}
405
406static int wm_dac_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
407{
408 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
409 struct prodigy_hifi_spec *spec = ice->spec;
410 int i, idx, change = 0;
411
412 mutex_lock(&ice->gpio_mutex);
413 for (i = 0; i < 2; i++) {
414 if (ucontrol->value.integer.value[i] != spec->vol[2 + i]) {
415 idx = WM_DAC_ATTEN_L + i;
416 spec->vol[2 + i] &= WM_VOL_MUTE;
417 spec->vol[2 + i] |= ucontrol->value.integer.value[i];
418 wm_set_vol(ice, idx, spec->vol[2 + i], spec->master[i]);
419 change = 1;
420 }
421 }
422 mutex_unlock(&ice->gpio_mutex);
423 return change;
424}
425
426
427/*
428 * WM8766 DAC volume attenuation mixer control
429 */
430static int wm8766_vol_info(struct snd_kcontrol *kcontrol,
431 struct snd_ctl_elem_info *uinfo)
432{
433 int voices = kcontrol->private_value >> 8;
434 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
435 uinfo->count = voices;
436 uinfo->value.integer.min = 0; /* mute */
437 uinfo->value.integer.max = DAC_RES; /* 0dB */
438 return 0;
439}
440
441static int wm8766_vol_get(struct snd_kcontrol *kcontrol,
442 struct snd_ctl_elem_value *ucontrol)
443{
444 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
445 struct prodigy_hifi_spec *spec = ice->spec;
446 int i, ofs, voices;
447
448 voices = kcontrol->private_value >> 8;
449 ofs = kcontrol->private_value & 0xff;
450 for (i = 0; i < voices; i++)
451 ucontrol->value.integer.value[i] = spec->vol[ofs + i];
452 return 0;
453}
454
455static int wm8766_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
456{
457 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
458 struct prodigy_hifi_spec *spec = ice->spec;
459 int i, idx, ofs, voices;
460 int change = 0;
461
462 voices = kcontrol->private_value >> 8;
463 ofs = kcontrol->private_value & 0xff;
464 mutex_lock(&ice->gpio_mutex);
465 for (i = 0; i < voices; i++) {
466 if (ucontrol->value.integer.value[i] != spec->vol[ofs + i]) {
467 idx = WM8766_LDA1 + ofs + i;
468 spec->vol[ofs + i] &= WM_VOL_MUTE;
469 spec->vol[ofs + i] |= ucontrol->value.integer.value[i];
470 wm8766_set_vol(ice, idx,
471 spec->vol[ofs + i], spec->master[i]);
472 change = 1;
473 }
474 }
475 mutex_unlock(&ice->gpio_mutex);
476 return change;
477}
478
479/*
480 * Master volume attenuation mixer control / applied to WM8776+WM8766
481 */
482static int wm_master_vol_info(struct snd_kcontrol *kcontrol,
483 struct snd_ctl_elem_info *uinfo)
484{
485 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
486 uinfo->count = 2;
487 uinfo->value.integer.min = 0;
488 uinfo->value.integer.max = DAC_RES;
489 return 0;
490}
491
492static int wm_master_vol_get(struct snd_kcontrol *kcontrol,
493 struct snd_ctl_elem_value *ucontrol)
494{
495 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
496 struct prodigy_hifi_spec *spec = ice->spec;
497 int i;
498 for (i = 0; i < 2; i++)
499 ucontrol->value.integer.value[i] = spec->master[i];
500 return 0;
501}
502
503static int wm_master_vol_put(struct snd_kcontrol *kcontrol,
504 struct snd_ctl_elem_value *ucontrol)
505{
506 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
507 struct prodigy_hifi_spec *spec = ice->spec;
508 int ch, change = 0;
509
510 mutex_lock(&ice->gpio_mutex);
511 for (ch = 0; ch < 2; ch++) {
512 if (ucontrol->value.integer.value[ch] != spec->master[ch]) {
513 spec->master[ch] = ucontrol->value.integer.value[ch];
514
515 /* Apply to front DAC */
516 wm_set_vol(ice, WM_DAC_ATTEN_L + ch,
517 spec->vol[2 + ch], spec->master[ch]);
518
519 wm8766_set_vol(ice, WM8766_LDA1 + ch,
520 spec->vol[0 + ch], spec->master[ch]);
521
522 wm8766_set_vol(ice, WM8766_LDA2 + ch,
523 spec->vol[4 + ch], spec->master[ch]);
524
525 wm8766_set_vol(ice, WM8766_LDA3 + ch,
526 spec->vol[6 + ch], spec->master[ch]);
527 change = 1;
528 }
529 }
530 mutex_unlock(&ice->gpio_mutex);
531 return change;
532}
533
534
535/* KONSTI */
536
537static int wm_adc_mux_enum_info(struct snd_kcontrol *kcontrol,
538 struct snd_ctl_elem_info *uinfo)
539{
540 static char* texts[32] = {
541 "NULL", WM_AIN1, WM_AIN2, WM_AIN1 "+" WM_AIN2,
542 WM_AIN3, WM_AIN1 "+" WM_AIN3, WM_AIN2 "+" WM_AIN3,
543 WM_AIN1 "+" WM_AIN2 "+" WM_AIN3,
544 WM_AIN4, WM_AIN1 "+" WM_AIN4, WM_AIN2 "+" WM_AIN4,
545 WM_AIN1 "+" WM_AIN2 "+" WM_AIN4,
546 WM_AIN3 "+" WM_AIN4, WM_AIN1 "+" WM_AIN3 "+" WM_AIN4,
547 WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
548 WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4,
549 WM_AIN5, WM_AIN1 "+" WM_AIN5, WM_AIN2 "+" WM_AIN5,
550 WM_AIN1 "+" WM_AIN2 "+" WM_AIN5,
551 WM_AIN3 "+" WM_AIN5, WM_AIN1 "+" WM_AIN3 "+" WM_AIN5,
552 WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
553 WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN5,
554 WM_AIN4 "+" WM_AIN5, WM_AIN1 "+" WM_AIN4 "+" WM_AIN5,
555 WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
556 WM_AIN1 "+" WM_AIN2 "+" WM_AIN4 "+" WM_AIN5,
557 WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
558 WM_AIN1 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
559 WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5,
560 WM_AIN1 "+" WM_AIN2 "+" WM_AIN3 "+" WM_AIN4 "+" WM_AIN5
561 };
562
563 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
564 uinfo->count = 1;
565 uinfo->value.enumerated.items = 32;
566 if (uinfo->value.enumerated.item > 31)
567 uinfo->value.enumerated.item = 31;
568 strcpy(uinfo->value.enumerated.name,
569 texts[uinfo->value.enumerated.item]);
570 return 0;
571}
572
573static int wm_adc_mux_enum_get(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_value *ucontrol)
575{
576 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
577
578 mutex_lock(&ice->gpio_mutex);
579 ucontrol->value.integer.value[0] = wm_get(ice, WM_ADC_MUX) & 0x1f;
580 mutex_unlock(&ice->gpio_mutex);
581 return 0;
582}
583
584static int wm_adc_mux_enum_put(struct snd_kcontrol *kcontrol,
585 struct snd_ctl_elem_value *ucontrol)
586{
587 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
588 unsigned short oval, nval;
589 int change = 0;
590
591 mutex_lock(&ice->gpio_mutex);
592 oval = wm_get(ice, WM_ADC_MUX);
593 nval = (oval & 0xe0) | ucontrol->value.integer.value[0];
594 if (nval != oval) {
595 wm_put(ice, WM_ADC_MUX, nval);
596 change = 1;
597 }
598 mutex_unlock(&ice->gpio_mutex);
599 return change;
600}
601
602/* KONSTI */
603
604/*
605 * ADC gain mixer control (-64dB to 0dB)
606 */
607
608#define ADC_0dB 0xcf
609#define ADC_RES 128
610#define ADC_MIN (ADC_0dB - ADC_RES)
611
612static int wm_adc_vol_info(struct snd_kcontrol *kcontrol,
613 struct snd_ctl_elem_info *uinfo)
614{
615 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
616 uinfo->count = 2;
617 uinfo->value.integer.min = 0; /* mute (-64dB) */
618 uinfo->value.integer.max = ADC_RES; /* 0dB, 0.5dB step */
619 return 0;
620}
621
622static int wm_adc_vol_get(struct snd_kcontrol *kcontrol,
623 struct snd_ctl_elem_value *ucontrol)
624{
625 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
626 unsigned short val;
627 int i;
628
629 mutex_lock(&ice->gpio_mutex);
630 for (i = 0; i < 2; i++) {
631 val = wm_get(ice, WM_ADC_ATTEN_L + i) & 0xff;
632 val = val > ADC_MIN ? (val - ADC_MIN) : 0;
633 ucontrol->value.integer.value[i] = val;
634 }
635 mutex_unlock(&ice->gpio_mutex);
636 return 0;
637}
638
639static int wm_adc_vol_put(struct snd_kcontrol *kcontrol,
640 struct snd_ctl_elem_value *ucontrol)
641{
642 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
643 unsigned short ovol, nvol;
644 int i, idx, change = 0;
645
646 mutex_lock(&ice->gpio_mutex);
647 for (i = 0; i < 2; i++) {
648 nvol = ucontrol->value.integer.value[i];
649 nvol = nvol ? (nvol + ADC_MIN) : 0;
650 idx = WM_ADC_ATTEN_L + i;
651 ovol = wm_get(ice, idx) & 0xff;
652 if (ovol != nvol) {
653 wm_put(ice, idx, nvol);
654 change = 1;
655 }
656 }
657 mutex_unlock(&ice->gpio_mutex);
658 return change;
659}
660
661/*
662 * ADC input mux mixer control
663 */
664#define wm_adc_mux_info snd_ctl_boolean_mono_info
665
666static int wm_adc_mux_get(struct snd_kcontrol *kcontrol,
667 struct snd_ctl_elem_value *ucontrol)
668{
669 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
670 int bit = kcontrol->private_value;
671
672 mutex_lock(&ice->gpio_mutex);
673 ucontrol->value.integer.value[0] =
674 (wm_get(ice, WM_ADC_MUX) & (1 << bit)) ? 1 : 0;
675 mutex_unlock(&ice->gpio_mutex);
676 return 0;
677}
678
679static int wm_adc_mux_put(struct snd_kcontrol *kcontrol,
680 struct snd_ctl_elem_value *ucontrol)
681{
682 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
683 int bit = kcontrol->private_value;
684 unsigned short oval, nval;
685 int change;
686
687 mutex_lock(&ice->gpio_mutex);
688 nval = oval = wm_get(ice, WM_ADC_MUX);
689 if (ucontrol->value.integer.value[0])
690 nval |= (1 << bit);
691 else
692 nval &= ~(1 << bit);
693 change = nval != oval;
694 if (change) {
695 wm_put(ice, WM_ADC_MUX, nval);
696 }
697 mutex_unlock(&ice->gpio_mutex);
698 return 0;
699}
700
701/*
702 * Analog bypass (In -> Out)
703 */
704#define wm_bypass_info snd_ctl_boolean_mono_info
705
706static int wm_bypass_get(struct snd_kcontrol *kcontrol,
707 struct snd_ctl_elem_value *ucontrol)
708{
709 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
710
711 mutex_lock(&ice->gpio_mutex);
712 ucontrol->value.integer.value[0] =
713 (wm_get(ice, WM_OUT_MUX) & 0x04) ? 1 : 0;
714 mutex_unlock(&ice->gpio_mutex);
715 return 0;
716}
717
718static int wm_bypass_put(struct snd_kcontrol *kcontrol,
719 struct snd_ctl_elem_value *ucontrol)
720{
721 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
722 unsigned short val, oval;
723 int change = 0;
724
725 mutex_lock(&ice->gpio_mutex);
726 val = oval = wm_get(ice, WM_OUT_MUX);
727 if (ucontrol->value.integer.value[0])
728 val |= 0x04;
729 else
730 val &= ~0x04;
731 if (val != oval) {
732 wm_put(ice, WM_OUT_MUX, val);
733 change = 1;
734 }
735 mutex_unlock(&ice->gpio_mutex);
736 return change;
737}
738
739/*
740 * Left/Right swap
741 */
742#define wm_chswap_info snd_ctl_boolean_mono_info
743
744static int wm_chswap_get(struct snd_kcontrol *kcontrol,
745 struct snd_ctl_elem_value *ucontrol)
746{
747 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
748
749 mutex_lock(&ice->gpio_mutex);
750 ucontrol->value.integer.value[0] =
751 (wm_get(ice, WM_DAC_CTRL1) & 0xf0) != 0x90;
752 mutex_unlock(&ice->gpio_mutex);
753 return 0;
754}
755
756static int wm_chswap_put(struct snd_kcontrol *kcontrol,
757 struct snd_ctl_elem_value *ucontrol)
758{
759 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
760 unsigned short val, oval;
761 int change = 0;
762
763 mutex_lock(&ice->gpio_mutex);
764 oval = wm_get(ice, WM_DAC_CTRL1);
765 val = oval & 0x0f;
766 if (ucontrol->value.integer.value[0])
767 val |= 0x60;
768 else
769 val |= 0x90;
770 if (val != oval) {
771 wm_put(ice, WM_DAC_CTRL1, val);
772 wm_put_nocache(ice, WM_DAC_CTRL1, val);
773 change = 1;
774 }
775 mutex_unlock(&ice->gpio_mutex);
776 return change;
777}
778
779
780/*
781 * mixers
782 */
783
784static struct snd_kcontrol_new prodigy_hifi_controls[] __devinitdata = {
785 {
786 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
787 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
788 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
789 .name = "Master Playback Volume",
790 .info = wm_master_vol_info,
791 .get = wm_master_vol_get,
792 .put = wm_master_vol_put,
793 .tlv = { .p = db_scale_wm_dac }
794 },
795 {
796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
797 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
798 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
799 .name = "Front Playback Volume",
800 .info = wm_dac_vol_info,
801 .get = wm_dac_vol_get,
802 .put = wm_dac_vol_put,
803 .tlv = { .p = db_scale_wm_dac },
804 },
805 {
806 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
807 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
808 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
809 .name = "Rear Playback Volume",
810 .info = wm8766_vol_info,
811 .get = wm8766_vol_get,
812 .put = wm8766_vol_put,
813 .private_value = (2 << 8) | 0,
814 .tlv = { .p = db_scale_wm_dac },
815 },
816 {
817 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
818 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
819 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
820 .name = "Center Playback Volume",
821 .info = wm8766_vol_info,
822 .get = wm8766_vol_get,
823 .put = wm8766_vol_put,
824 .private_value = (1 << 8) | 4,
825 .tlv = { .p = db_scale_wm_dac }
826 },
827 {
828 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
829 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
830 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
831 .name = "LFE Playback Volume",
832 .info = wm8766_vol_info,
833 .get = wm8766_vol_get,
834 .put = wm8766_vol_put,
835 .private_value = (1 << 8) | 5,
836 .tlv = { .p = db_scale_wm_dac }
837 },
838 {
839 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
840 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
841 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
842 .name = "Side Playback Volume",
843 .info = wm8766_vol_info,
844 .get = wm8766_vol_get,
845 .put = wm8766_vol_put,
846 .private_value = (2 << 8) | 6,
847 .tlv = { .p = db_scale_wm_dac },
848 },
849 {
850 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
851 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
852 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
853 .name = "Capture Volume",
854 .info = wm_adc_vol_info,
855 .get = wm_adc_vol_get,
856 .put = wm_adc_vol_put,
857 .tlv = { .p = db_scale_wm_dac },
858 },
859 {
860 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
861 .name = "CD Capture Switch",
862 .info = wm_adc_mux_info,
863 .get = wm_adc_mux_get,
864 .put = wm_adc_mux_put,
865 .private_value = 0,
866 },
867 {
868 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
869 .name = "Line Capture Switch",
870 .info = wm_adc_mux_info,
871 .get = wm_adc_mux_get,
872 .put = wm_adc_mux_put,
873 .private_value = 1,
874 },
875 {
876 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
877 .name = "Analog Bypass Switch",
878 .info = wm_bypass_info,
879 .get = wm_bypass_get,
880 .put = wm_bypass_put,
881 },
882 {
883 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
884 .name = "Swap Output Channels",
885 .info = wm_chswap_info,
886 .get = wm_chswap_get,
887 .put = wm_chswap_put,
888 },
889 {
890 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
891 .name = "Analog Capture Source",
892 .info = wm_adc_mux_enum_info,
893 .get = wm_adc_mux_enum_get,
894 .put = wm_adc_mux_enum_put,
895 },
896};
897
898/*
899 * WM codec registers
900 */
901static void wm_proc_regs_write(struct snd_info_entry *entry,
902 struct snd_info_buffer *buffer)
903{
904 struct snd_ice1712 *ice = entry->private_data;
905 char line[64];
906 unsigned int reg, val;
907 mutex_lock(&ice->gpio_mutex);
908 while (!snd_info_get_line(buffer, line, sizeof(line))) {
909 if (sscanf(line, "%x %x", &reg, &val) != 2)
910 continue;
911 if (reg <= 0x17 && val <= 0xffff)
912 wm_put(ice, reg, val);
913 }
914 mutex_unlock(&ice->gpio_mutex);
915}
916
917static void wm_proc_regs_read(struct snd_info_entry *entry,
918 struct snd_info_buffer *buffer)
919{
920 struct snd_ice1712 *ice = entry->private_data;
921 int reg, val;
922
923 mutex_lock(&ice->gpio_mutex);
924 for (reg = 0; reg <= 0x17; reg++) {
925 val = wm_get(ice, reg);
926 snd_iprintf(buffer, "%02x = %04x\n", reg, val);
927 }
928 mutex_unlock(&ice->gpio_mutex);
929}
930
931static void wm_proc_init(struct snd_ice1712 *ice)
932{
933 struct snd_info_entry *entry;
934 if (!snd_card_proc_new(ice->card, "wm_codec", &entry)) {
935 snd_info_set_text_ops(entry, ice, wm_proc_regs_read);
936 entry->mode |= S_IWUSR;
937 entry->c.text.write = wm_proc_regs_write;
938 }
939}
940
941static int __devinit prodigy_hifi_add_controls(struct snd_ice1712 *ice)
942{
943 unsigned int i;
944 int err;
945
946 for (i = 0; i < ARRAY_SIZE(prodigy_hifi_controls); i++) {
947 err = snd_ctl_add(ice->card,
948 snd_ctl_new1(&prodigy_hifi_controls[i], ice));
949 if (err < 0)
950 return err;
951 }
952
953 wm_proc_init(ice);
954
955 return 0;
956}
957
958static int __devinit prodigy_hd2_add_controls(struct snd_ice1712 *ice)
959{
960 unsigned int i;
961 int err;
962
963 for (i = 0; i < ARRAY_SIZE(prodigy_hd2_controls); i++) {
964 err = snd_ctl_add(ice->card,
965 snd_ctl_new1(&prodigy_hd2_controls[i], ice));
966 if (err < 0)
967 return err;
968 }
969
970 wm_proc_init(ice);
971
972 return 0;
973}
974
975
976/*
977 * initialize the chip
978 */
979static int __devinit prodigy_hifi_init(struct snd_ice1712 *ice)
980{
981 static unsigned short wm_inits[] = {
982 /* These come first to reduce init pop noise */
983 WM_ADC_MUX, 0x0003, /* ADC mute */
984 /* 0x00c0 replaced by 0x0003 */
985
986 WM_DAC_MUTE, 0x0001, /* DAC softmute */
987 WM_DAC_CTRL1, 0x0000, /* DAC mute */
988
989 WM_POWERDOWN, 0x0008, /* All power-up except HP */
990 WM_RESET, 0x0000, /* reset */
991 };
992 static unsigned short wm_inits2[] = {
993 WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */
994 WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */
995 WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */
996 WM_DAC_CTRL1, 0x0090, /* DAC L/R */
997 WM_OUT_MUX, 0x0001, /* OUT DAC */
998 WM_HP_ATTEN_L, 0x0179, /* HP 0dB */
999 WM_HP_ATTEN_R, 0x0179, /* HP 0dB */
1000 WM_DAC_ATTEN_L, 0x0000, /* DAC 0dB */
1001 WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */
1002 WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */
1003 WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */
1004 WM_PHASE_SWAP, 0x0000, /* phase normal */
1005#if 0
1006 WM_DAC_MASTER, 0x0100, /* DAC master muted */
1007#endif
1008 WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */
1009 WM_ADC_ATTEN_L, 0x0000, /* ADC muted */
1010 WM_ADC_ATTEN_R, 0x0000, /* ADC muted */
1011#if 1
1012 WM_ALC_CTRL1, 0x007b, /* */
1013 WM_ALC_CTRL2, 0x0000, /* */
1014 WM_ALC_CTRL3, 0x0000, /* */
1015 WM_NOISE_GATE, 0x0000, /* */
1016#endif
1017 WM_DAC_MUTE, 0x0000, /* DAC unmute */
1018 WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */
1019 };
1020 static unsigned short wm8766_inits[] = {
1021 WM8766_RESET, 0x0000,
1022 WM8766_DAC_CTRL, 0x0120,
1023 WM8766_INT_CTRL, 0x0022, /* I2S Normal Mode, 24 bit */
1024 WM8766_DAC_CTRL2, 0x0001,
1025 WM8766_DAC_CTRL3, 0x0080,
1026 WM8766_LDA1, 0x0100,
1027 WM8766_LDA2, 0x0100,
1028 WM8766_LDA3, 0x0100,
1029 WM8766_RDA1, 0x0100,
1030 WM8766_RDA2, 0x0100,
1031 WM8766_RDA3, 0x0100,
1032 WM8766_MUTE1, 0x0000,
1033 WM8766_MUTE2, 0x0000,
1034 };
1035
1036 struct prodigy_hifi_spec *spec;
1037 unsigned int i;
1038
1039 ice->vt1720 = 0;
1040 ice->vt1724 = 1;
1041
1042 ice->num_total_dacs = 8;
1043 ice->num_total_adcs = 1;
1044
1045 /* HACK - use this as the SPDIF source.
1046 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
1047 */
1048 ice->gpio.saved[0] = 0;
1049 /* to remeber the register values */
1050
1051 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1052 if (! ice->akm)
1053 return -ENOMEM;
1054 ice->akm_codecs = 1;
1055
1056 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1057 if (!spec)
1058 return -ENOMEM;
1059 ice->spec = spec;
1060
1061 /* initialize WM8776 codec */
1062 for (i = 0; i < ARRAY_SIZE(wm_inits); i += 2)
1063 wm_put(ice, wm_inits[i], wm_inits[i+1]);
1064 schedule_timeout_uninterruptible(1);
1065 for (i = 0; i < ARRAY_SIZE(wm_inits2); i += 2)
1066 wm_put(ice, wm_inits2[i], wm_inits2[i+1]);
1067
1068 /* initialize WM8766 codec */
1069 for (i = 0; i < ARRAY_SIZE(wm8766_inits); i += 2)
1070 wm8766_spi_write(ice, wm8766_inits[i], wm8766_inits[i+1]);
1071
1072
1073 return 0;
1074}
1075
1076
1077/*
1078 * initialize the chip
1079 */
1080static int __devinit prodigy_hd2_init(struct snd_ice1712 *ice)
1081{
1082 static unsigned short ak4396_inits[] = {
1083 AK4396_CTRL1, 0x87, /* I2S Normal Mode, 24 bit */
1084 AK4396_CTRL2, 0x02,
1085 AK4396_CTRL3, 0x00,
1086 AK4396_LCH_ATT, 0x00,
1087 AK4396_RCH_ATT, 0x00,
1088 };
1089
1090 struct prodigy_hifi_spec *spec;
1091 unsigned int i;
1092
1093 ice->vt1720 = 0;
1094 ice->vt1724 = 1;
1095
1096 ice->num_total_dacs = 1;
1097 ice->num_total_adcs = 1;
1098
1099 /* HACK - use this as the SPDIF source.
1100 * don't call snd_ice1712_gpio_get/put(), otherwise it's overwritten
1101 */
1102 ice->gpio.saved[0] = 0;
1103 /* to remeber the register values */
1104
1105 ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL);
1106 if (! ice->akm)
1107 return -ENOMEM;
1108 ice->akm_codecs = 1;
1109
1110 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1111 if (!spec)
1112 return -ENOMEM;
1113 ice->spec = spec;
1114
1115 /* initialize ak4396 codec */
1116 /* reset codec */
1117 ak4396_write(ice, AK4396_CTRL1, 0x86);
1118 msleep(100);
1119 ak4396_write(ice, AK4396_CTRL1, 0x87);
1120
1121 for (i = 0; i < ARRAY_SIZE(ak4396_inits); i += 2)
1122 ak4396_write(ice, ak4396_inits[i], ak4396_inits[i+1]);
1123
1124 return 0;
1125}
1126
1127
1128static unsigned char prodigy71hifi_eeprom[] __devinitdata = {
1129 0x4b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1130 0x80, /* ACLINK: I2S */
1131 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1132 0xc3, /* SPDIF: out-en, out-int, spdif-in */
1133 0xff, /* GPIO_DIR */
1134 0xff, /* GPIO_DIR1 */
1135 0x5f, /* GPIO_DIR2 */
1136 0x00, /* GPIO_MASK */
1137 0x00, /* GPIO_MASK1 */
1138 0x00, /* GPIO_MASK2 */
1139 0x00, /* GPIO_STATE */
1140 0x00, /* GPIO_STATE1 */
1141 0x00, /* GPIO_STATE2 */
1142};
1143
1144static unsigned char prodigyhd2_eeprom[] __devinitdata = {
1145 0x4b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */
1146 0x80, /* ACLINK: I2S */
1147 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1148 0xc3, /* SPDIF: out-en, out-int, spdif-in */
1149 0xff, /* GPIO_DIR */
1150 0xff, /* GPIO_DIR1 */
1151 0x5f, /* GPIO_DIR2 */
1152 0x00, /* GPIO_MASK */
1153 0x00, /* GPIO_MASK1 */
1154 0x00, /* GPIO_MASK2 */
1155 0x00, /* GPIO_STATE */
1156 0x00, /* GPIO_STATE1 */
1157 0x00, /* GPIO_STATE2 */
1158};
1159
1160static unsigned char fortissimo4_eeprom[] __devinitdata = {
1161 0x43, /* SYSCONF: clock 512, ADC, 4DACs */
1162 0x80, /* ACLINK: I2S */
1163 0xfc, /* I2S: vol, 96k, 24bit, 192k */
1164 0xc1, /* SPDIF: out-en, out-int */
1165 0xff, /* GPIO_DIR */
1166 0xff, /* GPIO_DIR1 */
1167 0x5f, /* GPIO_DIR2 */
1168 0x00, /* GPIO_MASK */
1169 0x00, /* GPIO_MASK1 */
1170 0x00, /* GPIO_MASK2 */
1171 0x00, /* GPIO_STATE */
1172 0x00, /* GPIO_STATE1 */
1173 0x00, /* GPIO_STATE2 */
1174};
1175
1176/* entry point */
1177struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[] __devinitdata = {
1178 {
1179 .subvendor = VT1724_SUBDEVICE_PRODIGY_HIFI,
1180 .name = "Audiotrak Prodigy 7.1 HiFi",
1181 .model = "prodigy71hifi",
1182 .chip_init = prodigy_hifi_init,
1183 .build_controls = prodigy_hifi_add_controls,
1184 .eeprom_size = sizeof(prodigy71hifi_eeprom),
1185 .eeprom_data = prodigy71hifi_eeprom,
1186 .driver = "Prodigy71HIFI",
1187 },
1188 {
1189 .subvendor = VT1724_SUBDEVICE_PRODIGY_HD2,
1190 .name = "Audiotrak Prodigy HD2",
1191 .model = "prodigyhd2",
1192 .chip_init = prodigy_hd2_init,
1193 .build_controls = prodigy_hd2_add_controls,
1194 .eeprom_size = sizeof(prodigyhd2_eeprom),
1195 .eeprom_data = prodigyhd2_eeprom,
1196 .driver = "Prodigy71HD2",
1197 },
1198 {
1199 .subvendor = VT1724_SUBDEVICE_FORTISSIMO4,
1200 .name = "Hercules Fortissimo IV",
1201 .model = "fortissimo4",
1202 .chip_init = prodigy_hifi_init,
1203 .build_controls = prodigy_hifi_add_controls,
1204 .eeprom_size = sizeof(fortissimo4_eeprom),
1205 .eeprom_data = fortissimo4_eeprom,
1206 .driver = "Fortissimo4",
1207 },
1208 { } /* terminator */
1209};
1210
diff --git a/sound/pci/ice1712/prodigy_hifi.h b/sound/pci/ice1712/prodigy_hifi.h
new file mode 100644
index 000000000000..a4415d455d9e
--- /dev/null
+++ b/sound/pci/ice1712/prodigy_hifi.h
@@ -0,0 +1,38 @@
1#ifndef __SOUND_PRODIGY_HIFI_H
2#define __SOUND_PRODIGY_HIFI_H
3
4/*
5 * ALSA driver for VIA VT1724 (Envy24HT)
6 *
7 * Lowlevel functions for Audiotrak Prodigy Hifi
8 *
9 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#define PRODIGY_HIFI_DEVICE_DESC "{Audiotrak,Prodigy 7.1 HIFI},"\
28 "{Audiotrak Prodigy HD2},"\
29 "{Hercules Fortissimo IV},"
30
31#define VT1724_SUBDEVICE_PRODIGY_HIFI 0x38315441 /* PRODIGY 7.1 HIFI */
32#define VT1724_SUBDEVICE_PRODIGY_HD2 0x37315441 /* PRODIGY HD2 */
33#define VT1724_SUBDEVICE_FORTISSIMO4 0x81160100 /* Fortissimo IV */
34
35
36extern struct snd_ice1712_card_info snd_vt1724_prodigy_hifi_cards[];
37
38#endif /* __SOUND_PRODIGY_HIFI_H */
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index d18a31e188a9..ddd5fc8d4fe1 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -21,7 +21,6 @@
21 * 21 *
22 */ 22 */
23 23
24#include <sound/driver.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
@@ -33,6 +32,12 @@
33#include "envy24ht.h" 32#include "envy24ht.h"
34#include "revo.h" 33#include "revo.h"
35 34
35/* a non-standard I2C device for revo51 */
36struct revo51_spec {
37 struct snd_i2c_device *dev;
38 struct snd_pt2258 *pt2258;
39} revo51;
40
36static void revo_i2s_mclk_changed(struct snd_ice1712 *ice) 41static void revo_i2s_mclk_changed(struct snd_ice1712 *ice)
37{ 42{
38 /* assert PRST# to converters; MT05 bit 7 */ 43 /* assert PRST# to converters; MT05 bit 7 */
@@ -153,8 +158,14 @@ static struct snd_i2c_bit_ops revo51_bit_ops = {
153static int revo51_i2c_init(struct snd_ice1712 *ice, 158static int revo51_i2c_init(struct snd_ice1712 *ice,
154 struct snd_pt2258 *pt) 159 struct snd_pt2258 *pt)
155{ 160{
161 struct revo51_spec *spec;
156 int err; 162 int err;
157 163
164 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
165 if (!spec)
166 return -ENOMEM;
167 ice->spec = spec;
168
158 /* create the I2C bus */ 169 /* create the I2C bus */
159 err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c); 170 err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c);
160 if (err < 0) 171 if (err < 0)
@@ -164,15 +175,14 @@ static int revo51_i2c_init(struct snd_ice1712 *ice,
164 ice->i2c->hw_ops.bit = &revo51_bit_ops; 175 ice->i2c->hw_ops.bit = &revo51_bit_ops;
165 176
166 /* create the I2C device */ 177 /* create the I2C device */
167 err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, 178 err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40, &spec->dev);
168 &ice->spec.revo51.dev);
169 if (err < 0) 179 if (err < 0)
170 return err; 180 return err;
171 181
172 pt->card = ice->card; 182 pt->card = ice->card;
173 pt->i2c_bus = ice->i2c; 183 pt->i2c_bus = ice->i2c;
174 pt->i2c_dev = ice->spec.revo51.dev; 184 pt->i2c_dev = spec->dev;
175 ice->spec.revo51.pt2258 = pt; 185 spec->pt2258 = pt;
176 186
177 snd_pt2258_reset(pt); 187 snd_pt2258_reset(pt);
178 188
@@ -556,6 +566,7 @@ static int __devinit revo_init(struct snd_ice1712 *ice)
556 566
557static int __devinit revo_add_controls(struct snd_ice1712 *ice) 567static int __devinit revo_add_controls(struct snd_ice1712 *ice)
558{ 568{
569 struct revo51_spec *spec;
559 int err; 570 int err;
560 571
561 switch (ice->eeprom.subvendor) { 572 switch (ice->eeprom.subvendor) {
@@ -568,7 +579,8 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice)
568 err = snd_ice1712_akm4xxx_build_controls(ice); 579 err = snd_ice1712_akm4xxx_build_controls(ice);
569 if (err < 0) 580 if (err < 0)
570 return err; 581 return err;
571 err = snd_pt2258_build_controls(ice->spec.revo51.pt2258); 582 spec = ice->spec;
583 err = snd_pt2258_build_controls(spec->pt2258);
572 if (err < 0) 584 if (err < 0)
573 return err; 585 return err;
574 break; 586 break;
diff --git a/sound/pci/ice1712/se.c b/sound/pci/ice1712/se.c
new file mode 100644
index 000000000000..69673b95869d
--- /dev/null
+++ b/sound/pci/ice1712/se.c
@@ -0,0 +1,774 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for ONKYO WAVIO SE-90PCI and SE-200PCI
5 *
6 * Copyright (c) 2007 Shin-ya Okada sh_okada(at)d4.dion.ne.jp
7 * (at) -> @
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <asm/io.h>
26#include <linux/delay.h>
27#include <linux/interrupt.h>
28#include <linux/init.h>
29#include <linux/slab.h>
30#include <sound/core.h>
31#include <sound/tlv.h>
32
33#include "ice1712.h"
34#include "envy24ht.h"
35#include "se.h"
36
37struct se_spec {
38 struct {
39 unsigned char ch1, ch2;
40 } vol[8];
41};
42
43/****************************************************************************/
44/* ONKYO WAVIO SE-200PCI */
45/****************************************************************************/
46/*
47 * system configuration ICE_EEP2_SYSCONF=0x4b
48 * XIN1 49.152MHz
49 * not have UART
50 * one stereo ADC and a S/PDIF receiver connected
51 * four stereo DACs connected
52 *
53 * AC-Link configuration ICE_EEP2_ACLINK=0x80
54 * use I2C, not use AC97
55 *
56 * I2S converters feature ICE_EEP2_I2S=0x78
57 * I2S codec has no volume/mute control feature
58 * I2S codec supports 96KHz and 192KHz
59 * I2S codec 24bits
60 *
61 * S/PDIF configuration ICE_EEP2_SPDIF=0xc3
62 * Enable integrated S/PDIF transmitter
63 * internal S/PDIF out implemented
64 * S/PDIF is stereo
65 * External S/PDIF out implemented
66 *
67 *
68 * ** connected chips **
69 *
70 * WM8740
71 * A 2ch-DAC of main outputs.
72 * It setuped as I2S mode by wire, so no way to setup from software.
73 * The sample-rate are automatically changed.
74 * ML/I2S (28pin) --------+
75 * MC/DM1 (27pin) -- 5V |
76 * MD/DM0 (26pin) -- GND |
77 * MUTEB (25pin) -- NC |
78 * MODE (24pin) -- GND |
79 * CSBIW (23pin) --------+
80 * |
81 * RSTB (22pin) --R(1K)-+
82 * Probably it reduce the noise from the control line.
83 *
84 * WM8766
85 * A 6ch-DAC for surrounds.
86 * It's control wire was connected to GPIOxx (3-wire serial interface)
87 * ML/I2S (11pin) -- GPIO18
88 * MC/IWL (12pin) -- GPIO17
89 * MD/DM (13pin) -- GPIO16
90 * MUTE (14pin) -- GPIO01
91 *
92 * WM8776
93 * A 2ch-ADC(with 10ch-selector) plus 2ch-DAC.
94 * It's control wire was connected to SDA/SCLK (2-wire serial interface)
95 * MODE (16pin) -- R(1K) -- GND
96 * CE (17pin) -- R(1K) -- GND 2-wire mode (address=0x34)
97 * DI (18pin) -- SDA
98 * CL (19pin) -- SCLK
99 *
100 *
101 * ** output pins and device names **
102 *
103 * 7.1ch name -- output connector color -- device (-D option)
104 *
105 * FRONT 2ch -- green -- plughw:0,0
106 * CENTER(Lch) SUBWOOFER(Rch) -- black -- plughw:0,2,0
107 * SURROUND 2ch -- orange -- plughw:0,2,1
108 * SURROUND BACK 2ch -- white -- plughw:0,2,2
109 *
110 */
111
112
113/****************************************************************************/
114/* WM8740 interface */
115/****************************************************************************/
116
117static void __devinit se200pci_WM8740_init(struct snd_ice1712 *ice)
118{
119 /* nothing to do */
120}
121
122
123static void se200pci_WM8740_set_pro_rate(struct snd_ice1712 *ice,
124 unsigned int rate)
125{
126 /* nothing to do */
127}
128
129
130/****************************************************************************/
131/* WM8766 interface */
132/****************************************************************************/
133
134static void se200pci_WM8766_write(struct snd_ice1712 *ice,
135 unsigned int addr, unsigned int data)
136{
137 unsigned int st;
138 unsigned int bits;
139 int i;
140 const unsigned int DATA = 0x010000;
141 const unsigned int CLOCK = 0x020000;
142 const unsigned int LOAD = 0x040000;
143 const unsigned int ALL_MASK = (DATA | CLOCK | LOAD);
144
145 snd_ice1712_save_gpio_status(ice);
146
147 st = ((addr & 0x7f) << 9) | (data & 0x1ff);
148 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction | ALL_MASK);
149 snd_ice1712_gpio_set_mask(ice, ice->gpio.write_mask & ~ALL_MASK);
150 bits = snd_ice1712_gpio_read(ice) & ~ALL_MASK;
151
152 snd_ice1712_gpio_write(ice, bits);
153 for (i = 0; i < 16; i++) {
154 udelay(1);
155 bits &= ~CLOCK;
156 st = (st << 1);
157 if (st & 0x10000)
158 bits |= DATA;
159 else
160 bits &= ~DATA;
161
162 snd_ice1712_gpio_write(ice, bits);
163
164 udelay(1);
165 bits |= CLOCK;
166 snd_ice1712_gpio_write(ice, bits);
167 }
168
169 udelay(1);
170 bits |= LOAD;
171 snd_ice1712_gpio_write(ice, bits);
172
173 udelay(1);
174 bits |= (DATA | CLOCK);
175 snd_ice1712_gpio_write(ice, bits);
176
177 snd_ice1712_restore_gpio_status(ice);
178}
179
180static void se200pci_WM8766_set_volume(struct snd_ice1712 *ice, int ch,
181 unsigned int vol1, unsigned int vol2)
182{
183 switch (ch) {
184 case 0:
185 se200pci_WM8766_write(ice, 0x000, vol1);
186 se200pci_WM8766_write(ice, 0x001, vol2 | 0x100);
187 break;
188 case 1:
189 se200pci_WM8766_write(ice, 0x004, vol1);
190 se200pci_WM8766_write(ice, 0x005, vol2 | 0x100);
191 break;
192 case 2:
193 se200pci_WM8766_write(ice, 0x006, vol1);
194 se200pci_WM8766_write(ice, 0x007, vol2 | 0x100);
195 break;
196 }
197}
198
199static void __devinit se200pci_WM8766_init(struct snd_ice1712 *ice)
200{
201 se200pci_WM8766_write(ice, 0x1f, 0x000); /* RESET ALL */
202 udelay(10);
203
204 se200pci_WM8766_set_volume(ice, 0, 0, 0); /* volume L=0 R=0 */
205 se200pci_WM8766_set_volume(ice, 1, 0, 0); /* volume L=0 R=0 */
206 se200pci_WM8766_set_volume(ice, 2, 0, 0); /* volume L=0 R=0 */
207
208 se200pci_WM8766_write(ice, 0x03, 0x022); /* serial mode I2S-24bits */
209 se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */
210 se200pci_WM8766_write(ice, 0x12, 0x000); /* MDP=0 */
211 se200pci_WM8766_write(ice, 0x15, 0x000); /* MDP=0 */
212 se200pci_WM8766_write(ice, 0x09, 0x000); /* demp=off mute=off */
213
214 se200pci_WM8766_write(ice, 0x02, 0x124); /* ch-assign L=L R=R RESET */
215 se200pci_WM8766_write(ice, 0x02, 0x120); /* ch-assign L=L R=R */
216}
217
218static void se200pci_WM8766_set_pro_rate(struct snd_ice1712 *ice,
219 unsigned int rate)
220{
221 if (rate > 96000)
222 se200pci_WM8766_write(ice, 0x0a, 0x000); /* MCLK=128fs */
223 else
224 se200pci_WM8766_write(ice, 0x0a, 0x080); /* MCLK=256fs */
225}
226
227
228/****************************************************************************/
229/* WM8776 interface */
230/****************************************************************************/
231
232static void se200pci_WM8776_write(struct snd_ice1712 *ice,
233 unsigned int addr, unsigned int data)
234{
235 unsigned int val;
236
237 val = (addr << 9) | data;
238 snd_vt1724_write_i2c(ice, 0x34, val >> 8, val & 0xff);
239}
240
241
242static void se200pci_WM8776_set_output_volume(struct snd_ice1712 *ice,
243 unsigned int vol1, unsigned int vol2)
244{
245 se200pci_WM8776_write(ice, 0x03, vol1);
246 se200pci_WM8776_write(ice, 0x04, vol2 | 0x100);
247}
248
249static void se200pci_WM8776_set_input_volume(struct snd_ice1712 *ice,
250 unsigned int vol1, unsigned int vol2)
251{
252 se200pci_WM8776_write(ice, 0x0e, vol1);
253 se200pci_WM8776_write(ice, 0x0f, vol2 | 0x100);
254}
255
256static const char *se200pci_sel[] = {
257 "LINE-IN", "CD-IN", "MIC-IN", "ALL-MIX", NULL
258};
259
260static void se200pci_WM8776_set_input_selector(struct snd_ice1712 *ice,
261 unsigned int sel)
262{
263 static unsigned char vals[] = {
264 /* LINE, CD, MIC, ALL, GND */
265 0x10, 0x04, 0x08, 0x1c, 0x03
266 };
267 if (sel > 4)
268 sel = 4;
269 se200pci_WM8776_write(ice, 0x15, vals[sel]);
270}
271
272static void se200pci_WM8776_set_afl(struct snd_ice1712 *ice, unsigned int afl)
273{
274 /* AFL -- After Fader Listening */
275 if (afl)
276 se200pci_WM8776_write(ice, 0x16, 0x005);
277 else
278 se200pci_WM8776_write(ice, 0x16, 0x001);
279}
280
281static const char *se200pci_agc[] = {
282 "Off", "LimiterMode", "ALCMode", NULL
283};
284
285static void se200pci_WM8776_set_agc(struct snd_ice1712 *ice, unsigned int agc)
286{
287 /* AGC -- Auto Gain Control of the input */
288 switch (agc) {
289 case 0:
290 se200pci_WM8776_write(ice, 0x11, 0x000); /* Off */
291 break;
292 case 1:
293 se200pci_WM8776_write(ice, 0x10, 0x07b);
294 se200pci_WM8776_write(ice, 0x11, 0x100); /* LimiterMode */
295 break;
296 case 2:
297 se200pci_WM8776_write(ice, 0x10, 0x1fb);
298 se200pci_WM8776_write(ice, 0x11, 0x100); /* ALCMode */
299 break;
300 }
301}
302
303static void __devinit se200pci_WM8776_init(struct snd_ice1712 *ice)
304{
305 int i;
306 static unsigned short __devinitdata default_values[] = {
307 0x100, 0x100, 0x100,
308 0x100, 0x100, 0x100,
309 0x000, 0x090, 0x000, 0x000,
310 0x022, 0x022, 0x022,
311 0x008, 0x0cf, 0x0cf, 0x07b, 0x000,
312 0x032, 0x000, 0x0a6, 0x001, 0x001
313 };
314
315 se200pci_WM8776_write(ice, 0x17, 0x000); /* reset all */
316 /* ADC and DAC interface is I2S 24bits mode */
317 /* The sample-rate are automatically changed */
318 udelay(10);
319 /* BUT my board can not do reset all, so I load all by manually. */
320 for (i = 0; i < ARRAY_SIZE(default_values); i++)
321 se200pci_WM8776_write(ice, i, default_values[i]);
322
323 se200pci_WM8776_set_input_selector(ice, 0);
324 se200pci_WM8776_set_afl(ice, 0);
325 se200pci_WM8776_set_agc(ice, 0);
326 se200pci_WM8776_set_input_volume(ice, 0, 0);
327 se200pci_WM8776_set_output_volume(ice, 0, 0);
328
329 /* head phone mute and power down */
330 se200pci_WM8776_write(ice, 0x00, 0);
331 se200pci_WM8776_write(ice, 0x01, 0);
332 se200pci_WM8776_write(ice, 0x02, 0x100);
333 se200pci_WM8776_write(ice, 0x0d, 0x080);
334}
335
336static void se200pci_WM8776_set_pro_rate(struct snd_ice1712 *ice,
337 unsigned int rate)
338{
339 /* nothing to do */
340}
341
342
343/****************************************************************************/
344/* runtime interface */
345/****************************************************************************/
346
347static void se200pci_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate)
348{
349 se200pci_WM8740_set_pro_rate(ice, rate);
350 se200pci_WM8766_set_pro_rate(ice, rate);
351 se200pci_WM8776_set_pro_rate(ice, rate);
352}
353
354struct se200pci_control {
355 char *name;
356 enum {
357 WM8766,
358 WM8776in,
359 WM8776out,
360 WM8776sel,
361 WM8776agc,
362 WM8776afl
363 } target;
364 enum { VOLUME1, VOLUME2, BOOLEAN, ENUM } type;
365 int ch;
366 const char **member;
367 const char *comment;
368};
369
370static const struct se200pci_control se200pci_cont[] = {
371 {
372 .name = "Front Playback Volume",
373 .target = WM8776out,
374 .type = VOLUME1,
375 .comment = "Front(green)"
376 },
377 {
378 .name = "Side Playback Volume",
379 .target = WM8766,
380 .type = VOLUME1,
381 .ch = 1,
382 .comment = "Surround(orange)"
383 },
384 {
385 .name = "Surround Playback Volume",
386 .target = WM8766,
387 .type = VOLUME1,
388 .ch = 2,
389 .comment = "SurroundBack(white)"
390 },
391 {
392 .name = "CLFE Playback Volume",
393 .target = WM8766,
394 .type = VOLUME1,
395 .ch = 0,
396 .comment = "Center(Lch)&SubWoofer(Rch)(black)"
397 },
398 {
399 .name = "Capture Volume",
400 .target = WM8776in,
401 .type = VOLUME2
402 },
403 {
404 .name = "Capture Select",
405 .target = WM8776sel,
406 .type = ENUM,
407 .member = se200pci_sel
408 },
409 {
410 .name = "AGC Capture Mode",
411 .target = WM8776agc,
412 .type = ENUM,
413 .member = se200pci_agc
414 },
415 {
416 .name = "AFL Bypass Playback Switch",
417 .target = WM8776afl,
418 .type = BOOLEAN
419 }
420};
421
422static int se200pci_get_enum_count(int n)
423{
424 const char **member;
425 int c;
426
427 member = se200pci_cont[n].member;
428 if (!member)
429 return 0;
430 for (c = 0; member[c]; c++)
431 ;
432 return c;
433}
434
435static int se200pci_cont_volume_info(struct snd_kcontrol *kc,
436 struct snd_ctl_elem_info *uinfo)
437{
438 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
439 uinfo->count = 2;
440 uinfo->value.integer.min = 0; /* mute */
441 uinfo->value.integer.max = 0xff; /* 0dB */
442 return 0;
443}
444
445#define se200pci_cont_boolean_info snd_ctl_boolean_mono_info
446
447static int se200pci_cont_enum_info(struct snd_kcontrol *kc,
448 struct snd_ctl_elem_info *uinfo)
449{
450 int n, c;
451
452 n = kc->private_value;
453 c = se200pci_get_enum_count(n);
454 if (!c)
455 return -EINVAL;
456 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
457 uinfo->count = 1;
458 uinfo->value.enumerated.items = c;
459 if (uinfo->value.enumerated.item >= c)
460 uinfo->value.enumerated.item = c - 1;
461 strcpy(uinfo->value.enumerated.name,
462 se200pci_cont[n].member[uinfo->value.enumerated.item]);
463 return 0;
464}
465
466static int se200pci_cont_volume_get(struct snd_kcontrol *kc,
467 struct snd_ctl_elem_value *uc)
468{
469 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
470 struct se_spec *spec = ice->spec;
471 int n = kc->private_value;
472 uc->value.integer.value[0] = spec->vol[n].ch1;
473 uc->value.integer.value[1] = spec->vol[n].ch2;
474 return 0;
475}
476
477static int se200pci_cont_boolean_get(struct snd_kcontrol *kc,
478 struct snd_ctl_elem_value *uc)
479{
480 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
481 struct se_spec *spec = ice->spec;
482 int n = kc->private_value;
483 uc->value.integer.value[0] = spec->vol[n].ch1;
484 return 0;
485}
486
487static int se200pci_cont_enum_get(struct snd_kcontrol *kc,
488 struct snd_ctl_elem_value *uc)
489{
490 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
491 struct se_spec *spec = ice->spec;
492 int n = kc->private_value;
493 uc->value.enumerated.item[0] = spec->vol[n].ch1;
494 return 0;
495}
496
497static void se200pci_cont_update(struct snd_ice1712 *ice, int n)
498{
499 struct se_spec *spec = ice->spec;
500 switch (se200pci_cont[n].target) {
501 case WM8766:
502 se200pci_WM8766_set_volume(ice,
503 se200pci_cont[n].ch,
504 spec->vol[n].ch1,
505 spec->vol[n].ch2);
506 break;
507
508 case WM8776in:
509 se200pci_WM8776_set_input_volume(ice,
510 spec->vol[n].ch1,
511 spec->vol[n].ch2);
512 break;
513
514 case WM8776out:
515 se200pci_WM8776_set_output_volume(ice,
516 spec->vol[n].ch1,
517 spec->vol[n].ch2);
518 break;
519
520 case WM8776sel:
521 se200pci_WM8776_set_input_selector(ice,
522 spec->vol[n].ch1);
523 break;
524
525 case WM8776agc:
526 se200pci_WM8776_set_agc(ice, spec->vol[n].ch1);
527 break;
528
529 case WM8776afl:
530 se200pci_WM8776_set_afl(ice, spec->vol[n].ch1);
531 break;
532
533 default:
534 break;
535 }
536}
537
538static int se200pci_cont_volume_put(struct snd_kcontrol *kc,
539 struct snd_ctl_elem_value *uc)
540{
541 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
542 struct se_spec *spec = ice->spec;
543 int n = kc->private_value;
544 unsigned int vol1, vol2;
545 int changed;
546
547 changed = 0;
548 vol1 = uc->value.integer.value[0] & 0xff;
549 vol2 = uc->value.integer.value[1] & 0xff;
550 if (spec->vol[n].ch1 != vol1) {
551 spec->vol[n].ch1 = vol1;
552 changed = 1;
553 }
554 if (spec->vol[n].ch2 != vol2) {
555 spec->vol[n].ch2 = vol2;
556 changed = 1;
557 }
558 if (changed)
559 se200pci_cont_update(ice, n);
560
561 return changed;
562}
563
564static int se200pci_cont_boolean_put(struct snd_kcontrol *kc,
565 struct snd_ctl_elem_value *uc)
566{
567 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
568 struct se_spec *spec = ice->spec;
569 int n = kc->private_value;
570 unsigned int vol1;
571
572 vol1 = !!uc->value.integer.value[0];
573 if (spec->vol[n].ch1 != vol1) {
574 spec->vol[n].ch1 = vol1;
575 se200pci_cont_update(ice, n);
576 return 1;
577 }
578 return 0;
579}
580
581static int se200pci_cont_enum_put(struct snd_kcontrol *kc,
582 struct snd_ctl_elem_value *uc)
583{
584 struct snd_ice1712 *ice = snd_kcontrol_chip(kc);
585 struct se_spec *spec = ice->spec;
586 int n = kc->private_value;
587 unsigned int vol1;
588
589 vol1 = uc->value.enumerated.item[0];
590 if (vol1 >= se200pci_get_enum_count(n))
591 return -EINVAL;
592 if (spec->vol[n].ch1 != vol1) {
593 spec->vol[n].ch1 = vol1;
594 se200pci_cont_update(ice, n);
595 return 1;
596 }
597 return 0;
598}
599
600static const DECLARE_TLV_DB_SCALE(db_scale_gain1, -12750, 50, 1);
601static const DECLARE_TLV_DB_SCALE(db_scale_gain2, -10350, 50, 1);
602
603static int __devinit se200pci_add_controls(struct snd_ice1712 *ice)
604{
605 int i;
606 struct snd_kcontrol_new cont;
607 int err;
608
609 memset(&cont, 0, sizeof(cont));
610 cont.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
611 for (i = 0; i < ARRAY_SIZE(se200pci_cont); i++) {
612 cont.private_value = i;
613 cont.name = se200pci_cont[i].name;
614 cont.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
615 cont.tlv.p = NULL;
616 switch (se200pci_cont[i].type) {
617 case VOLUME1:
618 case VOLUME2:
619 cont.info = se200pci_cont_volume_info;
620 cont.get = se200pci_cont_volume_get;
621 cont.put = se200pci_cont_volume_put;
622 cont.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
623 if (se200pci_cont[i].type == VOLUME1)
624 cont.tlv.p = db_scale_gain1;
625 else
626 cont.tlv.p = db_scale_gain2;
627 break;
628 case BOOLEAN:
629 cont.info = se200pci_cont_boolean_info;
630 cont.get = se200pci_cont_boolean_get;
631 cont.put = se200pci_cont_boolean_put;
632 break;
633 case ENUM:
634 cont.info = se200pci_cont_enum_info;
635 cont.get = se200pci_cont_enum_get;
636 cont.put = se200pci_cont_enum_put;
637 break;
638 default:
639 snd_BUG();
640 return -EINVAL;
641 }
642 err = snd_ctl_add(ice->card, snd_ctl_new1(&cont, ice));
643 if (err < 0)
644 return err;
645 }
646
647 return 0;
648}
649
650
651/****************************************************************************/
652/* ONKYO WAVIO SE-90PCI */
653/****************************************************************************/
654/*
655 * system configuration ICE_EEP2_SYSCONF=0x4b
656 * AC-Link configuration ICE_EEP2_ACLINK=0x80
657 * I2S converters feature ICE_EEP2_I2S=0x78
658 * S/PDIF configuration ICE_EEP2_SPDIF=0xc3
659 *
660 * ** connected chip **
661 *
662 * WM8716
663 * A 2ch-DAC of main outputs.
664 * It setuped as I2S mode by wire, so no way to setup from software.
665 * ML/I2S (28pin) -- +5V
666 * MC/DM1 (27pin) -- GND
667 * MC/DM0 (26pin) -- GND
668 * MUTEB (25pin) -- open (internal pull-up)
669 * MODE (24pin) -- GND
670 * CSBIWO (23pin) -- +5V
671 *
672 */
673
674 /* Nothing to do for this chip. */
675
676
677/****************************************************************************/
678/* probe/initialize/setup */
679/****************************************************************************/
680
681static int __devinit se_init(struct snd_ice1712 *ice)
682{
683 struct se_spec *spec;
684
685 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
686 if (!spec)
687 return -ENOMEM;
688 ice->spec = spec;
689
690 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE90PCI) {
691 ice->num_total_dacs = 2;
692 ice->num_total_adcs = 0;
693 ice->vt1720 = 1;
694 return 0;
695
696 } else if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI) {
697 ice->num_total_dacs = 8;
698 ice->num_total_adcs = 2;
699 se200pci_WM8740_init(ice);
700 se200pci_WM8766_init(ice);
701 se200pci_WM8776_init(ice);
702 ice->gpio.set_pro_rate = se200pci_set_pro_rate;
703 return 0;
704 }
705
706 return -ENOENT;
707}
708
709static int __devinit se_add_controls(struct snd_ice1712 *ice)
710{
711 int err;
712
713 err = 0;
714 /* nothing to do for VT1724_SUBDEVICE_SE90PCI */
715 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_SE200PCI)
716 err = se200pci_add_controls(ice);
717
718 return err;
719}
720
721
722/****************************************************************************/
723/* entry point */
724/****************************************************************************/
725
726static unsigned char se200pci_eeprom[] __devinitdata = {
727 [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */
728 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
729 [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */
730 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
731
732 [ICE_EEP2_GPIO_DIR] = 0x02, /* WM8766 mute 1=output */
733 [ICE_EEP2_GPIO_DIR1] = 0x00, /* not used */
734 [ICE_EEP2_GPIO_DIR2] = 0x07, /* WM8766 ML/MC/MD 1=output */
735
736 [ICE_EEP2_GPIO_MASK] = 0x00, /* 0=writable */
737 [ICE_EEP2_GPIO_MASK1] = 0x00, /* 0=writable */
738 [ICE_EEP2_GPIO_MASK2] = 0x00, /* 0=writable */
739
740 [ICE_EEP2_GPIO_STATE] = 0x00, /* WM8766 mute=0 */
741 [ICE_EEP2_GPIO_STATE1] = 0x00, /* not used */
742 [ICE_EEP2_GPIO_STATE2] = 0x07, /* WM8766 ML/MC/MD */
743};
744
745static unsigned char se90pci_eeprom[] __devinitdata = {
746 [ICE_EEP2_SYSCONF] = 0x4b, /* 49.152Hz, spdif-in/ADC, 4DACs */
747 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
748 [ICE_EEP2_I2S] = 0x78, /* 96k-ok, 24bit, 192k-ok */
749 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
750
751 /* ALL GPIO bits are in input mode */
752};
753
754struct snd_ice1712_card_info snd_vt1724_se_cards[] __devinitdata = {
755 {
756 .subvendor = VT1724_SUBDEVICE_SE200PCI,
757 .name = "ONKYO SE200PCI",
758 .model = "se200pci",
759 .chip_init = se_init,
760 .build_controls = se_add_controls,
761 .eeprom_size = sizeof(se200pci_eeprom),
762 .eeprom_data = se200pci_eeprom,
763 },
764 {
765 .subvendor = VT1724_SUBDEVICE_SE90PCI,
766 .name = "ONKYO SE90PCI",
767 .model = "se90pci",
768 .chip_init = se_init,
769 .build_controls = se_add_controls,
770 .eeprom_size = sizeof(se90pci_eeprom),
771 .eeprom_data = se90pci_eeprom,
772 },
773 {} /*terminator*/
774};
diff --git a/sound/pci/ice1712/se.h b/sound/pci/ice1712/se.h
new file mode 100644
index 000000000000..0b0a9dabdcfb
--- /dev/null
+++ b/sound/pci/ice1712/se.h
@@ -0,0 +1,15 @@
1#ifndef __SOUND_SE_H
2#define __SOUND_SE_H
3
4/* ID */
5#define SE_DEVICE_DESC \
6 "{ONKYO INC,SE-90PCI},"\
7 "{ONKYO INC,SE-200PCI},"
8
9#define VT1724_SUBDEVICE_SE90PCI 0xb161000
10#define VT1724_SUBDEVICE_SE200PCI 0xb160100
11
12/* entry struct */
13extern struct snd_ice1712_card_info snd_vt1724_se_cards[];
14
15#endif /* __SOUND_SE_H */
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
index 239524158fe7..7f9674b641c0 100644
--- a/sound/pci/ice1712/vt1720_mobo.c
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -21,7 +21,6 @@
21 * 21 *
22 */ 22 */
23 23
24#include <sound/driver.h>
25#include <asm/io.h> 24#include <asm/io.h>
26#include <linux/delay.h> 25#include <linux/delay.h>
27#include <linux/interrupt.h> 26#include <linux/interrupt.h>
diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c
index 7fcce0a506d6..a08d17c7e651 100644
--- a/sound/pci/ice1712/wtm.c
+++ b/sound/pci/ice1712/wtm.c
@@ -25,7 +25,6 @@
25 25
26 26
27 27
28#include <sound/driver.h>
29#include <asm/io.h> 28#include <asm/io.h>
30#include <linux/delay.h> 29#include <linux/delay.h>
31#include <linux/interrupt.h> 30#include <linux/interrupt.h>
@@ -178,7 +177,7 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
178 177
179 if (kcontrol->private_value) { 178 if (kcontrol->private_value) {
180 idx = STAC946X_MASTER_VOLUME; 179 idx = STAC946X_MASTER_VOLUME;
181 nvol = ucontrol->value.integer.value[0]; 180 nvol = ucontrol->value.integer.value[0] & 0x7f;
182 tmp = stac9460_get(ice, idx); 181 tmp = stac9460_get(ice, idx);
183 ovol = 0x7f - (tmp & 0x7f); 182 ovol = 0x7f - (tmp & 0x7f);
184 change = (ovol != nvol); 183 change = (ovol != nvol);
@@ -189,7 +188,7 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
189 } else { 188 } else {
190 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 189 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
191 idx = id + STAC946X_LF_VOLUME; 190 idx = id + STAC946X_LF_VOLUME;
192 nvol = ucontrol->value.integer.value[0]; 191 nvol = ucontrol->value.integer.value[0] & 0x7f;
193 if (id < 6) 192 if (id < 6)
194 tmp = stac9460_get(ice, idx); 193 tmp = stac9460_get(ice, idx);
195 else 194 else
@@ -317,7 +316,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
317 if (id == 0) { 316 if (id == 0) {
318 for (i = 0; i < 2; ++i) { 317 for (i = 0; i < 2; ++i) {
319 reg = STAC946X_MIC_L_VOLUME + i; 318 reg = STAC946X_MIC_L_VOLUME + i;
320 nvol = ucontrol->value.integer.value[i]; 319 nvol = ucontrol->value.integer.value[i] & 0x0f;
321 ovol = 0x0f - stac9460_get(ice, reg); 320 ovol = 0x0f - stac9460_get(ice, reg);
322 change = ((ovol & 0x0f) != nvol); 321 change = ((ovol & 0x0f) != nvol);
323 if (change) 322 if (change)
@@ -327,7 +326,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
327 } else { 326 } else {
328 for (i = 0; i < 2; ++i) { 327 for (i = 0; i < 2; ++i) {
329 reg = STAC946X_MIC_L_VOLUME + i; 328 reg = STAC946X_MIC_L_VOLUME + i;
330 nvol = ucontrol->value.integer.value[i]; 329 nvol = ucontrol->value.integer.value[i] & 0x0f;
331 ovol = 0x0f - stac9460_2_get(ice, reg); 330 ovol = 0x0f - stac9460_2_get(ice, reg);
332 change = ((ovol & 0x0f) != nvol); 331 change = ((ovol & 0x0f) != nvol);
333 if (change) 332 if (change)