aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-09 11:24:04 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-02-09 11:24:04 -0500
commit6026179519896e7d35b2564e7544487d1c8948e7 (patch)
treec78c7032abce24d846423572204f1cd4e97d8efc /sound/pci
parentd27146dd5b72ab7d7e641f56f4bee1484dabd0b7 (diff)
parentc2902c8ae06762d941fab64198467f78cab6f8cd (diff)
Merge branch 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa
* 'linus' of master.kernel.org:/pub/scm/linux/kernel/git/perex/alsa: (212 commits) [PATCH] Fix breakage with CONFIG_SYSFS_DEPRECATED [ALSA] version 1.0.14rc2 [ALSA] ASoC documentation updates [ALSA] ca0106 - Add missing sysfs device assignment [ALSA] aoa i2sbus: Stop Apple i2s DMA gracefully [ALSA] hda-codec - Add support for Fujitsu PI1556 Realtek ALC880 [ALSA] aoa: remove suspend/resume printks [ALSA] Fix possible deadlocks in sequencer at removal of ports [ALSA] emu10k1 - Fix STAC9758 front channel [ALSA] soc - Clean up with kmemdup() [ALSA] snd-ak4114: Fix two array overflows [ALSA] ac97_bus power management [ALSA] usbaudio - Add support for Edirol UA-101 [ALSA] hda-codec - Add ALC861VD/ALC660VD support [ALSA] soc - ASoC 0.13 Sharp poodle machine [ALSA] soc - ASoC 0.13 Sharp tosa machine [ALSA] soc - ASoC 0.13 spitz machine [ALSA] soc - ASoC Sharp corgi machine [ALSA] soc - ASoC 0.13 pxa2xx DMA [ALSA] soc - ASoC 0.13 pxa2xx AC97 driver ...
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/Kconfig30
-rw-r--r--sound/pci/ac97/ac97_codec.c64
-rw-r--r--sound/pci/ac97/ac97_patch.c549
-rw-r--r--sound/pci/ac97/ac97_patch.h1
-rw-r--r--sound/pci/ac97/ak4531_codec.c6
-rw-r--r--sound/pci/als300.c6
-rw-r--r--sound/pci/atiixp.c31
-rw-r--r--sound/pci/atiixp_modem.c2
-rw-r--r--sound/pci/ca0106/ca0106_main.c21
-rw-r--r--sound/pci/ca0106/ca0106_mixer.c50
-rw-r--r--sound/pci/cs4281.c2
-rw-r--r--sound/pci/echoaudio/darla20.c1
-rw-r--r--sound/pci/echoaudio/darla24.c1
-rw-r--r--sound/pci/echoaudio/echo3g.c1
-rw-r--r--sound/pci/echoaudio/echo3g_dsp.c2
-rw-r--r--sound/pci/echoaudio/echoaudio.c18
-rw-r--r--sound/pci/echoaudio/gina20.c1
-rw-r--r--sound/pci/echoaudio/gina24.c1
-rw-r--r--sound/pci/echoaudio/indigo.c1
-rw-r--r--sound/pci/echoaudio/indigodj.c1
-rw-r--r--sound/pci/echoaudio/indigoio.c1
-rw-r--r--sound/pci/echoaudio/layla20.c1
-rw-r--r--sound/pci/echoaudio/layla24.c1
-rw-r--r--sound/pci/echoaudio/mia.c1
-rw-r--r--sound/pci/echoaudio/mona.c1
-rw-r--r--sound/pci/emu10k1/emu10k1_main.c616
-rw-r--r--sound/pci/emu10k1/emu10k1x.c6
-rw-r--r--sound/pci/emu10k1/emufx.c204
-rw-r--r--sound/pci/emu10k1/emumixer.c745
-rw-r--r--sound/pci/emu10k1/emupcm.c147
-rw-r--r--sound/pci/emu10k1/emuproc.c34
-rw-r--r--sound/pci/emu10k1/io.c104
-rw-r--r--sound/pci/emu10k1/p16v.c14
-rw-r--r--sound/pci/emu10k1/p17v.h47
-rw-r--r--sound/pci/emu10k1/voice.c2
-rw-r--r--sound/pci/ens1370.c154
-rw-r--r--sound/pci/es1938.c2
-rw-r--r--sound/pci/fm801.c2
-rw-r--r--sound/pci/hda/Makefile11
-rw-r--r--sound/pci/hda/hda_codec.c68
-rw-r--r--sound/pci/hda/hda_intel.c33
-rw-r--r--sound/pci/hda/hda_local.h12
-rw-r--r--sound/pci/hda/hda_patch.h6
-rw-r--r--sound/pci/hda/patch_analog.c165
-rw-r--r--sound/pci/hda/patch_cmedia.c24
-rw-r--r--sound/pci/hda/patch_conexant.c1311
-rw-r--r--sound/pci/hda/patch_realtek.c2367
-rw-r--r--sound/pci/hda/patch_sigmatel.c692
-rw-r--r--sound/pci/hda/patch_via.c1396
-rw-r--r--sound/pci/ice1712/Makefile2
-rw-r--r--sound/pci/ice1712/amp.c4
-rw-r--r--sound/pci/ice1712/amp.h2
-rw-r--r--sound/pci/ice1712/aureon.c186
-rw-r--r--sound/pci/ice1712/aureon.h6
-rw-r--r--sound/pci/ice1712/delta.c34
-rw-r--r--sound/pci/ice1712/delta.h2
-rw-r--r--sound/pci/ice1712/ews.c24
-rw-r--r--sound/pci/ice1712/ews.h2
-rw-r--r--sound/pci/ice1712/hoontech.c7
-rw-r--r--sound/pci/ice1712/hoontech.h2
-rw-r--r--sound/pci/ice1712/ice1712.c74
-rw-r--r--sound/pci/ice1712/ice1712.h18
-rw-r--r--sound/pci/ice1712/ice1724.c78
-rw-r--r--sound/pci/ice1712/juli.c36
-rw-r--r--sound/pci/ice1712/juli.h2
-rw-r--r--sound/pci/ice1712/phase.c76
-rw-r--r--sound/pci/ice1712/phase.h2
-rw-r--r--sound/pci/ice1712/pontis.c42
-rw-r--r--sound/pci/ice1712/pontis.h2
-rw-r--r--sound/pci/ice1712/prodigy192.c40
-rw-r--r--sound/pci/ice1712/prodigy192.h2
-rw-r--r--sound/pci/ice1712/revo.c372
-rw-r--r--sound/pci/ice1712/revo.h13
-rw-r--r--sound/pci/ice1712/vt1720_mobo.c59
-rw-r--r--sound/pci/ice1712/vt1720_mobo.h2
-rw-r--r--sound/pci/ice1712/wtm.c542
-rw-r--r--sound/pci/ice1712/wtm.h20
-rw-r--r--sound/pci/intel8x0.c208
-rw-r--r--sound/pci/intel8x0m.c120
-rw-r--r--sound/pci/korg1212/korg1212.c45
-rw-r--r--sound/pci/maestro3.c373
-rw-r--r--sound/pci/mixart/mixart_mixer.c4
-rw-r--r--sound/pci/nm256/nm256.c56
-rw-r--r--sound/pci/pcxhr/pcxhr_mixer.c6
-rw-r--r--sound/pci/rme9652/hdsp.c38
-rw-r--r--sound/pci/rme9652/hdspm.c1242
-rw-r--r--sound/pci/trident/trident_main.c4
-rw-r--r--sound/pci/via82xx.c134
-rw-r--r--sound/pci/via82xx_modem.c2
-rw-r--r--sound/pci/vx222/vx222.c4
-rw-r--r--sound/pci/vx222/vx222_ops.c2
-rw-r--r--sound/pci/ymfpci/ymfpci_image.h6
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c171
93 files changed, 10903 insertions, 2119 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 8a6b1803c763..1bcfb3aac18d 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -236,7 +236,7 @@ config SND_CS5535AUDIO
236config SND_DARLA20 236config SND_DARLA20
237 tristate "(Echoaudio) Darla20" 237 tristate "(Echoaudio) Darla20"
238 depends on SND 238 depends on SND
239 depends on FW_LOADER 239 select FW_LOADER
240 select SND_PCM 240 select SND_PCM
241 help 241 help
242 Say 'Y' or 'M' to include support for Echoaudio Darla. 242 Say 'Y' or 'M' to include support for Echoaudio Darla.
@@ -247,7 +247,7 @@ config SND_DARLA20
247config SND_GINA20 247config SND_GINA20
248 tristate "(Echoaudio) Gina20" 248 tristate "(Echoaudio) Gina20"
249 depends on SND 249 depends on SND
250 depends on FW_LOADER 250 select FW_LOADER
251 select SND_PCM 251 select SND_PCM
252 help 252 help
253 Say 'Y' or 'M' to include support for Echoaudio Gina. 253 Say 'Y' or 'M' to include support for Echoaudio Gina.
@@ -258,7 +258,7 @@ config SND_GINA20
258config SND_LAYLA20 258config SND_LAYLA20
259 tristate "(Echoaudio) Layla20" 259 tristate "(Echoaudio) Layla20"
260 depends on SND 260 depends on SND
261 depends on FW_LOADER 261 select FW_LOADER
262 select SND_RAWMIDI 262 select SND_RAWMIDI
263 select SND_PCM 263 select SND_PCM
264 help 264 help
@@ -270,7 +270,7 @@ config SND_LAYLA20
270config SND_DARLA24 270config SND_DARLA24
271 tristate "(Echoaudio) Darla24" 271 tristate "(Echoaudio) Darla24"
272 depends on SND 272 depends on SND
273 depends on FW_LOADER 273 select FW_LOADER
274 select SND_PCM 274 select SND_PCM
275 help 275 help
276 Say 'Y' or 'M' to include support for Echoaudio Darla24. 276 Say 'Y' or 'M' to include support for Echoaudio Darla24.
@@ -281,7 +281,7 @@ config SND_DARLA24
281config SND_GINA24 281config SND_GINA24
282 tristate "(Echoaudio) Gina24" 282 tristate "(Echoaudio) Gina24"
283 depends on SND 283 depends on SND
284 depends on FW_LOADER 284 select FW_LOADER
285 select SND_PCM 285 select SND_PCM
286 help 286 help
287 Say 'Y' or 'M' to include support for Echoaudio Gina24. 287 Say 'Y' or 'M' to include support for Echoaudio Gina24.
@@ -292,7 +292,7 @@ config SND_GINA24
292config SND_LAYLA24 292config SND_LAYLA24
293 tristate "(Echoaudio) Layla24" 293 tristate "(Echoaudio) Layla24"
294 depends on SND 294 depends on SND
295 depends on FW_LOADER 295 select FW_LOADER
296 select SND_RAWMIDI 296 select SND_RAWMIDI
297 select SND_PCM 297 select SND_PCM
298 help 298 help
@@ -304,7 +304,7 @@ config SND_LAYLA24
304config SND_MONA 304config SND_MONA
305 tristate "(Echoaudio) Mona" 305 tristate "(Echoaudio) Mona"
306 depends on SND 306 depends on SND
307 depends on FW_LOADER 307 select FW_LOADER
308 select SND_RAWMIDI 308 select SND_RAWMIDI
309 select SND_PCM 309 select SND_PCM
310 help 310 help
@@ -316,7 +316,7 @@ config SND_MONA
316config SND_MIA 316config SND_MIA
317 tristate "(Echoaudio) Mia" 317 tristate "(Echoaudio) Mia"
318 depends on SND 318 depends on SND
319 depends on FW_LOADER 319 select FW_LOADER
320 select SND_RAWMIDI 320 select SND_RAWMIDI
321 select SND_PCM 321 select SND_PCM
322 help 322 help
@@ -328,7 +328,7 @@ config SND_MIA
328config SND_ECHO3G 328config SND_ECHO3G
329 tristate "(Echoaudio) 3G cards" 329 tristate "(Echoaudio) 3G cards"
330 depends on SND 330 depends on SND
331 depends on FW_LOADER 331 select FW_LOADER
332 select SND_RAWMIDI 332 select SND_RAWMIDI
333 select SND_PCM 333 select SND_PCM
334 help 334 help
@@ -340,7 +340,7 @@ config SND_ECHO3G
340config SND_INDIGO 340config SND_INDIGO
341 tristate "(Echoaudio) Indigo" 341 tristate "(Echoaudio) Indigo"
342 depends on SND 342 depends on SND
343 depends on FW_LOADER 343 select FW_LOADER
344 select SND_PCM 344 select SND_PCM
345 help 345 help
346 Say 'Y' or 'M' to include support for Echoaudio Indigo. 346 Say 'Y' or 'M' to include support for Echoaudio Indigo.
@@ -351,7 +351,7 @@ config SND_INDIGO
351config SND_INDIGOIO 351config SND_INDIGOIO
352 tristate "(Echoaudio) Indigo IO" 352 tristate "(Echoaudio) Indigo IO"
353 depends on SND 353 depends on SND
354 depends on FW_LOADER 354 select FW_LOADER
355 select SND_PCM 355 select SND_PCM
356 help 356 help
357 Say 'Y' or 'M' to include support for Echoaudio Indigo IO. 357 Say 'Y' or 'M' to include support for Echoaudio Indigo IO.
@@ -362,7 +362,7 @@ config SND_INDIGOIO
362config SND_INDIGODJ 362config SND_INDIGODJ
363 tristate "(Echoaudio) Indigo DJ" 363 tristate "(Echoaudio) Indigo DJ"
364 depends on SND 364 depends on SND
365 depends on FW_LOADER 365 select FW_LOADER
366 select SND_PCM 366 select SND_PCM
367 help 367 help
368 Say 'Y' or 'M' to include support for Echoaudio Indigo DJ. 368 Say 'Y' or 'M' to include support for Echoaudio Indigo DJ.
@@ -373,6 +373,7 @@ config SND_INDIGODJ
373config SND_EMU10K1 373config SND_EMU10K1
374 tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)" 374 tristate "Emu10k1 (SB Live!, Audigy, E-mu APS)"
375 depends on SND 375 depends on SND
376 select FW_LOADER
376 select SND_HWDEP 377 select SND_HWDEP
377 select SND_RAWMIDI 378 select SND_RAWMIDI
378 select SND_AC97_CODEC 379 select SND_AC97_CODEC
@@ -575,6 +576,7 @@ config SND_INTEL8X0M
575config SND_KORG1212 576config SND_KORG1212
576 tristate "Korg 1212 IO" 577 tristate "Korg 1212 IO"
577 depends on SND 578 depends on SND
579 select FW_LOADER
578 select SND_PCM 580 select SND_PCM
579 help 581 help
580 Say Y here to include support for Korg 1212IO soundcards. 582 Say Y here to include support for Korg 1212IO soundcards.
@@ -585,6 +587,7 @@ config SND_KORG1212
585config SND_MAESTRO3 587config SND_MAESTRO3
586 tristate "ESS Allegro/Maestro3" 588 tristate "ESS Allegro/Maestro3"
587 depends on SND 589 depends on SND
590 select FW_LOADER
588 select SND_AC97_CODEC 591 select SND_AC97_CODEC
589 help 592 help
590 Say Y here to include support for soundcards based on ESS Maestro 3 593 Say Y here to include support for soundcards based on ESS Maestro 3
@@ -629,7 +632,7 @@ config SND_PCXHR
629config SND_RIPTIDE 632config SND_RIPTIDE
630 tristate "Conexant Riptide" 633 tristate "Conexant Riptide"
631 depends on SND 634 depends on SND
632 depends on FW_LOADER 635 select FW_LOADER
633 select SND_OPL3_LIB 636 select SND_OPL3_LIB
634 select SND_MPU401_UART 637 select SND_MPU401_UART
635 select SND_AC97_CODEC 638 select SND_AC97_CODEC
@@ -734,6 +737,7 @@ config SND_VX222
734config SND_YMFPCI 737config SND_YMFPCI
735 tristate "Yamaha YMF724/740/744/754" 738 tristate "Yamaha YMF724/740/744/754"
736 depends on SND 739 depends on SND
740 select FW_LOADER
737 select SND_OPL3_LIB 741 select SND_OPL3_LIB
738 select SND_MPU401_UART 742 select SND_MPU401_UART
739 select SND_AC97_CODEC 743 select SND_AC97_CODEC
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index d2994cb4c8c9..74ed81081478 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -111,7 +111,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
111{ 0x41445372, 0xffffffff, "AD1981A", patch_ad1981a, NULL }, 111{ 0x41445372, 0xffffffff, "AD1981A", patch_ad1981a, NULL },
112{ 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL }, 112{ 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL },
113{ 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL }, 113{ 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL },
114{ 0x41445378, 0xffffffff, "AD1986", patch_ad1985, NULL }, 114{ 0x41445378, 0xffffffff, "AD1986", patch_ad1986, NULL },
115{ 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL }, 115{ 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL },
116{ 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL }, 116{ 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL },
117{ 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */ 117{ 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */
@@ -194,6 +194,13 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
194 194
195 195
196static void update_power_regs(struct snd_ac97 *ac97); 196static void update_power_regs(struct snd_ac97 *ac97);
197#ifdef CONFIG_SND_AC97_POWER_SAVE
198#define ac97_is_power_save_mode(ac97) \
199 ((ac97->scaps & AC97_SCAP_POWER_SAVE) && power_save)
200#else
201#define ac97_is_power_save_mode(ac97) 0
202#endif
203
197 204
198/* 205/*
199 * I/O routines 206 * I/O routines
@@ -982,8 +989,8 @@ static int snd_ac97_free(struct snd_ac97 *ac97)
982{ 989{
983 if (ac97) { 990 if (ac97) {
984#ifdef CONFIG_SND_AC97_POWER_SAVE 991#ifdef CONFIG_SND_AC97_POWER_SAVE
985 if (ac97->power_workq) 992 cancel_delayed_work(&ac97->power_work);
986 destroy_workqueue(ac97->power_workq); 993 flush_scheduled_work();
987#endif 994#endif
988 snd_ac97_proc_done(ac97); 995 snd_ac97_proc_done(ac97);
989 if (ac97->bus) 996 if (ac97->bus)
@@ -1184,13 +1191,13 @@ static int snd_ac97_cmute_new_stereo(struct snd_card *card, char *name, int reg,
1184/* 1191/*
1185 * set dB information 1192 * set dB information
1186 */ 1193 */
1187static DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0); 1194static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
1188static DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0); 1195static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
1189static DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); 1196static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
1190static DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); 1197static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
1191static DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); 1198static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
1192 1199
1193static unsigned int *find_db_scale(unsigned int maxval) 1200static const unsigned int *find_db_scale(unsigned int maxval)
1194{ 1201{
1195 switch (maxval) { 1202 switch (maxval) {
1196 case 0x0f: return db_scale_4bit; 1203 case 0x0f: return db_scale_4bit;
@@ -1200,8 +1207,8 @@ static unsigned int *find_db_scale(unsigned int maxval)
1200 return NULL; 1207 return NULL;
1201} 1208}
1202 1209
1203static void set_tlv_db_scale(struct snd_kcontrol *kctl, unsigned int *tlv) 1210static void set_tlv_db_scale(struct snd_kcontrol *kctl, const unsigned int *tlv)
1204{ 1211{
1205 kctl->tlv.p = tlv; 1212 kctl->tlv.p = tlv;
1206 if (tlv) 1213 if (tlv)
1207 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; 1214 kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
@@ -1989,7 +1996,6 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template,
1989 mutex_init(&ac97->reg_mutex); 1996 mutex_init(&ac97->reg_mutex);
1990 mutex_init(&ac97->page_mutex); 1997 mutex_init(&ac97->page_mutex);
1991#ifdef CONFIG_SND_AC97_POWER_SAVE 1998#ifdef CONFIG_SND_AC97_POWER_SAVE
1992 ac97->power_workq = create_workqueue("ac97");
1993 INIT_DELAYED_WORK(&ac97->power_work, do_update_power); 1999 INIT_DELAYED_WORK(&ac97->power_work, do_update_power);
1994#endif 2000#endif
1995 2001
@@ -2275,15 +2281,13 @@ static void snd_ac97_powerdown(struct snd_ac97 *ac97)
2275 udelay(100); 2281 udelay(100);
2276 power |= AC97_PD_PR2 | AC97_PD_PR3; /* Analog Mixer powerdown */ 2282 power |= AC97_PD_PR2 | AC97_PD_PR3; /* Analog Mixer powerdown */
2277 snd_ac97_write(ac97, AC97_POWERDOWN, power); 2283 snd_ac97_write(ac97, AC97_POWERDOWN, power);
2278#ifdef CONFIG_SND_AC97_POWER_SAVE 2284 if (ac97_is_power_save_mode(ac97)) {
2279 if (power_save) {
2280 udelay(100); 2285 udelay(100);
2281 /* AC-link powerdown, internal Clk disable */ 2286 /* AC-link powerdown, internal Clk disable */
2282 /* FIXME: this may cause click noises on some boards */ 2287 /* FIXME: this may cause click noises on some boards */
2283 power |= AC97_PD_PR4 | AC97_PD_PR5; 2288 power |= AC97_PD_PR4 | AC97_PD_PR5;
2284 snd_ac97_write(ac97, AC97_POWERDOWN, power); 2289 snd_ac97_write(ac97, AC97_POWERDOWN, power);
2285 } 2290 }
2286#endif
2287} 2291}
2288 2292
2289 2293
@@ -2337,14 +2341,16 @@ int snd_ac97_update_power(struct snd_ac97 *ac97, int reg, int powerup)
2337 } 2341 }
2338 } 2342 }
2339 2343
2340 if (power_save && !powerup && ac97->power_workq) 2344 if (ac97_is_power_save_mode(ac97) && !powerup)
2341 /* adjust power-down bits after two seconds delay 2345 /* adjust power-down bits after two seconds delay
2342 * (for avoiding loud click noises for many (OSS) apps 2346 * (for avoiding loud click noises for many (OSS) apps
2343 * that open/close frequently) 2347 * that open/close frequently)
2344 */ 2348 */
2345 queue_delayed_work(ac97->power_workq, &ac97->power_work, HZ*2); 2349 schedule_delayed_work(&ac97->power_work, HZ*2);
2346 else 2350 else {
2351 cancel_delayed_work(&ac97->power_work);
2347 update_power_regs(ac97); 2352 update_power_regs(ac97);
2353 }
2348 2354
2349 return 0; 2355 return 0;
2350} 2356}
@@ -2357,19 +2363,15 @@ static void update_power_regs(struct snd_ac97 *ac97)
2357 unsigned int power_up, bits; 2363 unsigned int power_up, bits;
2358 int i; 2364 int i;
2359 2365
2366 power_up = (1 << PWIDX_FRONT) | (1 << PWIDX_ADC);
2367 power_up |= (1 << PWIDX_MIC);
2368 if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
2369 power_up |= (1 << PWIDX_SURR);
2370 if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
2371 power_up |= (1 << PWIDX_CLFE);
2360#ifdef CONFIG_SND_AC97_POWER_SAVE 2372#ifdef CONFIG_SND_AC97_POWER_SAVE
2361 if (power_save) 2373 if (ac97_is_power_save_mode(ac97))
2362 power_up = ac97->power_up; 2374 power_up = ac97->power_up;
2363 else {
2364#endif
2365 power_up = (1 << PWIDX_FRONT) | (1 << PWIDX_ADC);
2366 power_up |= (1 << PWIDX_MIC);
2367 if (ac97->scaps & AC97_SCAP_SURROUND_DAC)
2368 power_up |= (1 << PWIDX_SURR);
2369 if (ac97->scaps & AC97_SCAP_CENTER_LFE_DAC)
2370 power_up |= (1 << PWIDX_CLFE);
2371#ifdef CONFIG_SND_AC97_POWER_SAVE
2372 }
2373#endif 2375#endif
2374 if (power_up) { 2376 if (power_up) {
2375 if (ac97->regs[AC97_POWERDOWN] & AC97_PD_PR2) { 2377 if (ac97->regs[AC97_POWERDOWN] & AC97_PD_PR2) {
@@ -2414,6 +2416,10 @@ void snd_ac97_suspend(struct snd_ac97 *ac97)
2414 return; 2416 return;
2415 if (ac97->build_ops->suspend) 2417 if (ac97->build_ops->suspend)
2416 ac97->build_ops->suspend(ac97); 2418 ac97->build_ops->suspend(ac97);
2419#ifdef CONFIG_SND_AC97_POWER_SAVE
2420 cancel_delayed_work(&ac97->power_work);
2421 flush_scheduled_work();
2422#endif
2417 snd_ac97_powerdown(ac97); 2423 snd_ac97_powerdown(ac97);
2418} 2424}
2419 2425
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index e813968e0cf8..641d0c8d659e 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -54,7 +54,7 @@ static int patch_build_controls(struct snd_ac97 * ac97, const struct snd_kcontro
54 54
55/* replace with a new TLV */ 55/* replace with a new TLV */
56static void reset_tlv(struct snd_ac97 *ac97, const char *name, 56static void reset_tlv(struct snd_ac97 *ac97, const char *name,
57 unsigned int *tlv) 57 const unsigned int *tlv)
58{ 58{
59 struct snd_ctl_elem_id sid; 59 struct snd_ctl_elem_id sid;
60 struct snd_kcontrol *kctl; 60 struct snd_kcontrol *kctl;
@@ -190,14 +190,28 @@ static inline int is_clfe_on(struct snd_ac97 *ac97)
190 return ac97->channel_mode >= 2; 190 return ac97->channel_mode >= 2;
191} 191}
192 192
193/* system has shared jacks with surround out enabled */
194static inline int is_shared_surrout(struct snd_ac97 *ac97)
195{
196 return !ac97->indep_surround && is_surround_on(ac97);
197}
198
199/* system has shared jacks with center/lfe out enabled */
200static inline int is_shared_clfeout(struct snd_ac97 *ac97)
201{
202 return !ac97->indep_surround && is_clfe_on(ac97);
203}
204
205/* system has shared jacks with line in enabled */
193static inline int is_shared_linein(struct snd_ac97 *ac97) 206static inline int is_shared_linein(struct snd_ac97 *ac97)
194{ 207{
195 return ! ac97->indep_surround && is_surround_on(ac97); 208 return !ac97->indep_surround && !is_surround_on(ac97);
196} 209}
197 210
211/* system has shared jacks with mic in enabled */
198static inline int is_shared_micin(struct snd_ac97 *ac97) 212static inline int is_shared_micin(struct snd_ac97 *ac97)
199{ 213{
200 return ! ac97->indep_surround && is_clfe_on(ac97); 214 return !ac97->indep_surround && !is_clfe_on(ac97);
201} 215}
202 216
203 217
@@ -941,6 +955,9 @@ static int patch_sigmatel_stac9708_specific(struct snd_ac97 *ac97)
941{ 955{
942 int err; 956 int err;
943 957
958 /* the register bit is writable, but the function is not implemented: */
959 snd_ac97_remove_ctl(ac97, "PCM Out Path & Mute", NULL);
960
944 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Sigmatel Surround Playback"); 961 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Sigmatel Surround Playback");
945 if ((err = patch_build_controls(ac97, &snd_ac97_stac9708_bias_control, 1)) < 0) 962 if ((err = patch_build_controls(ac97, &snd_ac97_stac9708_bias_control, 1)) < 0)
946 return err; 963 return err;
@@ -1552,7 +1569,7 @@ static const struct snd_kcontrol_new snd_ac97_controls_ad1885[] = {
1552 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 8, 1, 1), /* inverted */ 1569 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 8, 1, 1), /* inverted */
1553}; 1570};
1554 1571
1555static DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max, -8850, 150, 0); 1572static const DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max, -8850, 150, 0);
1556 1573
1557static int patch_ad1885_specific(struct snd_ac97 * ac97) 1574static int patch_ad1885_specific(struct snd_ac97 * ac97)
1558{ 1575{
@@ -1609,19 +1626,22 @@ int patch_ad1886(struct snd_ac97 * ac97)
1609 return 0; 1626 return 0;
1610} 1627}
1611 1628
1612/* MISC bits */ 1629/* MISC bits (AD1888/AD1980/AD1985 register 0x76) */
1613#define AC97_AD198X_MBC 0x0003 /* mic boost */ 1630#define AC97_AD198X_MBC 0x0003 /* mic boost */
1614#define AC97_AD198X_MBC_20 0x0000 /* +20dB */ 1631#define AC97_AD198X_MBC_20 0x0000 /* +20dB */
1615#define AC97_AD198X_MBC_10 0x0001 /* +10dB */ 1632#define AC97_AD198X_MBC_10 0x0001 /* +10dB */
1616#define AC97_AD198X_MBC_30 0x0002 /* +30dB */ 1633#define AC97_AD198X_MBC_30 0x0002 /* +30dB */
1617#define AC97_AD198X_VREFD 0x0004 /* VREF high-Z */ 1634#define AC97_AD198X_VREFD 0x0004 /* VREF high-Z */
1618#define AC97_AD198X_VREFH 0x0008 /* 2.25V, 3.7V */ 1635#define AC97_AD198X_VREFH 0x0008 /* 0=2.25V, 1=3.7V */
1619#define AC97_AD198X_VREF_0 0x000c /* 0V */ 1636#define AC97_AD198X_VREF_0 0x000c /* 0V (AD1985 only) */
1637#define AC97_AD198X_VREF_MASK (AC97_AD198X_VREFH | AC97_AD198X_VREFD)
1638#define AC97_AD198X_VREF_SHIFT 2
1620#define AC97_AD198X_SRU 0x0010 /* sample rate unlock */ 1639#define AC97_AD198X_SRU 0x0010 /* sample rate unlock */
1621#define AC97_AD198X_LOSEL 0x0020 /* LINE_OUT amplifiers input select */ 1640#define AC97_AD198X_LOSEL 0x0020 /* LINE_OUT amplifiers input select */
1622#define AC97_AD198X_2MIC 0x0040 /* 2-channel mic select */ 1641#define AC97_AD198X_2MIC 0x0040 /* 2-channel mic select */
1623#define AC97_AD198X_SPRD 0x0080 /* SPREAD enable */ 1642#define AC97_AD198X_SPRD 0x0080 /* SPREAD enable */
1624#define AC97_AD198X_DMIX0 0x0100 /* downmix mode: 0 = 6-to-4, 1 = 6-to-2 downmix */ 1643#define AC97_AD198X_DMIX0 0x0100 /* downmix mode: */
1644 /* 0 = 6-to-4, 1 = 6-to-2 downmix */
1625#define AC97_AD198X_DMIX1 0x0200 /* downmix mode: 1 = enabled */ 1645#define AC97_AD198X_DMIX1 0x0200 /* downmix mode: 1 = enabled */
1626#define AC97_AD198X_HPSEL 0x0400 /* headphone amplifier input select */ 1646#define AC97_AD198X_HPSEL 0x0400 /* headphone amplifier input select */
1627#define AC97_AD198X_CLDIS 0x0800 /* center/lfe disable */ 1647#define AC97_AD198X_CLDIS 0x0800 /* center/lfe disable */
@@ -1630,6 +1650,83 @@ int patch_ad1886(struct snd_ac97 * ac97)
1630#define AC97_AD198X_AC97NC 0x4000 /* AC97 no compatible mode */ 1650#define AC97_AD198X_AC97NC 0x4000 /* AC97 no compatible mode */
1631#define AC97_AD198X_DACZ 0x8000 /* DAC zero-fill mode */ 1651#define AC97_AD198X_DACZ 0x8000 /* DAC zero-fill mode */
1632 1652
1653/* MISC 1 bits (AD1986 register 0x76) */
1654#define AC97_AD1986_MBC 0x0003 /* mic boost */
1655#define AC97_AD1986_MBC_20 0x0000 /* +20dB */
1656#define AC97_AD1986_MBC_10 0x0001 /* +10dB */
1657#define AC97_AD1986_MBC_30 0x0002 /* +30dB */
1658#define AC97_AD1986_LISEL0 0x0004 /* LINE_IN select bit 0 */
1659#define AC97_AD1986_LISEL1 0x0008 /* LINE_IN select bit 1 */
1660#define AC97_AD1986_LISEL_MASK (AC97_AD1986_LISEL1 | AC97_AD1986_LISEL0)
1661#define AC97_AD1986_LISEL_LI 0x0000 /* LINE_IN pins as LINE_IN source */
1662#define AC97_AD1986_LISEL_SURR 0x0004 /* SURROUND pins as LINE_IN source */
1663#define AC97_AD1986_LISEL_MIC 0x0008 /* MIC_1/2 pins as LINE_IN source */
1664#define AC97_AD1986_SRU 0x0010 /* sample rate unlock */
1665#define AC97_AD1986_SOSEL 0x0020 /* SURROUND_OUT amplifiers input sel */
1666#define AC97_AD1986_2MIC 0x0040 /* 2-channel mic select */
1667#define AC97_AD1986_SPRD 0x0080 /* SPREAD enable */
1668#define AC97_AD1986_DMIX0 0x0100 /* downmix mode: */
1669 /* 0 = 6-to-4, 1 = 6-to-2 downmix */
1670#define AC97_AD1986_DMIX1 0x0200 /* downmix mode: 1 = enabled */
1671#define AC97_AD1986_CLDIS 0x0800 /* center/lfe disable */
1672#define AC97_AD1986_SODIS 0x1000 /* SURROUND_OUT disable */
1673#define AC97_AD1986_MSPLT 0x2000 /* mute split (read only 1) */
1674#define AC97_AD1986_AC97NC 0x4000 /* AC97 no compatible mode (r/o 1) */
1675#define AC97_AD1986_DACZ 0x8000 /* DAC zero-fill mode */
1676
1677/* MISC 2 bits (AD1986 register 0x70) */
1678#define AC97_AD_MISC2 0x70 /* Misc Control Bits 2 (AD1986) */
1679
1680#define AC97_AD1986_CVREF0 0x0004 /* C/LFE VREF_OUT 2.25V */
1681#define AC97_AD1986_CVREF1 0x0008 /* C/LFE VREF_OUT 0V */
1682#define AC97_AD1986_CVREF2 0x0010 /* C/LFE VREF_OUT 3.7V */
1683#define AC97_AD1986_CVREF_MASK \
1684 (AC97_AD1986_CVREF2 | AC97_AD1986_CVREF1 | AC97_AD1986_CVREF0)
1685#define AC97_AD1986_JSMAP 0x0020 /* Jack Sense Mapping 1 = alternate */
1686#define AC97_AD1986_MMDIS 0x0080 /* Mono Mute Disable */
1687#define AC97_AD1986_MVREF0 0x0400 /* MIC VREF_OUT 2.25V */
1688#define AC97_AD1986_MVREF1 0x0800 /* MIC VREF_OUT 0V */
1689#define AC97_AD1986_MVREF2 0x1000 /* MIC VREF_OUT 3.7V */
1690#define AC97_AD1986_MVREF_MASK \
1691 (AC97_AD1986_MVREF2 | AC97_AD1986_MVREF1 | AC97_AD1986_MVREF0)
1692
1693/* MISC 3 bits (AD1986 register 0x7a) */
1694#define AC97_AD_MISC3 0x7a /* Misc Control Bits 3 (AD1986) */
1695
1696#define AC97_AD1986_MMIX 0x0004 /* Mic Mix, left/right */
1697#define AC97_AD1986_GPO 0x0008 /* General Purpose Out */
1698#define AC97_AD1986_LOHPEN 0x0010 /* LINE_OUT headphone drive */
1699#define AC97_AD1986_LVREF0 0x0100 /* LINE_OUT VREF_OUT 2.25V */
1700#define AC97_AD1986_LVREF1 0x0200 /* LINE_OUT VREF_OUT 0V */
1701#define AC97_AD1986_LVREF2 0x0400 /* LINE_OUT VREF_OUT 3.7V */
1702#define AC97_AD1986_LVREF_MASK \
1703 (AC97_AD1986_LVREF2 | AC97_AD1986_LVREF1 | AC97_AD1986_LVREF0)
1704#define AC97_AD1986_JSINVA 0x0800 /* Jack Sense Invert SENSE_A */
1705#define AC97_AD1986_LOSEL 0x1000 /* LINE_OUT amplifiers input select */
1706#define AC97_AD1986_HPSEL0 0x2000 /* Headphone amplifiers */
1707 /* input select Surround DACs */
1708#define AC97_AD1986_HPSEL1 0x4000 /* Headphone amplifiers input */
1709 /* select C/LFE DACs */
1710#define AC97_AD1986_JSINVB 0x8000 /* Jack Sense Invert SENSE_B */
1711
1712/* Serial Config bits (AD1986 register 0x74) (incomplete) */
1713#define AC97_AD1986_OMS0 0x0100 /* Optional Mic Selector bit 0 */
1714#define AC97_AD1986_OMS1 0x0200 /* Optional Mic Selector bit 1 */
1715#define AC97_AD1986_OMS2 0x0400 /* Optional Mic Selector bit 2 */
1716#define AC97_AD1986_OMS_MASK \
1717 (AC97_AD1986_OMS2 | AC97_AD1986_OMS1 | AC97_AD1986_OMS0)
1718#define AC97_AD1986_OMS_M 0x0000 /* MIC_1/2 pins are MIC sources */
1719#define AC97_AD1986_OMS_L 0x0100 /* LINE_IN pins are MIC sources */
1720#define AC97_AD1986_OMS_C 0x0200 /* Center/LFE pins are MCI sources */
1721#define AC97_AD1986_OMS_MC 0x0400 /* Mix of MIC and C/LFE pins */
1722 /* are MIC sources */
1723#define AC97_AD1986_OMS_ML 0x0500 /* MIX of MIC and LINE_IN pins */
1724 /* are MIC sources */
1725#define AC97_AD1986_OMS_LC 0x0600 /* MIX of LINE_IN and C/LFE pins */
1726 /* are MIC sources */
1727#define AC97_AD1986_OMS_MLC 0x0700 /* MIX of MIC, LINE_IN, C/LFE pins */
1728 /* are MIC sources */
1729
1633 1730
1634static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1731static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1635{ 1732{
@@ -1952,8 +2049,80 @@ int patch_ad1980(struct snd_ac97 * ac97)
1952 return 0; 2049 return 0;
1953} 2050}
1954 2051
2052static int snd_ac97_ad1985_vrefout_info(struct snd_kcontrol *kcontrol,
2053 struct snd_ctl_elem_info *uinfo)
2054{
2055 static char *texts[4] = {"High-Z", "3.7 V", "2.25 V", "0 V"};
2056
2057 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2058 uinfo->count = 1;
2059 uinfo->value.enumerated.items = 4;
2060 if (uinfo->value.enumerated.item > 3)
2061 uinfo->value.enumerated.item = 3;
2062 strcpy(uinfo->value.enumerated.name,
2063 texts[uinfo->value.enumerated.item]);
2064 return 0;
2065}
2066
2067static int snd_ac97_ad1985_vrefout_get(struct snd_kcontrol *kcontrol,
2068 struct snd_ctl_elem_value *ucontrol)
2069{
2070 static const int reg2ctrl[4] = {2, 0, 1, 3};
2071 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2072 unsigned short val;
2073 val = (ac97->regs[AC97_AD_MISC] & AC97_AD198X_VREF_MASK)
2074 >> AC97_AD198X_VREF_SHIFT;
2075 ucontrol->value.enumerated.item[0] = reg2ctrl[val];
2076 return 0;
2077}
2078
2079static int snd_ac97_ad1985_vrefout_put(struct snd_kcontrol *kcontrol,
2080 struct snd_ctl_elem_value *ucontrol)
2081{
2082 static const int ctrl2reg[4] = {1, 2, 0, 3};
2083 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2084 unsigned short val;
2085
2086 if (ucontrol->value.enumerated.item[0] > 3
2087 || ucontrol->value.enumerated.item[0] < 0)
2088 return -EINVAL;
2089 val = ctrl2reg[ucontrol->value.enumerated.item[0]]
2090 << AC97_AD198X_VREF_SHIFT;
2091 return snd_ac97_update_bits(ac97, AC97_AD_MISC,
2092 AC97_AD198X_VREF_MASK, val);
2093}
2094
1955static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = { 2095static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = {
1956 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0) 2096 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0),
2097 {
2098 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2099 .name = "Exchange Front/Surround",
2100 .info = snd_ac97_ad1888_lohpsel_info,
2101 .get = snd_ac97_ad1888_lohpsel_get,
2102 .put = snd_ac97_ad1888_lohpsel_put
2103 },
2104 AC97_SINGLE("High Pass Filter Enable", AC97_AD_TEST2, 12, 1, 1),
2105 AC97_SINGLE("Spread Front to Surround and Center/LFE",
2106 AC97_AD_MISC, 7, 1, 0),
2107 {
2108 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2109 .name = "Downmix",
2110 .info = snd_ac97_ad1888_downmix_info,
2111 .get = snd_ac97_ad1888_downmix_get,
2112 .put = snd_ac97_ad1888_downmix_put
2113 },
2114 {
2115 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2116 .name = "V_REFOUT",
2117 .info = snd_ac97_ad1985_vrefout_info,
2118 .get = snd_ac97_ad1985_vrefout_get,
2119 .put = snd_ac97_ad1985_vrefout_put
2120 },
2121 AC97_SURROUND_JACK_MODE_CTL,
2122 AC97_CHANNEL_MODE_CTL,
2123
2124 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
2125 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0),
1957}; 2126};
1958 2127
1959static void ad1985_update_jacks(struct snd_ac97 *ac97) 2128static void ad1985_update_jacks(struct snd_ac97 *ac97)
@@ -1967,9 +2136,16 @@ static int patch_ad1985_specific(struct snd_ac97 *ac97)
1967{ 2136{
1968 int err; 2137 int err;
1969 2138
1970 if ((err = patch_ad1980_specific(ac97)) < 0) 2139 /* rename 0x04 as "Master" and 0x02 as "Master Surround" */
2140 snd_ac97_rename_vol_ctl(ac97, "Master Playback",
2141 "Master Surround Playback");
2142 snd_ac97_rename_vol_ctl(ac97, "Headphone Playback", "Master Playback");
2143
2144 if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
1971 return err; 2145 return err;
1972 return patch_build_controls(ac97, snd_ac97_ad1985_controls, ARRAY_SIZE(snd_ac97_ad1985_controls)); 2146
2147 return patch_build_controls(ac97, snd_ac97_ad1985_controls,
2148 ARRAY_SIZE(snd_ac97_ad1985_controls));
1973} 2149}
1974 2150
1975static struct snd_ac97_build_ops patch_ad1985_build_ops = { 2151static struct snd_ac97_build_ops patch_ad1985_build_ops = {
@@ -1989,24 +2165,311 @@ int patch_ad1985(struct snd_ac97 * ac97)
1989 ac97->build_ops = &patch_ad1985_build_ops; 2165 ac97->build_ops = &patch_ad1985_build_ops;
1990 misc = snd_ac97_read(ac97, AC97_AD_MISC); 2166 misc = snd_ac97_read(ac97, AC97_AD_MISC);
1991 /* switch front/surround line-out/hp-out */ 2167 /* switch front/surround line-out/hp-out */
1992 /* center/LFE, mic in 3.75V mode */
1993 /* AD-compatible mode */ 2168 /* AD-compatible mode */
1994 /* Stereo mutes enabled */ 2169 /* Stereo mutes enabled */
1995 /* in accordance with ADI driver: misc | 0x5c28 */
1996 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc | 2170 snd_ac97_write_cache(ac97, AC97_AD_MISC, misc |
1997 AC97_AD198X_VREFH |
1998 AC97_AD198X_LOSEL | 2171 AC97_AD198X_LOSEL |
1999 AC97_AD198X_HPSEL | 2172 AC97_AD198X_HPSEL |
2000 AC97_AD198X_CLDIS |
2001 AC97_AD198X_LODIS |
2002 AC97_AD198X_MSPLT | 2173 AC97_AD198X_MSPLT |
2003 AC97_AD198X_AC97NC); 2174 AC97_AD198X_AC97NC);
2004 ac97->flags |= AC97_STEREO_MUTES; 2175 ac97->flags |= AC97_STEREO_MUTES;
2176
2177 /* update current jack configuration */
2178 ad1985_update_jacks(ac97);
2179
2005 /* on AD1985 rev. 3, AC'97 revision bits are zero */ 2180 /* on AD1985 rev. 3, AC'97 revision bits are zero */
2006 ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23; 2181 ac97->ext_id = (ac97->ext_id & ~AC97_EI_REV_MASK) | AC97_EI_REV_23;
2007 return 0; 2182 return 0;
2008} 2183}
2009 2184
2185static int snd_ac97_ad1986_bool_info(struct snd_kcontrol *kcontrol,
2186 struct snd_ctl_elem_info *uinfo)
2187{
2188 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2189 uinfo->count = 1;
2190 uinfo->value.integer.min = 0;
2191 uinfo->value.integer.max = 1;
2192 return 0;
2193}
2194
2195static int snd_ac97_ad1986_lososel_get(struct snd_kcontrol *kcontrol,
2196 struct snd_ctl_elem_value *ucontrol)
2197{
2198 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2199 unsigned short val;
2200
2201 val = ac97->regs[AC97_AD_MISC3];
2202 ucontrol->value.integer.value[0] = (val & AC97_AD1986_LOSEL) != 0;
2203 return 0;
2204}
2205
2206static int snd_ac97_ad1986_lososel_put(struct snd_kcontrol *kcontrol,
2207 struct snd_ctl_elem_value *ucontrol)
2208{
2209 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2210 int ret0;
2211 int ret1;
2212 int sprd = (ac97->regs[AC97_AD_MISC] & AC97_AD1986_SPRD) != 0;
2213
2214 ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC3, AC97_AD1986_LOSEL,
2215 ucontrol->value.integer.value[0] != 0
2216 ? AC97_AD1986_LOSEL : 0);
2217 if (ret0 < 0)
2218 return ret0;
2219
2220 /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */
2221 ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL,
2222 (ucontrol->value.integer.value[0] != 0
2223 || sprd)
2224 ? AC97_AD1986_SOSEL : 0);
2225 if (ret1 < 0)
2226 return ret1;
2227
2228 return (ret0 > 0 || ret1 > 0) ? 1 : 0;
2229}
2230
2231static int snd_ac97_ad1986_spread_get(struct snd_kcontrol *kcontrol,
2232 struct snd_ctl_elem_value *ucontrol)
2233{
2234 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2235 unsigned short val;
2236
2237 val = ac97->regs[AC97_AD_MISC];
2238 ucontrol->value.integer.value[0] = (val & AC97_AD1986_SPRD) != 0;
2239 return 0;
2240}
2241
2242static int snd_ac97_ad1986_spread_put(struct snd_kcontrol *kcontrol,
2243 struct snd_ctl_elem_value *ucontrol)
2244{
2245 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2246 int ret0;
2247 int ret1;
2248 int sprd = (ac97->regs[AC97_AD_MISC3] & AC97_AD1986_LOSEL) != 0;
2249
2250 ret0 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SPRD,
2251 ucontrol->value.integer.value[0] != 0
2252 ? AC97_AD1986_SPRD : 0);
2253 if (ret0 < 0)
2254 return ret0;
2255
2256 /* SOSEL is set to values of "Spread" or "Exchange F/S" controls */
2257 ret1 = snd_ac97_update_bits(ac97, AC97_AD_MISC, AC97_AD1986_SOSEL,
2258 (ucontrol->value.integer.value[0] != 0
2259 || sprd)
2260 ? AC97_AD1986_SOSEL : 0);
2261 if (ret1 < 0)
2262 return ret1;
2263
2264 return (ret0 > 0 || ret1 > 0) ? 1 : 0;
2265}
2266
2267static int snd_ac97_ad1986_miclisel_get(struct snd_kcontrol *kcontrol,
2268 struct snd_ctl_elem_value *ucontrol)
2269{
2270 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2271
2272 ucontrol->value.integer.value[0] = ac97->spec.ad18xx.swap_mic_linein;
2273 return 0;
2274}
2275
2276static int snd_ac97_ad1986_miclisel_put(struct snd_kcontrol *kcontrol,
2277 struct snd_ctl_elem_value *ucontrol)
2278{
2279 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2280 unsigned char swap = ucontrol->value.integer.value[0] != 0;
2281
2282 if (swap != ac97->spec.ad18xx.swap_mic_linein) {
2283 ac97->spec.ad18xx.swap_mic_linein = swap;
2284 if (ac97->build_ops->update_jacks)
2285 ac97->build_ops->update_jacks(ac97);
2286 return 1;
2287 }
2288 return 0;
2289}
2290
2291static int snd_ac97_ad1986_vrefout_get(struct snd_kcontrol *kcontrol,
2292 struct snd_ctl_elem_value *ucontrol)
2293{
2294 /* Use MIC_1/2 V_REFOUT as the "get" value */
2295 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2296 unsigned short val;
2297 unsigned short reg = ac97->regs[AC97_AD_MISC2];
2298 if ((reg & AC97_AD1986_MVREF0) != 0)
2299 val = 2;
2300 else if ((reg & AC97_AD1986_MVREF1) != 0)
2301 val = 3;
2302 else if ((reg & AC97_AD1986_MVREF2) != 0)
2303 val = 1;
2304 else
2305 val = 0;
2306 ucontrol->value.enumerated.item[0] = val;
2307 return 0;
2308}
2309
2310static int snd_ac97_ad1986_vrefout_put(struct snd_kcontrol *kcontrol,
2311 struct snd_ctl_elem_value *ucontrol)
2312{
2313 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
2314 unsigned short cval;
2315 unsigned short lval;
2316 unsigned short mval;
2317 int cret;
2318 int lret;
2319 int mret;
2320
2321 switch (ucontrol->value.enumerated.item[0])
2322 {
2323 case 0: /* High-Z */
2324 cval = 0;
2325 lval = 0;
2326 mval = 0;
2327 break;
2328 case 1: /* 3.7 V */
2329 cval = AC97_AD1986_CVREF2;
2330 lval = AC97_AD1986_LVREF2;
2331 mval = AC97_AD1986_MVREF2;
2332 break;
2333 case 2: /* 2.25 V */
2334 cval = AC97_AD1986_CVREF0;
2335 lval = AC97_AD1986_LVREF0;
2336 mval = AC97_AD1986_MVREF0;
2337 break;
2338 case 3: /* 0 V */
2339 cval = AC97_AD1986_CVREF1;
2340 lval = AC97_AD1986_LVREF1;
2341 mval = AC97_AD1986_MVREF1;
2342 break;
2343 default:
2344 return -EINVAL;
2345 }
2346
2347 cret = snd_ac97_update_bits(ac97, AC97_AD_MISC2,
2348 AC97_AD1986_CVREF_MASK, cval);
2349 if (cret < 0)
2350 return cret;
2351 lret = snd_ac97_update_bits(ac97, AC97_AD_MISC3,
2352 AC97_AD1986_LVREF_MASK, lval);
2353 if (lret < 0)
2354 return lret;
2355 mret = snd_ac97_update_bits(ac97, AC97_AD_MISC2,
2356 AC97_AD1986_MVREF_MASK, mval);
2357 if (mret < 0)
2358 return mret;
2359
2360 return (cret > 0 || lret > 0 || mret > 0) ? 1 : 0;
2361}
2362
2363static const struct snd_kcontrol_new snd_ac97_ad1986_controls[] = {
2364 AC97_SINGLE("Exchange Center/LFE", AC97_AD_SERIAL_CFG, 3, 1, 0),
2365 {
2366 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2367 .name = "Exchange Front/Surround",
2368 .info = snd_ac97_ad1986_bool_info,
2369 .get = snd_ac97_ad1986_lososel_get,
2370 .put = snd_ac97_ad1986_lososel_put
2371 },
2372 {
2373 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2374 .name = "Exchange Mic/Line In",
2375 .info = snd_ac97_ad1986_bool_info,
2376 .get = snd_ac97_ad1986_miclisel_get,
2377 .put = snd_ac97_ad1986_miclisel_put
2378 },
2379 {
2380 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2381 .name = "Spread Front to Surround and Center/LFE",
2382 .info = snd_ac97_ad1986_bool_info,
2383 .get = snd_ac97_ad1986_spread_get,
2384 .put = snd_ac97_ad1986_spread_put
2385 },
2386 {
2387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2388 .name = "Downmix",
2389 .info = snd_ac97_ad1888_downmix_info,
2390 .get = snd_ac97_ad1888_downmix_get,
2391 .put = snd_ac97_ad1888_downmix_put
2392 },
2393 {
2394 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2395 .name = "V_REFOUT",
2396 .info = snd_ac97_ad1985_vrefout_info,
2397 .get = snd_ac97_ad1986_vrefout_get,
2398 .put = snd_ac97_ad1986_vrefout_put
2399 },
2400 AC97_SURROUND_JACK_MODE_CTL,
2401 AC97_CHANNEL_MODE_CTL,
2402
2403 AC97_SINGLE("Headphone Jack Sense", AC97_AD_JACK_SPDIF, 10, 1, 0),
2404 AC97_SINGLE("Line Jack Sense", AC97_AD_JACK_SPDIF, 12, 1, 0)
2405};
2406
2407static void ad1986_update_jacks(struct snd_ac97 *ac97)
2408{
2409 unsigned short misc_val = 0;
2410 unsigned short ser_val;
2411
2412 /* disable SURROUND and CENTER/LFE if not surround mode */
2413 if (! is_surround_on(ac97))
2414 misc_val |= AC97_AD1986_SODIS;
2415 if (! is_clfe_on(ac97))
2416 misc_val |= AC97_AD1986_CLDIS;
2417
2418 /* select line input (default=LINE_IN, SURROUND or MIC_1/2) */
2419 if (is_shared_linein(ac97))
2420 misc_val |= AC97_AD1986_LISEL_SURR;
2421 else if (ac97->spec.ad18xx.swap_mic_linein != 0)
2422 misc_val |= AC97_AD1986_LISEL_MIC;
2423 snd_ac97_update_bits(ac97, AC97_AD_MISC,
2424 AC97_AD1986_SODIS | AC97_AD1986_CLDIS |
2425 AC97_AD1986_LISEL_MASK,
2426 misc_val);
2427
2428 /* select microphone input (MIC_1/2, Center/LFE or LINE_IN) */
2429 if (is_shared_micin(ac97))
2430 ser_val = AC97_AD1986_OMS_C;
2431 else if (ac97->spec.ad18xx.swap_mic_linein != 0)
2432 ser_val = AC97_AD1986_OMS_L;
2433 else
2434 ser_val = AC97_AD1986_OMS_M;
2435 snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG,
2436 AC97_AD1986_OMS_MASK,
2437 ser_val);
2438}
2439
2440static int patch_ad1986_specific(struct snd_ac97 *ac97)
2441{
2442 int err;
2443
2444 if ((err = patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1)) < 0)
2445 return err;
2446
2447 return patch_build_controls(ac97, snd_ac97_ad1986_controls,
2448 ARRAY_SIZE(snd_ac97_ad1985_controls));
2449}
2450
2451static struct snd_ac97_build_ops patch_ad1986_build_ops = {
2452 .build_post_spdif = patch_ad198x_post_spdif,
2453 .build_specific = patch_ad1986_specific,
2454#ifdef CONFIG_PM
2455 .resume = ad18xx_resume,
2456#endif
2457 .update_jacks = ad1986_update_jacks,
2458};
2459
2460int patch_ad1986(struct snd_ac97 * ac97)
2461{
2462 patch_ad1881(ac97);
2463 ac97->build_ops = &patch_ad1986_build_ops;
2464 ac97->flags |= AC97_STEREO_MUTES;
2465
2466 /* update current jack configuration */
2467 ad1986_update_jacks(ac97);
2468
2469 return 0;
2470}
2471
2472
2010/* 2473/*
2011 * realtek ALC65x/850 codecs 2474 * realtek ALC65x/850 codecs
2012 */ 2475 */
@@ -2014,12 +2477,12 @@ static void alc650_update_jacks(struct snd_ac97 *ac97)
2014{ 2477{
2015 int shared; 2478 int shared;
2016 2479
2017 /* shared Line-In */ 2480 /* shared Line-In / Surround Out */
2018 shared = is_shared_linein(ac97); 2481 shared = is_shared_surrout(ac97);
2019 snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 9, 2482 snd_ac97_update_bits(ac97, AC97_ALC650_MULTICH, 1 << 9,
2020 shared ? (1 << 9) : 0); 2483 shared ? (1 << 9) : 0);
2021 /* update shared Mic */ 2484 /* update shared Mic In / Center/LFE Out */
2022 shared = is_shared_micin(ac97); 2485 shared = is_shared_clfeout(ac97);
2023 /* disable/enable vref */ 2486 /* disable/enable vref */
2024 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12, 2487 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
2025 shared ? (1 << 12) : 0); 2488 shared ? (1 << 12) : 0);
@@ -2064,7 +2527,7 @@ static const struct snd_kcontrol_new snd_ac97_spdif_controls_alc650[] = {
2064 /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */ 2527 /* AC97_SINGLE("IEC958 Input Monitor", AC97_ALC650_MULTICH, 13, 1, 0), */
2065}; 2528};
2066 2529
2067static DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max, -4350, 150, 0); 2530static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max, -4350, 150, 0);
2068 2531
2069static int patch_alc650_specific(struct snd_ac97 * ac97) 2532static int patch_alc650_specific(struct snd_ac97 * ac97)
2070{ 2533{
@@ -2149,12 +2612,12 @@ static void alc655_update_jacks(struct snd_ac97 *ac97)
2149{ 2612{
2150 int shared; 2613 int shared;
2151 2614
2152 /* shared Line-In */ 2615 /* shared Line-In / Surround Out */
2153 shared = is_shared_linein(ac97); 2616 shared = is_shared_surrout(ac97);
2154 ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 9, 2617 ac97_update_bits_page(ac97, AC97_ALC650_MULTICH, 1 << 9,
2155 shared ? (1 << 9) : 0, 0); 2618 shared ? (1 << 9) : 0, 0);
2156 /* update shared mic */ 2619 /* update shared Mic In / Center/LFE Out */
2157 shared = is_shared_micin(ac97); 2620 shared = is_shared_clfeout(ac97);
2158 /* misc control; vrefout disable */ 2621 /* misc control; vrefout disable */
2159 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12, 2622 snd_ac97_update_bits(ac97, AC97_ALC650_CLOCK, 1 << 12,
2160 shared ? (1 << 12) : 0); 2623 shared ? (1 << 12) : 0);
@@ -2264,7 +2727,8 @@ int patch_alc655(struct snd_ac97 * ac97)
2264 if (ac97->subsystem_vendor == 0x1462 && 2727 if (ac97->subsystem_vendor == 0x1462 &&
2265 (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */ 2728 (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */
2266 ac97->subsystem_device == 0x0161 || /* LG K1 Express */ 2729 ac97->subsystem_device == 0x0161 || /* LG K1 Express */
2267 ac97->subsystem_device == 0x0351)) /* MSI L725 laptop */ 2730 ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */
2731 ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */
2268 val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ 2732 val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */
2269 else 2733 else
2270 val |= (1 << 1); /* Pin 47 is spdif input pin */ 2734 val |= (1 << 1); /* Pin 47 is spdif input pin */
@@ -2297,16 +2761,16 @@ static void alc850_update_jacks(struct snd_ac97 *ac97)
2297{ 2761{
2298 int shared; 2762 int shared;
2299 2763
2300 /* shared Line-In */ 2764 /* shared Line-In / Surround Out */
2301 shared = is_shared_linein(ac97); 2765 shared = is_shared_surrout(ac97);
2302 /* SURR 1kOhm (bit4), Amp (bit5) */ 2766 /* SURR 1kOhm (bit4), Amp (bit5) */
2303 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5), 2767 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5),
2304 shared ? (1<<5) : (1<<4)); 2768 shared ? (1<<5) : (1<<4));
2305 /* LINE-IN = 0, SURROUND = 2 */ 2769 /* LINE-IN = 0, SURROUND = 2 */
2306 snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12, 2770 snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 12,
2307 shared ? (2<<12) : (0<<12)); 2771 shared ? (2<<12) : (0<<12));
2308 /* update shared mic */ 2772 /* update shared Mic In / Center/LFE Out */
2309 shared = is_shared_micin(ac97); 2773 shared = is_shared_clfeout(ac97);
2310 /* Vref disable (bit12), 1kOhm (bit13) */ 2774 /* Vref disable (bit12), 1kOhm (bit13) */
2311 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13), 2775 snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13),
2312 shared ? (1<<12) : (1<<13)); 2776 shared ? (1<<12) : (1<<13));
@@ -2379,9 +2843,9 @@ int patch_alc850(struct snd_ac97 *ac97)
2379 */ 2843 */
2380static void cm9738_update_jacks(struct snd_ac97 *ac97) 2844static void cm9738_update_jacks(struct snd_ac97 *ac97)
2381{ 2845{
2382 /* shared Line-In */ 2846 /* shared Line-In / Surround Out */
2383 snd_ac97_update_bits(ac97, AC97_CM9738_VENDOR_CTRL, 1 << 10, 2847 snd_ac97_update_bits(ac97, AC97_CM9738_VENDOR_CTRL, 1 << 10,
2384 is_shared_linein(ac97) ? (1 << 10) : 0); 2848 is_shared_surrout(ac97) ? (1 << 10) : 0);
2385} 2849}
2386 2850
2387static const struct snd_kcontrol_new snd_ac97_cm9738_controls[] = { 2851static const struct snd_kcontrol_new snd_ac97_cm9738_controls[] = {
@@ -2463,12 +2927,12 @@ static const struct snd_kcontrol_new snd_ac97_cm9739_controls_spdif[] = {
2463 2927
2464static void cm9739_update_jacks(struct snd_ac97 *ac97) 2928static void cm9739_update_jacks(struct snd_ac97 *ac97)
2465{ 2929{
2466 /* shared Line-In */ 2930 /* shared Line-In / Surround Out */
2467 snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 1 << 10, 2931 snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 1 << 10,
2468 is_shared_linein(ac97) ? (1 << 10) : 0); 2932 is_shared_surrout(ac97) ? (1 << 10) : 0);
2469 /* shared Mic */ 2933 /* shared Mic In / Center/LFE Out **/
2470 snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000, 2934 snd_ac97_update_bits(ac97, AC97_CM9739_MULTI_CHAN, 0x3000,
2471 is_shared_micin(ac97) ? 0x1000 : 0x2000); 2935 is_shared_clfeout(ac97) ? 0x1000 : 0x2000);
2472} 2936}
2473 2937
2474static const struct snd_kcontrol_new snd_ac97_cm9739_controls[] = { 2938static const struct snd_kcontrol_new snd_ac97_cm9739_controls[] = {
@@ -2580,8 +3044,8 @@ static void cm9761_update_jacks(struct snd_ac97 *ac97)
2580 3044
2581 val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)]; 3045 val |= surr_on[ac97->spec.dev_flags][is_surround_on(ac97)];
2582 val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)]; 3046 val |= clfe_on[ac97->spec.dev_flags][is_clfe_on(ac97)];
2583 val |= surr_shared[ac97->spec.dev_flags][is_shared_linein(ac97)]; 3047 val |= surr_shared[ac97->spec.dev_flags][is_shared_surrout(ac97)];
2584 val |= clfe_shared[ac97->spec.dev_flags][is_shared_micin(ac97)]; 3048 val |= clfe_shared[ac97->spec.dev_flags][is_shared_clfeout(ac97)];
2585 3049
2586 snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val); 3050 snd_ac97_update_bits(ac97, AC97_CM9761_MULTI_CHAN, 0x3c88, val);
2587} 3051}
@@ -2821,6 +3285,7 @@ int patch_vt1617a(struct snd_ac97 * ac97)
2821 snd_ac97_write_cache(ac97, 0x5c, 0x20); 3285 snd_ac97_write_cache(ac97, 0x5c, 0x20);
2822 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ 3286 ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */
2823 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; 3287 ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
3288 ac97->build_ops = &patch_vt1616_ops;
2824 return 0; 3289 return 0;
2825} 3290}
2826 3291
@@ -2828,12 +3293,12 @@ int patch_vt1617a(struct snd_ac97 * ac97)
2828 */ 3293 */
2829static void it2646_update_jacks(struct snd_ac97 *ac97) 3294static void it2646_update_jacks(struct snd_ac97 *ac97)
2830{ 3295{
2831 /* shared Line-In */ 3296 /* shared Line-In / Surround Out */
2832 snd_ac97_update_bits(ac97, 0x76, 1 << 9, 3297 snd_ac97_update_bits(ac97, 0x76, 1 << 9,
2833 is_shared_linein(ac97) ? (1<<9) : 0); 3298 is_shared_surrout(ac97) ? (1<<9) : 0);
2834 /* shared Mic */ 3299 /* shared Mic / Center/LFE Out */
2835 snd_ac97_update_bits(ac97, 0x76, 1 << 10, 3300 snd_ac97_update_bits(ac97, 0x76, 1 << 10,
2836 is_shared_micin(ac97) ? (1<<10) : 0); 3301 is_shared_clfeout(ac97) ? (1<<10) : 0);
2837} 3302}
2838 3303
2839static const struct snd_kcontrol_new snd_ac97_controls_it2646[] = { 3304static const struct snd_kcontrol_new snd_ac97_controls_it2646[] = {
diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h
index 741979217207..94340daaaf1f 100644
--- a/sound/pci/ac97/ac97_patch.h
+++ b/sound/pci/ac97/ac97_patch.h
@@ -48,6 +48,7 @@ int patch_ad1980(struct snd_ac97 * ac97);
48int patch_ad1981a(struct snd_ac97 * ac97); 48int patch_ad1981a(struct snd_ac97 * ac97);
49int patch_ad1981b(struct snd_ac97 * ac97); 49int patch_ad1981b(struct snd_ac97 * ac97);
50int patch_ad1985(struct snd_ac97 * ac97); 50int patch_ad1985(struct snd_ac97 * ac97);
51int patch_ad1986(struct snd_ac97 * ac97);
51int patch_alc650(struct snd_ac97 * ac97); 52int patch_alc650(struct snd_ac97 * ac97);
52int patch_alc655(struct snd_ac97 * ac97); 53int patch_alc655(struct snd_ac97 * ac97);
53int patch_alc850(struct snd_ac97 * ac97); 54int patch_alc850(struct snd_ac97 * ac97);
diff --git a/sound/pci/ac97/ak4531_codec.c b/sound/pci/ac97/ak4531_codec.c
index c153cb79c518..dc26820a03a5 100644
--- a/sound/pci/ac97/ak4531_codec.c
+++ b/sound/pci/ac97/ak4531_codec.c
@@ -267,9 +267,9 @@ static int snd_ak4531_put_input_sw(struct snd_kcontrol *kcontrol, struct snd_ctl
267 return change; 267 return change;
268} 268}
269 269
270static DECLARE_TLV_DB_SCALE(db_scale_master, -6200, 200, 0); 270static const DECLARE_TLV_DB_SCALE(db_scale_master, -6200, 200, 0);
271static DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0); 271static const DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0);
272static DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0); 272static const DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0);
273 273
274static struct snd_kcontrol_new snd_ak4531_controls[] = { 274static struct snd_kcontrol_new snd_ak4531_controls[] = {
275 275
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 9f406fbe0d95..8afcb98ca7bb 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -444,7 +444,7 @@ static int snd_als300_capture_close(struct snd_pcm_substream *substream)
444} 444}
445 445
446static int snd_als300_pcm_hw_params(struct snd_pcm_substream *substream, 446static int snd_als300_pcm_hw_params(struct snd_pcm_substream *substream,
447 snd_pcm_hw_params_t * hw_params) 447 struct snd_pcm_hw_params *hw_params)
448{ 448{
449 return snd_pcm_lib_malloc_pages(substream, 449 return snd_pcm_lib_malloc_pages(substream,
450 params_buffer_bytes(hw_params)); 450 params_buffer_bytes(hw_params));
@@ -673,7 +673,7 @@ static void snd_als300_init(struct snd_als300 *chip)
673 snd_als300_dbgcallleave(); 673 snd_als300_dbgcallleave();
674} 674}
675 675
676static int __devinit snd_als300_create(snd_card_t *card, 676static int __devinit snd_als300_create(struct snd_card *card,
677 struct pci_dev *pci, int chip_type, 677 struct pci_dev *pci, int chip_type,
678 struct snd_als300 **rchip) 678 struct snd_als300 **rchip)
679{ 679{
@@ -681,7 +681,7 @@ static int __devinit snd_als300_create(snd_card_t *card,
681 void *irq_handler; 681 void *irq_handler;
682 int err; 682 int err;
683 683
684 static snd_device_ops_t ops = { 684 static struct snd_device_ops ops = {
685 .dev_free = snd_als300_dev_free, 685 .dev_free = snd_als300_dev_free,
686 }; 686 };
687 *rchip = NULL; 687 *rchip = NULL;
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 476c3433073e..7d8053b5e8d5 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -45,6 +45,7 @@ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */
45static int ac97_clock = 48000; 45static int ac97_clock = 48000;
46static char *ac97_quirk; 46static char *ac97_quirk;
47static int spdif_aclink = 1; 47static int spdif_aclink = 1;
48static int ac97_codec = -1;
48 49
49module_param(index, int, 0444); 50module_param(index, int, 0444);
50MODULE_PARM_DESC(index, "Index value for ATI IXP controller."); 51MODULE_PARM_DESC(index, "Index value for ATI IXP controller.");
@@ -54,6 +55,8 @@ module_param(ac97_clock, int, 0444);
54MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); 55MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
55module_param(ac97_quirk, charp, 0444); 56module_param(ac97_quirk, charp, 0444);
56MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); 57MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
58module_param(ac97_codec, int, 0444);
59MODULE_PARM_DESC(ac97_codec, "Specify codec instead of probing.");
57module_param(spdif_aclink, bool, 0444); 60module_param(spdif_aclink, bool, 0444);
58MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); 61MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
59 62
@@ -293,6 +296,10 @@ static struct pci_device_id snd_atiixp_ids[] = {
293 296
294MODULE_DEVICE_TABLE(pci, snd_atiixp_ids); 297MODULE_DEVICE_TABLE(pci, snd_atiixp_ids);
295 298
299static struct snd_pci_quirk atiixp_quirks[] __devinitdata = {
300 SND_PCI_QUIRK(0x15bd, 0x3100, "DFI RS482", 0),
301 { } /* terminator */
302};
296 303
297/* 304/*
298 * lowlevel functions 305 * lowlevel functions
@@ -553,11 +560,33 @@ static int snd_atiixp_aclink_down(struct atiixp *chip)
553 ATI_REG_ISR_CODEC2_NOT_READY) 560 ATI_REG_ISR_CODEC2_NOT_READY)
554#define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME) 561#define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME)
555 562
563static int ac97_probing_bugs(struct pci_dev *pci)
564{
565 const struct snd_pci_quirk *q;
566
567 q = snd_pci_quirk_lookup(pci, atiixp_quirks);
568 if (q) {
569 snd_printdd(KERN_INFO "Atiixp quirk for %s. "
570 "Forcing codec %d\n", q->name, q->value);
571 return q->value;
572 }
573 /* this hardware doesn't need workarounds. Probe for codec */
574 return -1;
575}
576
556static int snd_atiixp_codec_detect(struct atiixp *chip) 577static int snd_atiixp_codec_detect(struct atiixp *chip)
557{ 578{
558 int timeout; 579 int timeout;
559 580
560 chip->codec_not_ready_bits = 0; 581 chip->codec_not_ready_bits = 0;
582 if (ac97_codec == -1)
583 ac97_codec = ac97_probing_bugs(chip->pci);
584 if (ac97_codec >= 0) {
585 chip->codec_not_ready_bits |=
586 CODEC_CHECK_BITS ^ (1 << (ac97_codec + 10));
587 return 0;
588 }
589
561 atiixp_write(chip, IER, CODEC_CHECK_BITS); 590 atiixp_write(chip, IER, CODEC_CHECK_BITS);
562 /* wait for the interrupts */ 591 /* wait for the interrupts */
563 timeout = 50; 592 timeout = 50;
@@ -1396,7 +1425,7 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp *chip, int clock,
1396 ac97.private_data = chip; 1425 ac97.private_data = chip;
1397 ac97.pci = chip->pci; 1426 ac97.pci = chip->pci;
1398 ac97.num = i; 1427 ac97.num = i;
1399 ac97.scaps = AC97_SCAP_SKIP_MODEM; 1428 ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
1400 if (! chip->spdif_over_aclink) 1429 if (! chip->spdif_over_aclink)
1401 ac97.scaps |= AC97_SCAP_NO_SPDIF; 1430 ac97.scaps |= AC97_SCAP_NO_SPDIF;
1402 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) { 1431 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index cc2e6b9d407e..904023fe4f26 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1090,7 +1090,7 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
1090 ac97.private_data = chip; 1090 ac97.private_data = chip;
1091 ac97.pci = chip->pci; 1091 ac97.pci = chip->pci;
1092 ac97.num = i; 1092 ac97.num = i;
1093 ac97.scaps = AC97_SCAP_SKIP_AUDIO; 1093 ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
1094 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) { 1094 if ((err = snd_ac97_mixer(pbus, &ac97, &chip->ac97[i])) < 0) {
1095 chip->ac97[i] = NULL; /* to be sure */ 1095 chip->ac97[i] = NULL; /* to be sure */
1096 snd_printdd("atiixp-modem: codec %d not available for modem\n", i); 1096 snd_printdd("atiixp-modem: codec %d not available for modem\n", i);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index f61f052f6d14..ea6712b63c9f 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1382,7 +1382,6 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1382 snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf); 1382 snd_ca0106_ptr_write(chip, SPDIF_SELECT1, 0, 0xf);
1383 snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers. Use 0x000f0000 for surround71 */ 1383 snd_ca0106_ptr_write(chip, SPDIF_SELECT2, 0, 0x000f0000); /* 0x0b000000 for digital, 0x000b0000 for analog, from win2000 drivers. Use 0x000f0000 for surround71 */
1384 chip->spdif_enable = 0; /* Set digital SPDIF output off */ 1384 chip->spdif_enable = 0; /* Set digital SPDIF output off */
1385 chip->capture_source = 3; /* Set CAPTURE_SOURCE */
1386 //snd_ca0106_ptr_write(chip, 0x45, 0, 0); /* Analogue out */ 1385 //snd_ca0106_ptr_write(chip, 0x45, 0, 0); /* Analogue out */
1387 //snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00); /* Digital out */ 1386 //snd_ca0106_ptr_write(chip, 0x45, 0, 0xf00); /* Digital out */
1388 1387
@@ -1402,8 +1401,22 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
1402 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff); /* Mute */ 1401 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME1, ch, 0xffffffff); /* Mute */
1403 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff); /* Mute */ 1402 snd_ca0106_ptr_write(chip, PLAYBACK_VOLUME2, ch, 0xffffffff); /* Mute */
1404 } 1403 }
1405 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC, Line in, TAD in, AUX in */ 1404 if (chip->details->i2c_adc == 1) {
1406 chip->capture_source = 3; /* Set CAPTURE_SOURCE */ 1405 /* Select MIC, Line in, TAD in, AUX in */
1406 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4);
1407 /* Default to CAPTURE_SOURCE to i2s in */
1408 chip->capture_source = 3;
1409 } else if (chip->details->ac97 == 1) {
1410 /* Default to AC97 in */
1411 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x444400e4);
1412 /* Default to CAPTURE_SOURCE to AC97 in */
1413 chip->capture_source = 4;
1414 } else {
1415 /* Select MIC, Line in, TAD in, AUX in */
1416 snd_ca0106_ptr_write(chip, CAPTURE_SOURCE, 0x0, 0x333300e4);
1417 /* Default to Set CAPTURE_SOURCE to i2s in */
1418 chip->capture_source = 3;
1419 }
1407 1420
1408 if (chip->details->gpio_type == 2) { /* The SB0438 use GPIO differently. */ 1421 if (chip->details->gpio_type == 2) { /* The SB0438 use GPIO differently. */
1409 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */ 1422 /* FIXME: Still need to find out what the other GPIO bits do. E.g. For digital spdif out. */
@@ -1605,6 +1618,8 @@ static int __devinit snd_ca0106_probe(struct pci_dev *pci,
1605 snd_ca0106_proc_init(chip); 1618 snd_ca0106_proc_init(chip);
1606#endif 1619#endif
1607 1620
1621 snd_card_set_dev(card, &pci->dev);
1622
1608 if ((err = snd_card_register(card)) < 0) { 1623 if ((err = snd_card_register(card)) < 0) {
1609 snd_card_free(card); 1624 snd_card_free(card);
1610 return err; 1625 return err;
diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c
index 9855f528ea78..b913a1fb8c21 100644
--- a/sound/pci/ca0106/ca0106_mixer.c
+++ b/sound/pci/ca0106/ca0106_mixer.c
@@ -74,8 +74,8 @@
74 74
75#include "ca0106.h" 75#include "ca0106.h"
76 76
77static DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1); 77static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1);
78static DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1); 78static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1);
79 79
80static int snd_ca0106_shared_spdif_info(struct snd_kcontrol *kcontrol, 80static int snd_ca0106_shared_spdif_info(struct snd_kcontrol *kcontrol,
81 struct snd_ctl_elem_info *uinfo) 81 struct snd_ctl_elem_info *uinfo)
@@ -482,19 +482,6 @@ static int snd_ca0106_i2c_volume_put(struct snd_kcontrol *kcontrol,
482 .private_value = ((chid) << 8) | (reg) \ 482 .private_value = ((chid) << 8) | (reg) \
483} 483}
484 484
485#define I2C_VOLUME(xname,chid) \
486{ \
487 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
488 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
489 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
490 .info = snd_ca0106_i2c_volume_info, \
491 .get = snd_ca0106_i2c_volume_get, \
492 .put = snd_ca0106_i2c_volume_put, \
493 .tlv = { .p = snd_ca0106_db_scale2 }, \
494 .private_value = chid \
495}
496
497
498static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = { 485static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
499 CA_VOLUME("Analog Front Playback Volume", 486 CA_VOLUME("Analog Front Playback Volume",
500 CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2), 487 CONTROL_FRONT_CHANNEL, PLAYBACK_VOLUME2),
@@ -517,11 +504,6 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
517 CA_VOLUME("CAPTURE feedback Playback Volume", 504 CA_VOLUME("CAPTURE feedback Playback Volume",
518 1, CAPTURE_CONTROL), 505 1, CAPTURE_CONTROL),
519 506
520 I2C_VOLUME("Phone Capture Volume", 0),
521 I2C_VOLUME("Mic Capture Volume", 1),
522 I2C_VOLUME("Line in Capture Volume", 2),
523 I2C_VOLUME("Aux Capture Volume", 3),
524
525 { 507 {
526 .access = SNDRV_CTL_ELEM_ACCESS_READ, 508 .access = SNDRV_CTL_ELEM_ACCESS_READ,
527 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 509 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -539,14 +521,14 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
539 }, 521 },
540 { 522 {
541 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
542 .name = "Digital Capture Source", 524 .name = "Digital Source Capture Enum",
543 .info = snd_ca0106_capture_source_info, 525 .info = snd_ca0106_capture_source_info,
544 .get = snd_ca0106_capture_source_get, 526 .get = snd_ca0106_capture_source_get,
545 .put = snd_ca0106_capture_source_put 527 .put = snd_ca0106_capture_source_put
546 }, 528 },
547 { 529 {
548 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 530 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
549 .name = "Capture Source", 531 .name = "Analog Source Capture Enum",
550 .info = snd_ca0106_i2c_capture_source_info, 532 .info = snd_ca0106_i2c_capture_source_info,
551 .get = snd_ca0106_i2c_capture_source_get, 533 .get = snd_ca0106_i2c_capture_source_get,
552 .put = snd_ca0106_i2c_capture_source_put 534 .put = snd_ca0106_i2c_capture_source_put
@@ -561,6 +543,25 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
561 }, 543 },
562}; 544};
563 545
546#define I2C_VOLUME(xname,chid) \
547{ \
548 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
549 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
550 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
551 .info = snd_ca0106_i2c_volume_info, \
552 .get = snd_ca0106_i2c_volume_get, \
553 .put = snd_ca0106_i2c_volume_put, \
554 .tlv = { .p = snd_ca0106_db_scale2 }, \
555 .private_value = chid \
556}
557
558static struct snd_kcontrol_new snd_ca0106_volume_i2c_adc_ctls[] __devinitdata = {
559 I2C_VOLUME("Phone Capture Volume", 0),
560 I2C_VOLUME("Mic Capture Volume", 1),
561 I2C_VOLUME("Line in Capture Volume", 2),
562 I2C_VOLUME("Aux Capture Volume", 3),
563};
564
564static int __devinit remove_ctl(struct snd_card *card, const char *name) 565static int __devinit remove_ctl(struct snd_card *card, const char *name)
565{ 566{
566 struct snd_ctl_elem_id id; 567 struct snd_ctl_elem_id id;
@@ -645,6 +646,11 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
645 return err; 646 return err;
646 } 647 }
647 if (emu->details->i2c_adc == 1) { 648 if (emu->details->i2c_adc == 1) {
649 for (i = 0; i < ARRAY_SIZE(snd_ca0106_volume_i2c_adc_ctls); i++) {
650 err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_volume_i2c_adc_ctls[i], emu));
651 if (err < 0)
652 return err;
653 }
648 if (emu->details->gpio_type == 1) 654 if (emu->details->gpio_type == 1)
649 err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu)); 655 err = snd_ctl_add(card, snd_ctl_new1(&snd_ca0106_capture_mic_line_in, emu));
650 else /* gpio_type == 2 */ 656 else /* gpio_type == 2 */
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 8e5519de7115..44cf54607647 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1055,7 +1055,7 @@ static int snd_cs4281_put_volume(struct snd_kcontrol *kcontrol,
1055 return change; 1055 return change;
1056} 1056}
1057 1057
1058static DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0); 1058static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0);
1059 1059
1060static struct snd_kcontrol_new snd_cs4281_fm_vol = 1060static struct snd_kcontrol_new snd_cs4281_fm_vol =
1061{ 1061{
diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c
index b7108e29a668..8e7fe033270f 100644
--- a/sound/pci/echoaudio/darla20.c
+++ b/sound/pci/echoaudio/darla20.c
@@ -47,6 +47,7 @@
47#include <sound/core.h> 47#include <sound/core.h>
48#include <sound/info.h> 48#include <sound/info.h>
49#include <sound/control.h> 49#include <sound/control.h>
50#include <sound/tlv.h>
50#include <sound/pcm.h> 51#include <sound/pcm.h>
51#include <sound/pcm_params.h> 52#include <sound/pcm_params.h>
52#include <sound/asoundef.h> 53#include <sound/asoundef.h>
diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c
index e59a982ee361..a13c623eb999 100644
--- a/sound/pci/echoaudio/darla24.c
+++ b/sound/pci/echoaudio/darla24.c
@@ -51,6 +51,7 @@
51#include <sound/core.h> 51#include <sound/core.h>
52#include <sound/info.h> 52#include <sound/info.h>
53#include <sound/control.h> 53#include <sound/control.h>
54#include <sound/tlv.h>
54#include <sound/pcm.h> 55#include <sound/pcm.h>
55#include <sound/pcm_params.h> 56#include <sound/pcm_params.h>
56#include <sound/asoundef.h> 57#include <sound/asoundef.h>
diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c
index 12099fe1547d..8fb15823aca5 100644
--- a/sound/pci/echoaudio/echo3g.c
+++ b/sound/pci/echoaudio/echo3g.c
@@ -58,6 +58,7 @@
58#include <sound/core.h> 58#include <sound/core.h>
59#include <sound/info.h> 59#include <sound/info.h>
60#include <sound/control.h> 60#include <sound/control.h>
61#include <sound/tlv.h>
61#include <sound/pcm.h> 62#include <sound/pcm.h>
62#include <sound/pcm_params.h> 63#include <sound/pcm_params.h>
63#include <sound/asoundef.h> 64#include <sound/asoundef.h>
diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c
index d26a1d1f3ed1..48eb7c599111 100644
--- a/sound/pci/echoaudio/echo3g_dsp.c
+++ b/sound/pci/echoaudio/echo3g_dsp.c
@@ -39,7 +39,7 @@ static int set_phantom_power(struct echoaudio *chip, char on);
39static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, 39static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq,
40 char force); 40 char force);
41 41
42#include <linux/irq.h> 42#include <linux/interrupt.h>
43 43
44static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) 44static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
45{ 45{
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 047e0b5bf15d..6a428b81dba6 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -34,6 +34,7 @@ module_param_array(enable, bool, NULL, 0444);
34MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard."); 34MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard.");
35 35
36static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; 36static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999};
37static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1);
37 38
38static int get_firmware(const struct firmware **fw_entry, 39static int get_firmware(const struct firmware **fw_entry,
39 const struct firmware *frm, struct echoaudio *chip) 40 const struct firmware *frm, struct echoaudio *chip)
@@ -1011,17 +1012,21 @@ static int snd_echo_output_gain_put(struct snd_kcontrol *kcontrol,
1011static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = { 1012static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = {
1012 .name = "Line Playback Volume", 1013 .name = "Line Playback Volume",
1013 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1014 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1015 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
1014 .info = snd_echo_output_gain_info, 1016 .info = snd_echo_output_gain_info,
1015 .get = snd_echo_output_gain_get, 1017 .get = snd_echo_output_gain_get,
1016 .put = snd_echo_output_gain_put, 1018 .put = snd_echo_output_gain_put,
1019 .tlv = {.p = db_scale_output_gain},
1017}; 1020};
1018#else 1021#else
1019static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { 1022static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = {
1020 .name = "PCM Playback Volume", 1023 .name = "PCM Playback Volume",
1021 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1024 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1025 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
1022 .info = snd_echo_output_gain_info, 1026 .info = snd_echo_output_gain_info,
1023 .get = snd_echo_output_gain_get, 1027 .get = snd_echo_output_gain_get,
1024 .put = snd_echo_output_gain_put, 1028 .put = snd_echo_output_gain_put,
1029 .tlv = {.p = db_scale_output_gain},
1025}; 1030};
1026#endif 1031#endif
1027 1032
@@ -1080,12 +1085,16 @@ static int snd_echo_input_gain_put(struct snd_kcontrol *kcontrol,
1080 return changed; 1085 return changed;
1081} 1086}
1082 1087
1088static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0);
1089
1083static struct snd_kcontrol_new snd_echo_line_input_gain __devinitdata = { 1090static struct snd_kcontrol_new snd_echo_line_input_gain __devinitdata = {
1084 .name = "Line Capture Volume", 1091 .name = "Line Capture Volume",
1085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1092 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1093 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
1086 .info = snd_echo_input_gain_info, 1094 .info = snd_echo_input_gain_info,
1087 .get = snd_echo_input_gain_get, 1095 .get = snd_echo_input_gain_get,
1088 .put = snd_echo_input_gain_put, 1096 .put = snd_echo_input_gain_put,
1097 .tlv = {.p = db_scale_input_gain},
1089}; 1098};
1090 1099
1091#endif /* ECHOCARD_HAS_INPUT_GAIN */ 1100#endif /* ECHOCARD_HAS_INPUT_GAIN */
@@ -1277,9 +1286,11 @@ static int snd_echo_mixer_put(struct snd_kcontrol *kcontrol,
1277static struct snd_kcontrol_new snd_echo_monitor_mixer __devinitdata = { 1286static struct snd_kcontrol_new snd_echo_monitor_mixer __devinitdata = {
1278 .name = "Monitor Mixer Volume", 1287 .name = "Monitor Mixer Volume",
1279 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1288 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1289 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
1280 .info = snd_echo_mixer_info, 1290 .info = snd_echo_mixer_info,
1281 .get = snd_echo_mixer_get, 1291 .get = snd_echo_mixer_get,
1282 .put = snd_echo_mixer_put, 1292 .put = snd_echo_mixer_put,
1293 .tlv = {.p = db_scale_output_gain},
1283}; 1294};
1284 1295
1285#endif /* ECHOCARD_HAS_MONITOR */ 1296#endif /* ECHOCARD_HAS_MONITOR */
@@ -1343,9 +1354,11 @@ static int snd_echo_vmixer_put(struct snd_kcontrol *kcontrol,
1343static struct snd_kcontrol_new snd_echo_vmixer __devinitdata = { 1354static struct snd_kcontrol_new snd_echo_vmixer __devinitdata = {
1344 .name = "VMixer Volume", 1355 .name = "VMixer Volume",
1345 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1356 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1357 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ,
1346 .info = snd_echo_vmixer_info, 1358 .info = snd_echo_vmixer_info,
1347 .get = snd_echo_vmixer_get, 1359 .get = snd_echo_vmixer_get,
1348 .put = snd_echo_vmixer_put, 1360 .put = snd_echo_vmixer_put,
1361 .tlv = {.p = db_scale_output_gain},
1349}; 1362};
1350 1363
1351#endif /* ECHOCARD_HAS_VMIXER */ 1364#endif /* ECHOCARD_HAS_VMIXER */
@@ -1753,9 +1766,12 @@ static int snd_echo_vumeters_get(struct snd_kcontrol *kcontrol,
1753static struct snd_kcontrol_new snd_echo_vumeters __devinitdata = { 1766static struct snd_kcontrol_new snd_echo_vumeters __devinitdata = {
1754 .name = "VU-meters", 1767 .name = "VU-meters",
1755 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1768 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1756 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 1769 .access = SNDRV_CTL_ELEM_ACCESS_READ |
1770 SNDRV_CTL_ELEM_ACCESS_VOLATILE |
1771 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
1757 .info = snd_echo_vumeters_info, 1772 .info = snd_echo_vumeters_info,
1758 .get = snd_echo_vumeters_get, 1773 .get = snd_echo_vumeters_get,
1774 .tlv = {.p = db_scale_output_gain},
1759}; 1775};
1760 1776
1761 1777
diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c
index 29d6d12f80ca..af4d32026e4a 100644
--- a/sound/pci/echoaudio/gina20.c
+++ b/sound/pci/echoaudio/gina20.c
@@ -51,6 +51,7 @@
51#include <sound/core.h> 51#include <sound/core.h>
52#include <sound/info.h> 52#include <sound/info.h>
53#include <sound/control.h> 53#include <sound/control.h>
54#include <sound/tlv.h>
54#include <sound/pcm.h> 55#include <sound/pcm.h>
55#include <sound/pcm_params.h> 56#include <sound/pcm_params.h>
56#include <sound/asoundef.h> 57#include <sound/asoundef.h>
diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c
index e464d720d0bd..9ff454a947ed 100644
--- a/sound/pci/echoaudio/gina24.c
+++ b/sound/pci/echoaudio/gina24.c
@@ -57,6 +57,7 @@
57#include <sound/core.h> 57#include <sound/core.h>
58#include <sound/info.h> 58#include <sound/info.h>
59#include <sound/control.h> 59#include <sound/control.h>
60#include <sound/tlv.h>
60#include <sound/pcm.h> 61#include <sound/pcm.h>
61#include <sound/pcm_params.h> 62#include <sound/pcm_params.h>
62#include <sound/asoundef.h> 63#include <sound/asoundef.h>
diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c
index bfd2467099ac..37eb726fd03d 100644
--- a/sound/pci/echoaudio/indigo.c
+++ b/sound/pci/echoaudio/indigo.c
@@ -49,6 +49,7 @@
49#include <sound/core.h> 49#include <sound/core.h>
50#include <sound/info.h> 50#include <sound/info.h>
51#include <sound/control.h> 51#include <sound/control.h>
52#include <sound/tlv.h>
52#include <sound/pcm.h> 53#include <sound/pcm.h>
53#include <sound/pcm_params.h> 54#include <sound/pcm_params.h>
54#include <sound/asoundef.h> 55#include <sound/asoundef.h>
diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c
index 8ed7ff1fd875..dc8b91824181 100644
--- a/sound/pci/echoaudio/indigodj.c
+++ b/sound/pci/echoaudio/indigodj.c
@@ -49,6 +49,7 @@
49#include <sound/core.h> 49#include <sound/core.h>
50#include <sound/info.h> 50#include <sound/info.h>
51#include <sound/control.h> 51#include <sound/control.h>
52#include <sound/tlv.h>
52#include <sound/pcm.h> 53#include <sound/pcm.h>
53#include <sound/pcm_params.h> 54#include <sound/pcm_params.h>
54#include <sound/asoundef.h> 55#include <sound/asoundef.h>
diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c
index a8788e959171..eadf3263453a 100644
--- a/sound/pci/echoaudio/indigoio.c
+++ b/sound/pci/echoaudio/indigoio.c
@@ -50,6 +50,7 @@
50#include <sound/core.h> 50#include <sound/core.h>
51#include <sound/info.h> 51#include <sound/info.h>
52#include <sound/control.h> 52#include <sound/control.h>
53#include <sound/tlv.h>
53#include <sound/pcm.h> 54#include <sound/pcm.h>
54#include <sound/pcm_params.h> 55#include <sound/pcm_params.h>
55#include <sound/asoundef.h> 56#include <sound/asoundef.h>
diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c
index e503d74b3ba9..6cede497579e 100644
--- a/sound/pci/echoaudio/layla20.c
+++ b/sound/pci/echoaudio/layla20.c
@@ -56,6 +56,7 @@
56#include <sound/core.h> 56#include <sound/core.h>
57#include <sound/info.h> 57#include <sound/info.h>
58#include <sound/control.h> 58#include <sound/control.h>
59#include <sound/tlv.h>
59#include <sound/pcm.h> 60#include <sound/pcm.h>
60#include <sound/pcm_params.h> 61#include <sound/pcm_params.h>
61#include <sound/asoundef.h> 62#include <sound/asoundef.h>
diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c
index d4581fdc841c..44f735426aa0 100644
--- a/sound/pci/echoaudio/layla24.c
+++ b/sound/pci/echoaudio/layla24.c
@@ -58,6 +58,7 @@
58#include <sound/core.h> 58#include <sound/core.h>
59#include <sound/info.h> 59#include <sound/info.h>
60#include <sound/control.h> 60#include <sound/control.h>
61#include <sound/tlv.h>
61#include <sound/pcm.h> 62#include <sound/pcm.h>
62#include <sound/pcm_params.h> 63#include <sound/pcm_params.h>
63#include <sound/asoundef.h> 64#include <sound/asoundef.h>
diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c
index be40c64263d2..dc172d03ac3f 100644
--- a/sound/pci/echoaudio/mia.c
+++ b/sound/pci/echoaudio/mia.c
@@ -56,6 +56,7 @@
56#include <sound/core.h> 56#include <sound/core.h>
57#include <sound/info.h> 57#include <sound/info.h>
58#include <sound/control.h> 58#include <sound/control.h>
59#include <sound/tlv.h>
59#include <sound/pcm.h> 60#include <sound/pcm.h>
60#include <sound/pcm_params.h> 61#include <sound/pcm_params.h>
61#include <sound/asoundef.h> 62#include <sound/asoundef.h>
diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c
index 5dc512add372..c856ed50dd9a 100644
--- a/sound/pci/echoaudio/mona.c
+++ b/sound/pci/echoaudio/mona.c
@@ -55,6 +55,7 @@
55#include <sound/core.h> 55#include <sound/core.h>
56#include <sound/info.h> 56#include <sound/info.h>
57#include <sound/control.h> 57#include <sound/control.h>
58#include <sound/tlv.h>
58#include <sound/pcm.h> 59#include <sound/pcm.h>
59#include <sound/pcm_params.h> 60#include <sound/pcm_params.h>
60#include <sound/asoundef.h> 61#include <sound/asoundef.h>
diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c
index 972ec40d8166..80aa585eade4 100644
--- a/sound/pci/emu10k1/emu10k1_main.c
+++ b/sound/pci/emu10k1/emu10k1_main.c
@@ -3,8 +3,10 @@
3 * Creative Labs, Inc. 3 * Creative Labs, Inc.
4 * Routines for control of EMU10K1 chips 4 * Routines for control of EMU10K1 chips
5 * 5 *
6 * Copyright (c) by James Courtier-Dutton <James@superbug.demon.co.uk> 6 * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
7 * Added support for Audigy 2 Value. 7 * Added support for Audigy 2 Value.
8 * Added EMU 1010 support.
9 * General bug fixes and enhancements.
8 * 10 *
9 * 11 *
10 * BUGS: 12 * BUGS:
@@ -41,8 +43,10 @@
41 43
42#include <sound/core.h> 44#include <sound/core.h>
43#include <sound/emu10k1.h> 45#include <sound/emu10k1.h>
46#include <linux/firmware.h>
44#include "p16v.h" 47#include "p16v.h"
45#include "tina2.h" 48#include "tina2.h"
49#include "p17v.h"
46 50
47 51
48/************************************************************************* 52/*************************************************************************
@@ -117,11 +121,28 @@ static unsigned int spi_dac_init[] = {
117 0x0622, 121 0x0622,
118 0x1400, 122 0x1400,
119}; 123};
124
125static unsigned int i2c_adc_init[][2] = {
126 { 0x17, 0x00 }, /* Reset */
127 { 0x07, 0x00 }, /* Timeout */
128 { 0x0b, 0x22 }, /* Interface control */
129 { 0x0c, 0x22 }, /* Master mode control */
130 { 0x0d, 0x08 }, /* Powerdown control */
131 { 0x0e, 0xcf }, /* Attenuation Left 0x01 = -103dB, 0xff = 24dB */
132 { 0x0f, 0xcf }, /* Attenuation Right 0.5dB steps */
133 { 0x10, 0x7b }, /* ALC Control 1 */
134 { 0x11, 0x00 }, /* ALC Control 2 */
135 { 0x12, 0x32 }, /* ALC Control 3 */
136 { 0x13, 0x00 }, /* Noise gate control */
137 { 0x14, 0xa6 }, /* Limiter control */
138 { 0x15, ADC_MUX_2 }, /* ADC Mixer control. Mic for Audigy 2 ZS Notebook */
139};
120 140
121static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) 141static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
122{ 142{
123 unsigned int silent_page; 143 unsigned int silent_page;
124 int ch; 144 int ch;
145 u32 tmp;
125 146
126 /* disable audio and lock cache */ 147 /* disable audio and lock cache */
127 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE, 148 outl(HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE,
@@ -160,8 +181,6 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
160 181
161 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */ 182 if (emu->card_capabilities->ca0151_chip) { /* audigy2 */
162 /* Hacks for Alice3 to work independent of haP16V driver */ 183 /* Hacks for Alice3 to work independent of haP16V driver */
163 u32 tmp;
164
165 //Setup SRCMulti_I2S SamplingRate 184 //Setup SRCMulti_I2S SamplingRate
166 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); 185 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
167 tmp &= 0xfffff1ff; 186 tmp &= 0xfffff1ff;
@@ -181,8 +200,6 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
181 } 200 }
182 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */ 201 if (emu->card_capabilities->ca0108_chip) { /* audigy2 Value */
183 /* Hacks for Alice3 to work independent of haP16V driver */ 202 /* Hacks for Alice3 to work independent of haP16V driver */
184 u32 tmp;
185
186 snd_printk(KERN_INFO "Audigy2 value: Special config.\n"); 203 snd_printk(KERN_INFO "Audigy2 value: Special config.\n");
187 //Setup SRCMulti_I2S SamplingRate 204 //Setup SRCMulti_I2S SamplingRate
188 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0); 205 tmp = snd_emu10k1_ptr_read(emu, A_SPDIF_SAMPLERATE, 0);
@@ -211,7 +228,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
211 int size, n; 228 int size, n;
212 229
213 size = ARRAY_SIZE(spi_dac_init); 230 size = ARRAY_SIZE(spi_dac_init);
214 for (n=0; n < size; n++) 231 for (n = 0; n < size; n++)
215 snd_emu10k1_spi_write(emu, spi_dac_init[n]); 232 snd_emu10k1_spi_write(emu, spi_dac_init[n]);
216 233
217 snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10); 234 snd_emu10k1_ptr20_write(emu, 0x60, 0, 0x10);
@@ -228,6 +245,23 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
228 outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */ 245 outl(0x76, emu->port + A_IOCFG); /* Windows uses 0x3f76 */
229 246
230 } 247 }
248 if (emu->card_capabilities->i2c_adc) { /* Audigy 2 ZS Notebook with ADC Wolfson WM8775 */
249 int size, n;
250
251 snd_emu10k1_ptr20_write(emu, P17V_I2S_SRC_SEL, 0, 0x2020205f);
252 tmp = inl(emu->port + A_IOCFG);
253 outl(tmp | 0x4, emu->port + A_IOCFG); /* Set bit 2 for mic input */
254 tmp = inl(emu->port + A_IOCFG);
255 size = ARRAY_SIZE(i2c_adc_init);
256 for (n = 0; n < size; n++)
257 snd_emu10k1_i2c_write(emu, i2c_adc_init[n][0], i2c_adc_init[n][1]);
258 for (n=0; n < 4; n++) {
259 emu->i2c_capture_volume[n][0]= 0xcf;
260 emu->i2c_capture_volume[n][1]= 0xcf;
261 }
262
263 }
264
231 265
232 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr); 266 snd_emu10k1_ptr_write(emu, PTB, 0, emu->ptb_pages.addr);
233 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */ 267 snd_emu10k1_ptr_write(emu, TCB, 0, 0); /* taken from original driver */
@@ -239,6 +273,10 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
239 snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page); 273 snd_emu10k1_ptr_write(emu, MAPB, ch, silent_page);
240 } 274 }
241 275
276 if (emu->card_capabilities->emu1010) {
277 outl(HCFG_AUTOMUTE_ASYNC |
278 HCFG_EMU32_SLAVE |
279 HCFG_AUDIOENABLE, emu->port + HCFG);
242 /* 280 /*
243 * Hokay, setup HCFG 281 * Hokay, setup HCFG
244 * Mute Disable Audio = 0 282 * Mute Disable Audio = 0
@@ -246,7 +284,7 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
246 * Lock Sound Memory = 0 284 * Lock Sound Memory = 0
247 * Auto Mute = 1 285 * Auto Mute = 1
248 */ 286 */
249 if (emu->audigy) { 287 } else if (emu->audigy) {
250 if (emu->revision == 4) /* audigy2 */ 288 if (emu->revision == 4) /* audigy2 */
251 outl(HCFG_AUDIOENABLE | 289 outl(HCFG_AUDIOENABLE |
252 HCFG_AC3ENABLE_CDSPDIF | 290 HCFG_AC3ENABLE_CDSPDIF |
@@ -265,8 +303,10 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
265 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG); 303 outl(HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE, emu->port + HCFG);
266 304
267 if (enable_ir) { /* enable IR for SB Live */ 305 if (enable_ir) { /* enable IR for SB Live */
268 if ( emu->card_capabilities->emu1212m) { 306 if (emu->card_capabilities->emu1010) {
269 ; /* Disable all access to A_IOCFG for the emu1212m */ 307 ; /* Disable all access to A_IOCFG for the emu1010 */
308 } else if (emu->card_capabilities->i2c_adc) {
309 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
270 } else if (emu->audigy) { 310 } else if (emu->audigy) {
271 unsigned int reg = inl(emu->port + A_IOCFG); 311 unsigned int reg = inl(emu->port + A_IOCFG);
272 outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG); 312 outl(reg | A_IOCFG_GPOUT2, emu->port + A_IOCFG);
@@ -284,8 +324,10 @@ static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume)
284 } 324 }
285 } 325 }
286 326
287 if ( emu->card_capabilities->emu1212m) { 327 if (emu->card_capabilities->emu1010) {
288 ; /* Disable all access to A_IOCFG for the emu1212m */ 328 ; /* Disable all access to A_IOCFG for the emu1010 */
329 } else if (emu->card_capabilities->i2c_adc) {
330 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
289 } else if (emu->audigy) { /* enable analog output */ 331 } else if (emu->audigy) { /* enable analog output */
290 unsigned int reg = inl(emu->port + A_IOCFG); 332 unsigned int reg = inl(emu->port + A_IOCFG);
291 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG); 333 outl(reg | A_IOCFG_GPOUT0, emu->port + A_IOCFG);
@@ -302,8 +344,10 @@ static void snd_emu10k1_audio_enable(struct snd_emu10k1 *emu)
302 outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG); 344 outl(inl(emu->port + HCFG) | HCFG_AUDIOENABLE, emu->port + HCFG);
303 345
304 /* Enable analog/digital outs on audigy */ 346 /* Enable analog/digital outs on audigy */
305 if ( emu->card_capabilities->emu1212m) { 347 if (emu->card_capabilities->emu1010) {
306 ; /* Disable all access to A_IOCFG for the emu1212m */ 348 ; /* Disable all access to A_IOCFG for the emu1010 */
349 } else if (emu->card_capabilities->i2c_adc) {
350 ; /* Disable A_IOCFG for Audigy 2 ZS Notebook */
307 } else if (emu->audigy) { 351 } else if (emu->audigy) {
308 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG); 352 outl(inl(emu->port + A_IOCFG) & ~0x44, emu->port + A_IOCFG);
309 353
@@ -596,133 +640,423 @@ static int snd_emu10k1_cardbus_init(struct snd_emu10k1 * emu)
596 return 0; 640 return 0;
597} 641}
598 642
599static int snd_emu1212m_fpga_write(struct snd_emu10k1 * emu, int reg, int value) 643static int snd_emu1010_load_firmware(struct snd_emu10k1 * emu, const char * filename)
600{ 644{
601 if (reg<0 || reg>0x3f) 645 int err;
602 return 1; 646 int n, i;
603 reg+=0x40; /* 0x40 upwards are registers. */ 647 int reg;
604 if (value<0 || value>0x3f) /* 0 to 0x3f are values */ 648 int value;
605 return 1; 649 const struct firmware *fw_entry;
606 outl(reg, emu->port + A_IOCFG); 650
607 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ 651 if ((err = request_firmware(&fw_entry, filename, &emu->pci->dev)) != 0) {
608 outl(value, emu->port + A_IOCFG); 652 snd_printk(KERN_ERR "firmware: %s not found. Err=%d\n",filename, err);
609 outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */ 653 return err;
610 654 }
611 return 0; 655 snd_printk(KERN_INFO "firmware size=0x%zx\n", fw_entry->size);
612} 656 if (fw_entry->size != 0x133a4) {
613 657 snd_printk(KERN_ERR "firmware: %s wrong size.\n",filename);
614static int snd_emu1212m_fpga_read(struct snd_emu10k1 * emu, int reg, int *value) 658 return -EINVAL;
615{ 659 }
616 if (reg<0 || reg>0x3f)
617 return 1;
618 reg+=0x40; /* 0x40 upwards are registers. */
619 outl(reg, emu->port + A_IOCFG);
620 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
621 *value = inl(emu->port + A_IOCFG);
622
623 return 0;
624}
625 660
626static int snd_emu1212m_fpga_netlist_write(struct snd_emu10k1 * emu, int reg, int value) 661 /* The FPGA is a Xilinx Spartan IIE XC2S50E */
627{ 662 /* GPIO7 -> FPGA PGMN
628 snd_emu1212m_fpga_write(emu, 0x00, ((reg >> 8) & 0x3f) ); 663 * GPIO6 -> FPGA CCLK
629 snd_emu1212m_fpga_write(emu, 0x01, (reg & 0x3f) ); 664 * GPIO5 -> FPGA DIN
630 snd_emu1212m_fpga_write(emu, 0x02, ((value >> 8) & 0x3f) ); 665 * FPGA CONFIG OFF -> FPGA PGMN
631 snd_emu1212m_fpga_write(emu, 0x03, (value & 0x3f) ); 666 */
667 outl(0x00, emu->port + A_IOCFG); /* Set PGMN low for 1uS. */
668 udelay(1);
669 outl(0x80, emu->port + A_IOCFG); /* Leave bit 7 set during netlist setup. */
670 udelay(100); /* Allow FPGA memory to clean */
671 for(n = 0; n < fw_entry->size; n++) {
672 value=fw_entry->data[n];
673 for(i = 0; i < 8; i++) {
674 reg = 0x80;
675 if (value & 0x1)
676 reg = reg | 0x20;
677 value = value >> 1;
678 outl(reg, emu->port + A_IOCFG);
679 outl(reg | 0x40, emu->port + A_IOCFG);
680 }
681 }
682 /* After programming, set GPIO bit 4 high again. */
683 outl(0x10, emu->port + A_IOCFG);
684
632 685
686 release_firmware(fw_entry);
633 return 0; 687 return 0;
634} 688}
635 689
636static int snd_emu10k1_emu1212m_init(struct snd_emu10k1 * emu) 690static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu)
637{ 691{
638 unsigned int i; 692 unsigned int i;
639 int tmp; 693 int tmp,tmp2;
640 694 int reg;
641 snd_printk(KERN_ERR "emu1212m: Special config.\n"); 695 int err;
696 const char *hana_filename = "emu/hana.fw";
697 const char *dock_filename = "emu/audio_dock.fw";
698
699 snd_printk(KERN_INFO "emu1010: Special config.\n");
700 /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
701 * Lock Sound Memory Cache, Lock Tank Memory Cache,
702 * Mute all codecs.
703 */
642 outl(0x0005a00c, emu->port + HCFG); 704 outl(0x0005a00c, emu->port + HCFG);
643 outl(0x0005a004, emu->port + HCFG); 705 /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
706 * Lock Tank Memory Cache,
707 * Mute all codecs.
708 */
709 outl(0x0005a004, emu->port + HCFG);
710 /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
711 * Mute all codecs.
712 */
644 outl(0x0005a000, emu->port + HCFG); 713 outl(0x0005a000, emu->port + HCFG);
714 /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave,
715 * Mute all codecs.
716 */
645 outl(0x0005a000, emu->port + HCFG); 717 outl(0x0005a000, emu->port + HCFG);
646 718
647 snd_emu1212m_fpga_read(emu, 0x22, &tmp ); 719 /* Disable 48Volt power to Audio Dock */
648 snd_emu1212m_fpga_read(emu, 0x23, &tmp ); 720 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 );
649 snd_emu1212m_fpga_read(emu, 0x24, &tmp ); 721
650 snd_emu1212m_fpga_write(emu, 0x04, 0x01 ); 722 /* ID, should read & 0x7f = 0x55. (Bit 7 is the IRQ bit) */
651 snd_emu1212m_fpga_read(emu, 0x0b, &tmp ); 723 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
652 snd_emu1212m_fpga_write(emu, 0x0b, 0x01 ); 724 snd_printdd("reg1=0x%x\n",reg);
653 snd_emu1212m_fpga_read(emu, 0x10, &tmp ); 725 if (reg == 0x55) {
654 snd_emu1212m_fpga_write(emu, 0x10, 0x00 ); 726 /* FPGA netlist already present so clear it */
655 snd_emu1212m_fpga_read(emu, 0x11, &tmp ); 727 /* Return to programming mode */
656 snd_emu1212m_fpga_write(emu, 0x11, 0x30 ); 728
657 snd_emu1212m_fpga_read(emu, 0x13, &tmp ); 729 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0x02 );
658 snd_emu1212m_fpga_write(emu, 0x13, 0x0f );
659 snd_emu1212m_fpga_read(emu, 0x11, &tmp );
660 snd_emu1212m_fpga_write(emu, 0x11, 0x30 );
661 snd_emu1212m_fpga_read(emu, 0x0a, &tmp );
662 snd_emu1212m_fpga_write(emu, 0x0a, 0x10 );
663 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 );
664 snd_emu1212m_fpga_write(emu, 0x12, 0x0c );
665 snd_emu1212m_fpga_write(emu, 0x09, 0x0f );
666 snd_emu1212m_fpga_write(emu, 0x06, 0x00 );
667 snd_emu1212m_fpga_write(emu, 0x05, 0x00 );
668 snd_emu1212m_fpga_write(emu, 0x0e, 0x12 );
669 snd_emu1212m_fpga_netlist_write(emu, 0x0000, 0x0200);
670 snd_emu1212m_fpga_netlist_write(emu, 0x0001, 0x0201);
671 snd_emu1212m_fpga_netlist_write(emu, 0x0002, 0x0500);
672 snd_emu1212m_fpga_netlist_write(emu, 0x0003, 0x0501);
673 snd_emu1212m_fpga_netlist_write(emu, 0x0004, 0x0400);
674 snd_emu1212m_fpga_netlist_write(emu, 0x0005, 0x0401);
675 snd_emu1212m_fpga_netlist_write(emu, 0x0006, 0x0402);
676 snd_emu1212m_fpga_netlist_write(emu, 0x0007, 0x0403);
677 snd_emu1212m_fpga_netlist_write(emu, 0x0008, 0x0404);
678 snd_emu1212m_fpga_netlist_write(emu, 0x0009, 0x0405);
679 snd_emu1212m_fpga_netlist_write(emu, 0x000a, 0x0406);
680 snd_emu1212m_fpga_netlist_write(emu, 0x000b, 0x0407);
681 snd_emu1212m_fpga_netlist_write(emu, 0x000c, 0x0100);
682 snd_emu1212m_fpga_netlist_write(emu, 0x000d, 0x0104);
683 snd_emu1212m_fpga_netlist_write(emu, 0x000e, 0x0200);
684 snd_emu1212m_fpga_netlist_write(emu, 0x000f, 0x0201);
685 for (i=0;i < 0x20;i++) {
686 snd_emu1212m_fpga_netlist_write(emu, 0x0100+i, 0x0000);
687 } 730 }
688 for (i=0;i < 4;i++) { 731 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
689 snd_emu1212m_fpga_netlist_write(emu, 0x0200+i, 0x0000); 732 snd_printdd("reg2=0x%x\n",reg);
733 if (reg == 0x55) {
734 /* FPGA failed to return to programming mode */
735 return -ENODEV;
690 } 736 }
691 for (i=0;i < 7;i++) { 737 snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg);
692 snd_emu1212m_fpga_netlist_write(emu, 0x0300+i, 0x0000); 738 if ((err = snd_emu1010_load_firmware(emu, hana_filename)) != 0) {
739 snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", hana_filename);
740 return err;
693 } 741 }
694 for (i=0;i < 7;i++) { 742
695 snd_emu1212m_fpga_netlist_write(emu, 0x0400+i, 0x0000); 743 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
744 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
745 if (reg != 0x55) {
746 /* FPGA failed to be programmed */
747 snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file failed, reg=0x%x\n", reg);
748 return -ENODEV;
696 } 749 }
697 snd_emu1212m_fpga_netlist_write(emu, 0x0500, 0x0108);
698 snd_emu1212m_fpga_netlist_write(emu, 0x0501, 0x010c);
699 snd_emu1212m_fpga_netlist_write(emu, 0x0600, 0x0110);
700 snd_emu1212m_fpga_netlist_write(emu, 0x0601, 0x0114);
701 snd_emu1212m_fpga_netlist_write(emu, 0x0700, 0x0118);
702 snd_emu1212m_fpga_netlist_write(emu, 0x0701, 0x011c);
703 snd_emu1212m_fpga_write(emu, 0x07, 0x01 );
704 750
705 snd_emu1212m_fpga_read(emu, 0x21, &tmp ); 751 snd_printk(KERN_INFO "emu1010: Hana Firmware loaded\n");
752 snd_emu1010_fpga_read(emu, EMU_HANA_MAJOR_REV, &tmp );
753 snd_emu1010_fpga_read(emu, EMU_HANA_MINOR_REV, &tmp2 );
754 snd_printk("Hana ver:%d.%d\n",tmp ,tmp2);
755 /* Enable 48Volt power to Audio Dock */
756 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, EMU_HANA_DOCK_PWR_ON );
757
758 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg );
759 snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg);
760 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg );
761 snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg);
762 snd_emu1010_fpga_read(emu, EMU_HANA_OPTICAL_TYPE, &tmp );
763 /* ADAT input. */
764 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x01 );
765 snd_emu1010_fpga_read(emu, EMU_HANA_ADC_PADS, &tmp );
766 /* Set no attenuation on Audio Dock pads. */
767 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, 0x00 );
768 emu->emu1010.adc_pads = 0x00;
769 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp );
770 /* Unmute Audio dock DACs, Headphone source DAC-4. */
771 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 );
772 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 );
773 snd_emu1010_fpga_read(emu, EMU_HANA_DAC_PADS, &tmp );
774 /* DAC PADs. */
775 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, 0x0f );
776 emu->emu1010.dac_pads = 0x0f;
777 snd_emu1010_fpga_read(emu, EMU_HANA_DOCK_MISC, &tmp );
778 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_MISC, 0x30 );
779 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp );
780 /* SPDIF Format. Set Consumer mode, 24bit, copy enable */
781 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 );
782 /* MIDI routing */
783 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 );
784 /* Unknown. */
785 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c );
786 /* snd_emu1010_fpga_write(emu, 0x09, 0x0f ); // IRQ Enable: All on */
787 /* IRQ Enable: All off */
788 snd_emu1010_fpga_write(emu, EMU_HANA_IRQ_ENABLE, 0x00 );
789
790 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg );
791 snd_printk(KERN_INFO "emu1010: Card options3=0x%x\n",reg);
792 /* Default WCLK set to 48kHz. */
793 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x00 );
794 /* Word Clock source, Internal 48kHz x1 */
795 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K );
796 //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X );
797 /* Audio Dock LEDs. */
798 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12 );
706 799
707 outl(0x0000a000, emu->port + HCFG); 800#if 0
801 /* For 96kHz */
802 snd_emu1010_fpga_link_dst_src_write(emu,
803 EMU_DST_ALICE2_EMU32_0, EMU_SRC_HAMOA_ADC_LEFT1);
804 snd_emu1010_fpga_link_dst_src_write(emu,
805 EMU_DST_ALICE2_EMU32_1, EMU_SRC_HAMOA_ADC_RIGHT1);
806 snd_emu1010_fpga_link_dst_src_write(emu,
807 EMU_DST_ALICE2_EMU32_4, EMU_SRC_HAMOA_ADC_LEFT2);
808 snd_emu1010_fpga_link_dst_src_write(emu,
809 EMU_DST_ALICE2_EMU32_5, EMU_SRC_HAMOA_ADC_RIGHT2);
810#endif
811#if 0
812 /* For 192kHz */
813 snd_emu1010_fpga_link_dst_src_write(emu,
814 EMU_DST_ALICE2_EMU32_0, EMU_SRC_HAMOA_ADC_LEFT1);
815 snd_emu1010_fpga_link_dst_src_write(emu,
816 EMU_DST_ALICE2_EMU32_1, EMU_SRC_HAMOA_ADC_RIGHT1);
817 snd_emu1010_fpga_link_dst_src_write(emu,
818 EMU_DST_ALICE2_EMU32_2, EMU_SRC_HAMOA_ADC_LEFT2);
819 snd_emu1010_fpga_link_dst_src_write(emu,
820 EMU_DST_ALICE2_EMU32_3, EMU_SRC_HAMOA_ADC_RIGHT2);
821 snd_emu1010_fpga_link_dst_src_write(emu,
822 EMU_DST_ALICE2_EMU32_4, EMU_SRC_HAMOA_ADC_LEFT3);
823 snd_emu1010_fpga_link_dst_src_write(emu,
824 EMU_DST_ALICE2_EMU32_5, EMU_SRC_HAMOA_ADC_RIGHT3);
825 snd_emu1010_fpga_link_dst_src_write(emu,
826 EMU_DST_ALICE2_EMU32_6, EMU_SRC_HAMOA_ADC_LEFT4);
827 snd_emu1010_fpga_link_dst_src_write(emu,
828 EMU_DST_ALICE2_EMU32_7, EMU_SRC_HAMOA_ADC_RIGHT4);
829#endif
830#if 1
831 /* For 48kHz */
832 snd_emu1010_fpga_link_dst_src_write(emu,
833 EMU_DST_ALICE2_EMU32_0, EMU_SRC_DOCK_MIC_A1);
834 snd_emu1010_fpga_link_dst_src_write(emu,
835 EMU_DST_ALICE2_EMU32_1, EMU_SRC_DOCK_MIC_B1);
836 snd_emu1010_fpga_link_dst_src_write(emu,
837 EMU_DST_ALICE2_EMU32_2, EMU_SRC_HAMOA_ADC_LEFT2);
838 snd_emu1010_fpga_link_dst_src_write(emu,
839 EMU_DST_ALICE2_EMU32_3, EMU_SRC_HAMOA_ADC_LEFT2);
840 snd_emu1010_fpga_link_dst_src_write(emu,
841 EMU_DST_ALICE2_EMU32_4, EMU_SRC_DOCK_ADC1_LEFT1);
842 snd_emu1010_fpga_link_dst_src_write(emu,
843 EMU_DST_ALICE2_EMU32_5, EMU_SRC_DOCK_ADC1_RIGHT1);
844 snd_emu1010_fpga_link_dst_src_write(emu,
845 EMU_DST_ALICE2_EMU32_6, EMU_SRC_DOCK_ADC2_LEFT1);
846 snd_emu1010_fpga_link_dst_src_write(emu,
847 EMU_DST_ALICE2_EMU32_7, EMU_SRC_DOCK_ADC2_RIGHT1);
848#endif
849#if 0
850 /* Original */
851 snd_emu1010_fpga_link_dst_src_write(emu,
852 EMU_DST_ALICE2_EMU32_4, EMU_SRC_HANA_ADAT);
853 snd_emu1010_fpga_link_dst_src_write(emu,
854 EMU_DST_ALICE2_EMU32_5, EMU_SRC_HANA_ADAT + 1);
855 snd_emu1010_fpga_link_dst_src_write(emu,
856 EMU_DST_ALICE2_EMU32_6, EMU_SRC_HANA_ADAT + 2);
857 snd_emu1010_fpga_link_dst_src_write(emu,
858 EMU_DST_ALICE2_EMU32_7, EMU_SRC_HANA_ADAT + 3);
859 snd_emu1010_fpga_link_dst_src_write(emu,
860 EMU_DST_ALICE2_EMU32_8, EMU_SRC_HANA_ADAT + 4);
861 snd_emu1010_fpga_link_dst_src_write(emu,
862 EMU_DST_ALICE2_EMU32_9, EMU_SRC_HANA_ADAT + 5);
863 snd_emu1010_fpga_link_dst_src_write(emu,
864 EMU_DST_ALICE2_EMU32_A, EMU_SRC_HANA_ADAT + 6);
865 snd_emu1010_fpga_link_dst_src_write(emu,
866 EMU_DST_ALICE2_EMU32_B, EMU_SRC_HANA_ADAT + 7);
867 snd_emu1010_fpga_link_dst_src_write(emu,
868 EMU_DST_ALICE2_EMU32_C, EMU_SRC_DOCK_MIC_A1);
869 snd_emu1010_fpga_link_dst_src_write(emu,
870 EMU_DST_ALICE2_EMU32_D, EMU_SRC_DOCK_MIC_B1);
871 snd_emu1010_fpga_link_dst_src_write(emu,
872 EMU_DST_ALICE2_EMU32_E, EMU_SRC_HAMOA_ADC_LEFT2);
873 snd_emu1010_fpga_link_dst_src_write(emu,
874 EMU_DST_ALICE2_EMU32_F, EMU_SRC_HAMOA_ADC_LEFT2);
875#endif
876 for (i = 0;i < 0x20; i++ ) {
877 /* AudioDock Elink <- Silence */
878 snd_emu1010_fpga_link_dst_src_write(emu, 0x0100+i, EMU_SRC_SILENCE);
879 }
880 for (i = 0;i < 4; i++) {
881 /* Hana SPDIF Out <- Silence */
882 snd_emu1010_fpga_link_dst_src_write(emu, 0x0200+i, EMU_SRC_SILENCE);
883 }
884 for (i = 0;i < 7; i++) {
885 /* Hamoa DAC <- Silence */
886 snd_emu1010_fpga_link_dst_src_write(emu, 0x0300+i, EMU_SRC_SILENCE);
887 }
888 for (i = 0;i < 7; i++) {
889 /* Hana ADAT Out <- Silence */
890 snd_emu1010_fpga_link_dst_src_write(emu, EMU_DST_HANA_ADAT + i, EMU_SRC_SILENCE);
891 }
892 snd_emu1010_fpga_link_dst_src_write(emu,
893 EMU_DST_ALICE_I2S0_LEFT, EMU_SRC_DOCK_ADC1_LEFT1);
894 snd_emu1010_fpga_link_dst_src_write(emu,
895 EMU_DST_ALICE_I2S0_RIGHT, EMU_SRC_DOCK_ADC1_RIGHT1);
896 snd_emu1010_fpga_link_dst_src_write(emu,
897 EMU_DST_ALICE_I2S1_LEFT, EMU_SRC_DOCK_ADC2_LEFT1);
898 snd_emu1010_fpga_link_dst_src_write(emu,
899 EMU_DST_ALICE_I2S1_RIGHT, EMU_SRC_DOCK_ADC2_RIGHT1);
900 snd_emu1010_fpga_link_dst_src_write(emu,
901 EMU_DST_ALICE_I2S2_LEFT, EMU_SRC_DOCK_ADC3_LEFT1);
902 snd_emu1010_fpga_link_dst_src_write(emu,
903 EMU_DST_ALICE_I2S2_RIGHT, EMU_SRC_DOCK_ADC3_RIGHT1);
904 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x01 ); // Unmute all
905
906 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp );
907
908 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
909 * Lock Sound Memory Cache, Lock Tank Memory Cache,
910 * Mute all codecs.
911 */
912 outl(0x0000a000, emu->port + HCFG);
913 /* AC97 1.03, Any 32Meg of 2Gig address, Auto-Mute, EMU32 Slave,
914 * Lock Sound Memory Cache, Lock Tank Memory Cache,
915 * Un-Mute all codecs.
916 */
708 outl(0x0000a001, emu->port + HCFG); 917 outl(0x0000a001, emu->port + HCFG);
918
709 /* Initial boot complete. Now patches */ 919 /* Initial boot complete. Now patches */
710 920
711 snd_emu1212m_fpga_read(emu, 0x21, &tmp ); 921 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &tmp );
712 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 ); 922 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); /* MIDI Route */
713 snd_emu1212m_fpga_write(emu, 0x12, 0x0c ); 923 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); /* Unknown */
714 snd_emu1212m_fpga_write(emu, 0x0c, 0x19 ); 924 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_IN, 0x19 ); /* MIDI Route */
715 snd_emu1212m_fpga_write(emu, 0x12, 0x0c ); 925 snd_emu1010_fpga_write(emu, EMU_HANA_MIDI_OUT, 0x0c ); /* Unknown */
716 snd_emu1212m_fpga_read(emu, 0x0a, &tmp ); 926 snd_emu1010_fpga_read(emu, EMU_HANA_SPDIF_MODE, &tmp );
717 snd_emu1212m_fpga_write(emu, 0x0a, 0x10 ); 927 snd_emu1010_fpga_write(emu, EMU_HANA_SPDIF_MODE, 0x10 ); /* SPDIF Format spdif (or 0x11 for aes/ebu) */
718 928
719 snd_emu1212m_fpga_read(emu, 0x20, &tmp ); 929 /* Delay to allow Audio Dock to settle */
720 snd_emu1212m_fpga_read(emu, 0x21, &tmp ); 930 msleep(100);
721 931 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &tmp ); /* IRQ Status */
722 snd_emu1212m_fpga_netlist_write(emu, 0x0300, 0x0312); 932 snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, &reg ); /* OPTIONS: Which cards are attached to the EMU */
723 snd_emu1212m_fpga_netlist_write(emu, 0x0301, 0x0313); 933 /* FIXME: The loading of this should be able to happen any time,
724 snd_emu1212m_fpga_netlist_write(emu, 0x0200, 0x0302); 934 * as the user can plug/unplug it at any time
725 snd_emu1212m_fpga_netlist_write(emu, 0x0201, 0x0303); 935 */
936 if (reg & (EMU_HANA_OPTION_DOCK_ONLINE | EMU_HANA_OPTION_DOCK_OFFLINE) ) {
937 /* Audio Dock attached */
938 /* Return to Audio Dock programming mode */
939 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n");
940 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK );
941 if ((err = snd_emu1010_load_firmware(emu, dock_filename)) != 0) {
942 return err;
943 }
944 snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 );
945 snd_emu1010_fpga_read(emu, EMU_HANA_IRQ_STATUS, &reg );
946 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_IRQ_STATUS=0x%x\n",reg);
947 /* ID, should read & 0x7f = 0x55 when FPGA programmed. */
948 snd_emu1010_fpga_read(emu, EMU_HANA_ID, &reg );
949 snd_printk(KERN_INFO "emu1010: EMU_HANA+DOCK_ID=0x%x\n",reg);
950 if (reg != 0x55) {
951 /* FPGA failed to be programmed */
952 snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware file failed, reg=0x%x\n", reg);
953 return 0;
954 return -ENODEV;
955 }
956 snd_printk(KERN_INFO "emu1010: Audio Dock Firmware loaded\n");
957 snd_emu1010_fpga_read(emu, EMU_DOCK_MAJOR_REV, &tmp );
958 snd_emu1010_fpga_read(emu, EMU_DOCK_MINOR_REV, &tmp2 );
959 snd_printk("Audio Dock ver:%d.%d\n",tmp ,tmp2);
960 }
961#if 0
962 snd_emu1010_fpga_link_dst_src_write(emu,
963 EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32B + 2); /* ALICE2 bus 0xa2 */
964 snd_emu1010_fpga_link_dst_src_write(emu,
965 EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32B + 3); /* ALICE2 bus 0xa3 */
966 snd_emu1010_fpga_link_dst_src_write(emu,
967 EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 2); /* ALICE2 bus 0xb2 */
968 snd_emu1010_fpga_link_dst_src_write(emu,
969 EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 3); /* ALICE2 bus 0xb3 */
970#endif
971 /* Default outputs */
972 snd_emu1010_fpga_link_dst_src_write(emu,
973 EMU_DST_DOCK_DAC1_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
974 emu->emu1010.output_source[0] = 21;
975 snd_emu1010_fpga_link_dst_src_write(emu,
976 EMU_DST_DOCK_DAC1_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
977 emu->emu1010.output_source[1] = 22;
978 snd_emu1010_fpga_link_dst_src_write(emu,
979 EMU_DST_DOCK_DAC2_LEFT1, EMU_SRC_ALICE_EMU32A + 2);
980 emu->emu1010.output_source[2] = 23;
981 snd_emu1010_fpga_link_dst_src_write(emu,
982 EMU_DST_DOCK_DAC2_RIGHT1, EMU_SRC_ALICE_EMU32A + 3);
983 emu->emu1010.output_source[3] = 24;
984 snd_emu1010_fpga_link_dst_src_write(emu,
985 EMU_DST_DOCK_DAC3_LEFT1, EMU_SRC_ALICE_EMU32A + 4);
986 emu->emu1010.output_source[4] = 25;
987 snd_emu1010_fpga_link_dst_src_write(emu,
988 EMU_DST_DOCK_DAC3_RIGHT1, EMU_SRC_ALICE_EMU32A + 5);
989 emu->emu1010.output_source[5] = 26;
990 snd_emu1010_fpga_link_dst_src_write(emu,
991 EMU_DST_DOCK_DAC4_LEFT1, EMU_SRC_ALICE_EMU32A + 6);
992 emu->emu1010.output_source[6] = 27;
993 snd_emu1010_fpga_link_dst_src_write(emu,
994 EMU_DST_DOCK_DAC4_RIGHT1, EMU_SRC_ALICE_EMU32A + 7);
995 emu->emu1010.output_source[7] = 28;
996 snd_emu1010_fpga_link_dst_src_write(emu,
997 EMU_DST_DOCK_PHONES_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
998 emu->emu1010.output_source[8] = 21;
999 snd_emu1010_fpga_link_dst_src_write(emu,
1000 EMU_DST_DOCK_PHONES_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
1001 emu->emu1010.output_source[9] = 22;
1002 snd_emu1010_fpga_link_dst_src_write(emu,
1003 EMU_DST_DOCK_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
1004 emu->emu1010.output_source[10] = 21;
1005 snd_emu1010_fpga_link_dst_src_write(emu,
1006 EMU_DST_DOCK_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
1007 emu->emu1010.output_source[11] = 22;
1008 snd_emu1010_fpga_link_dst_src_write(emu,
1009 EMU_DST_HANA_SPDIF_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
1010 emu->emu1010.output_source[12] = 21;
1011 snd_emu1010_fpga_link_dst_src_write(emu,
1012 EMU_DST_HANA_SPDIF_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
1013 emu->emu1010.output_source[13] = 22;
1014 snd_emu1010_fpga_link_dst_src_write(emu,
1015 EMU_DST_HAMOA_DAC_LEFT1, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
1016 emu->emu1010.output_source[14] = 21;
1017 snd_emu1010_fpga_link_dst_src_write(emu,
1018 EMU_DST_HAMOA_DAC_RIGHT1, EMU_SRC_ALICE_EMU32A + 1);
1019 emu->emu1010.output_source[15] = 22;
1020 snd_emu1010_fpga_link_dst_src_write(emu,
1021 EMU_DST_HANA_ADAT, EMU_SRC_ALICE_EMU32A + 0); /* ALICE2 bus 0xa0 */
1022 emu->emu1010.output_source[16] = 21;
1023 snd_emu1010_fpga_link_dst_src_write(emu,
1024 EMU_DST_HANA_ADAT + 1, EMU_SRC_ALICE_EMU32A + 1);
1025 emu->emu1010.output_source[17] = 22;
1026 snd_emu1010_fpga_link_dst_src_write(emu,
1027 EMU_DST_HANA_ADAT + 2, EMU_SRC_ALICE_EMU32A + 2);
1028 emu->emu1010.output_source[18] = 23;
1029 snd_emu1010_fpga_link_dst_src_write(emu,
1030 EMU_DST_HANA_ADAT + 3, EMU_SRC_ALICE_EMU32A + 3);
1031 emu->emu1010.output_source[19] = 24;
1032 snd_emu1010_fpga_link_dst_src_write(emu,
1033 EMU_DST_HANA_ADAT + 4, EMU_SRC_ALICE_EMU32A + 4);
1034 emu->emu1010.output_source[20] = 25;
1035 snd_emu1010_fpga_link_dst_src_write(emu,
1036 EMU_DST_HANA_ADAT + 5, EMU_SRC_ALICE_EMU32A + 5);
1037 emu->emu1010.output_source[21] = 26;
1038 snd_emu1010_fpga_link_dst_src_write(emu,
1039 EMU_DST_HANA_ADAT + 6, EMU_SRC_ALICE_EMU32A + 6);
1040 emu->emu1010.output_source[22] = 27;
1041 snd_emu1010_fpga_link_dst_src_write(emu,
1042 EMU_DST_HANA_ADAT + 7, EMU_SRC_ALICE_EMU32A + 7);
1043 emu->emu1010.output_source[23] = 28;
1044
1045 /* TEMP: Select SPDIF in/out */
1046 snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, 0x0); /* Output spdif */
1047
1048 /* TEMP: Select 48kHz SPDIF out */
1049 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x0); /* Mute all */
1050 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, 0x0); /* Default fallback clock 48kHz */
1051 /* Word Clock source, Internal 48kHz x1 */
1052 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K );
1053 //snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK, EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_4X );
1054 emu->emu1010.internal_clock = 1; /* 48000 */
1055 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2, 0x12);/* Set LEDs on Audio Dock */
1056 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, 0x1); /* Unmute all */
1057 //snd_emu1010_fpga_write(emu, 0x7, 0x0); /* Mute all */
1058 //snd_emu1010_fpga_write(emu, 0x7, 0x1); /* Unmute all */
1059 //snd_emu1010_fpga_write(emu, 0xe, 0x12); /* Set LEDs on Audio Dock */
726 1060
727 return 0; 1061 return 0;
728} 1062}
@@ -747,6 +1081,10 @@ static int snd_emu10k1_free(struct snd_emu10k1 *emu)
747 } 1081 }
748 snd_emu10k1_free_efx(emu); 1082 snd_emu10k1_free_efx(emu);
749 } 1083 }
1084 if (emu->card_capabilities->emu1010) {
1085 /* Disable 48Volt power to Audio Dock */
1086 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_PWR, 0 );
1087 }
750 if (emu->memhdr) 1088 if (emu->memhdr)
751 snd_util_memhdr_free(emu->memhdr); 1089 snd_util_memhdr_free(emu->memhdr);
752 if (emu->silent_page.area) 1090 if (emu->silent_page.area)
@@ -838,10 +1176,11 @@ static struct snd_emu_chip_details emu_chip_details[] = {
838 .adc_1361t = 1, /* 24 bit capture instead of 16bit */ 1176 .adc_1361t = 1, /* 24 bit capture instead of 16bit */
839 .ac97_chip = 1} , 1177 .ac97_chip = 1} ,
840 /* Audigy 2 ZS Notebook Cardbus card.*/ 1178 /* Audigy 2 ZS Notebook Cardbus card.*/
841 /* Tested by James@superbug.co.uk 22th December 2005 */ 1179 /* Tested by James@superbug.co.uk 6th November 2006 */
842 /* Audio output 7.1/Headphones working. 1180 /* Audio output 7.1/Headphones working.
843 * Digital output working. (AC3 not checked, only PCM) 1181 * Digital output working. (AC3 not checked, only PCM)
844 * Audio inputs not tested. 1182 * Audio Mic/Line inputs working.
1183 * Digital input not tested.
845 */ 1184 */
846 /* DSP: Tina2 1185 /* DSP: Tina2
847 * DAC: Wolfson WM8768/WM8568 1186 * DAC: Wolfson WM8768/WM8568
@@ -849,6 +1188,25 @@ static struct snd_emu_chip_details emu_chip_details[] = {
849 * AC97: None 1188 * AC97: None
850 * CA0151: None 1189 * CA0151: None
851 */ 1190 */
1191 /* Tested by James@superbug.co.uk 4th April 2006 */
1192 /* A_IOCFG bits
1193 * Output
1194 * 0: Not Used
1195 * 1: 0 = Mute all the 7.1 channel out. 1 = unmute.
1196 * 2: Analog input 0 = line in, 1 = mic in
1197 * 3: Not Used
1198 * 4: Digital output 0 = off, 1 = on.
1199 * 5: Not Used
1200 * 6: Not Used
1201 * 7: Not Used
1202 * Input
1203 * All bits 1 (0x3fxx) means nothing plugged in.
1204 * 8-9: 0 = Line in/Mic, 2 = Optical in, 3 = Nothing.
1205 * A-B: 0 = Headphones, 2 = Optical out, 3 = Nothing.
1206 * C-D: 2 = Front/Rear/etc, 3 = nothing.
1207 * E-F: Always 0
1208 *
1209 */
852 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102, 1210 {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x20011102,
853 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]", 1211 .driver = "Audigy2", .name = "Audigy 2 ZS Notebook [SB0530]",
854 .id = "Audigy2", 1212 .id = "Audigy2",
@@ -856,6 +1214,7 @@ static struct snd_emu_chip_details emu_chip_details[] = {
856 .ca0108_chip = 1, 1214 .ca0108_chip = 1,
857 .ca_cardbus_chip = 1, 1215 .ca_cardbus_chip = 1,
858 .spi_dac = 1, 1216 .spi_dac = 1,
1217 .i2c_adc = 1,
859 .spk71 = 1} , 1218 .spk71 = 1} ,
860 {.vendor = 0x1102, .device = 0x0008, 1219 {.vendor = 0x1102, .device = 0x0008,
861 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", 1220 .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]",
@@ -865,11 +1224,12 @@ static struct snd_emu_chip_details emu_chip_details[] = {
865 .ac97_chip = 1} , 1224 .ac97_chip = 1} ,
866 /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */ 1225 /* Tested by James@superbug.co.uk 8th July 2005. No sound available yet. */
867 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102, 1226 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x40011102,
868 .driver = "Audigy2", .name = "E-mu 1212m [4001]", 1227 .driver = "Audigy2", .name = "E-mu 1010 [4001]",
869 .id = "EMU1212m", 1228 .id = "EMU1010",
870 .emu10k2_chip = 1, 1229 .emu10k2_chip = 1,
871 .ca0102_chip = 1, 1230 .ca0102_chip = 1,
872 .emu1212m = 1} , 1231 .spk71 = 1,
1232 .emu1010 = 1} ,
873 /* Tested by James@superbug.co.uk 3rd July 2005 */ 1233 /* Tested by James@superbug.co.uk 3rd July 2005 */
874 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102, 1234 {.vendor = 0x1102, .device = 0x0004, .subsystem = 0x20071102,
875 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]", 1235 .driver = "Audigy2", .name = "Audigy 4 PRO [SB0380]",
@@ -1297,8 +1657,8 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
1297 } else if (emu->card_capabilities->ca_cardbus_chip) { 1657 } else if (emu->card_capabilities->ca_cardbus_chip) {
1298 if ((err = snd_emu10k1_cardbus_init(emu)) < 0) 1658 if ((err = snd_emu10k1_cardbus_init(emu)) < 0)
1299 goto error; 1659 goto error;
1300 } else if (emu->card_capabilities->emu1212m) { 1660 } else if (emu->card_capabilities->emu1010) {
1301 if ((err = snd_emu10k1_emu1212m_init(emu)) < 0) { 1661 if ((err = snd_emu10k1_emu1010_init(emu)) < 0) {
1302 snd_emu10k1_free(emu); 1662 snd_emu10k1_free(emu);
1303 return err; 1663 return err;
1304 } 1664 }
@@ -1446,8 +1806,8 @@ void snd_emu10k1_resume_init(struct snd_emu10k1 *emu)
1446 snd_emu10k1_ecard_init(emu); 1806 snd_emu10k1_ecard_init(emu);
1447 else if (emu->card_capabilities->ca_cardbus_chip) 1807 else if (emu->card_capabilities->ca_cardbus_chip)
1448 snd_emu10k1_cardbus_init(emu); 1808 snd_emu10k1_cardbus_init(emu);
1449 else if (emu->card_capabilities->emu1212m) 1809 else if (emu->card_capabilities->emu1010)
1450 snd_emu10k1_emu1212m_init(emu); 1810 snd_emu10k1_emu1010_init(emu);
1451 else 1811 else
1452 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE); 1812 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE);
1453 snd_emu10k1_init(emu, emu->enable_ir, 1); 1813 snd_emu10k1_init(emu, emu->enable_ir, 1);
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index 2199b42a6019..bb0fec7f7e1b 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -460,7 +460,7 @@ static int snd_emu10k1x_pcm_prepare(struct snd_pcm_substream *substream)
460 u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size); 460 u32 period_size_bytes = frames_to_bytes(runtime, runtime->period_size);
461 int i; 461 int i;
462 462
463 for(i=0; i < runtime->periods; i++) { 463 for(i = 0; i < runtime->periods; i++) {
464 *table_base++=runtime->dma_addr+(i*period_size_bytes); 464 *table_base++=runtime->dma_addr+(i*period_size_bytes);
465 *table_base++=period_size_bytes<<16; 465 *table_base++=period_size_bytes<<16;
466 } 466 }
@@ -1042,8 +1042,8 @@ static void snd_emu10k1x_proc_reg_write(struct snd_info_entry *entry,
1042 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3) 1042 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
1043 continue; 1043 continue;
1044 1044
1045 if ((reg < 0x49) && (reg >=0) && (val <= 0xffffffff) 1045 if ((reg < 0x49) && (reg >= 0) && (val <= 0xffffffff)
1046 && (channel_id >=0) && (channel_id <= 2) ) 1046 && (channel_id >= 0) && (channel_id <= 2) )
1047 snd_emu10k1x_ptr_write(emu, reg, channel_id, val); 1047 snd_emu10k1x_ptr_write(emu, reg, channel_id, val);
1048 } 1048 }
1049} 1049}
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c
index 13cd6ce89811..c02012cccd8e 100644
--- a/sound/pci/emu10k1/emufx.c
+++ b/sound/pci/emu10k1/emufx.c
@@ -3,6 +3,9 @@
3 * Creative Labs, Inc. 3 * Creative Labs, Inc.
4 * Routines for effect processor FX8010 4 * Routines for effect processor FX8010
5 * 5 *
6 * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
7 * Added EMU 1010 support.
8 *
6 * BUGS: 9 * BUGS:
7 * -- 10 * --
8 * 11 *
@@ -293,7 +296,7 @@ static const u32 db_table[101] = {
293}; 296};
294 297
295/* EMU10k1/EMU10k2 DSP control db gain */ 298/* EMU10k1/EMU10k2 DSP control db gain */
296static DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); 299static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1);
297 300
298static const u32 onoff_table[2] = { 301static const u32 onoff_table[2] = {
299 0x00000000, 0x00000001 302 0x00000000, 0x00000001
@@ -652,13 +655,66 @@ snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct snd_ctl_elem_id *id)
652 return NULL; 655 return NULL;
653} 656}
654 657
658#define MAX_TLV_SIZE 256
659
660static unsigned int *copy_tlv(const unsigned int __user *_tlv)
661{
662 unsigned int data[2];
663 unsigned int *tlv;
664
665 if (!_tlv)
666 return NULL;
667 if (copy_from_user(data, _tlv, sizeof(data)))
668 return NULL;
669 if (data[1] >= MAX_TLV_SIZE)
670 return NULL;
671 tlv = kmalloc(data[1] * 4 + sizeof(data), GFP_KERNEL);
672 if (!tlv)
673 return NULL;
674 memcpy(tlv, data, sizeof(data));
675 if (copy_from_user(tlv + 2, _tlv + 2, data[1])) {
676 kfree(tlv);
677 return NULL;
678 }
679 return tlv;
680}
681
682static int copy_gctl(struct snd_emu10k1 *emu,
683 struct snd_emu10k1_fx8010_control_gpr *gctl,
684 struct snd_emu10k1_fx8010_control_gpr __user *_gctl,
685 int idx)
686{
687 struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
688
689 if (emu->support_tlv)
690 return copy_from_user(gctl, &_gctl[idx], sizeof(*gctl));
691 octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
692 if (copy_from_user(gctl, &octl[idx], sizeof(*octl)))
693 return -EFAULT;
694 gctl->tlv = NULL;
695 return 0;
696}
697
698static int copy_gctl_to_user(struct snd_emu10k1 *emu,
699 struct snd_emu10k1_fx8010_control_gpr __user *_gctl,
700 struct snd_emu10k1_fx8010_control_gpr *gctl,
701 int idx)
702{
703 struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
704
705 if (emu->support_tlv)
706 return copy_to_user(&_gctl[idx], gctl, sizeof(*gctl));
707
708 octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
709 return copy_to_user(&octl[idx], gctl, sizeof(*octl));
710}
711
655static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, 712static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
656 struct snd_emu10k1_fx8010_code *icode) 713 struct snd_emu10k1_fx8010_code *icode)
657{ 714{
658 unsigned int i; 715 unsigned int i;
659 struct snd_ctl_elem_id __user *_id; 716 struct snd_ctl_elem_id __user *_id;
660 struct snd_ctl_elem_id id; 717 struct snd_ctl_elem_id id;
661 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
662 struct snd_emu10k1_fx8010_control_gpr *gctl; 718 struct snd_emu10k1_fx8010_control_gpr *gctl;
663 int err; 719 int err;
664 720
@@ -673,9 +729,8 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
673 if (! gctl) 729 if (! gctl)
674 return -ENOMEM; 730 return -ENOMEM;
675 err = 0; 731 err = 0;
676 for (i = 0, _gctl = icode->gpr_add_controls; 732 for (i = 0; i < icode->gpr_add_control_count; i++) {
677 i < icode->gpr_add_control_count; i++, _gctl++) { 733 if (copy_gctl(emu, gctl, icode->gpr_add_controls, i)) {
678 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
679 err = -EFAULT; 734 err = -EFAULT;
680 goto __error; 735 goto __error;
681 } 736 }
@@ -694,10 +749,9 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
694 goto __error; 749 goto __error;
695 } 750 }
696 } 751 }
697 for (i = 0, _gctl = icode->gpr_list_controls; 752 for (i = 0; i < icode->gpr_list_control_count; i++) {
698 i < icode->gpr_list_control_count; i++, _gctl++) {
699 /* FIXME: we need to check the WRITE access */ 753 /* FIXME: we need to check the WRITE access */
700 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) { 754 if (copy_gctl(emu, gctl, icode->gpr_list_controls, i)) {
701 err = -EFAULT; 755 err = -EFAULT;
702 goto __error; 756 goto __error;
703 } 757 }
@@ -715,13 +769,14 @@ static void snd_emu10k1_ctl_private_free(struct snd_kcontrol *kctl)
715 kctl->private_value = 0; 769 kctl->private_value = 0;
716 list_del(&ctl->list); 770 list_del(&ctl->list);
717 kfree(ctl); 771 kfree(ctl);
772 if (kctl->tlv.p)
773 kfree(kctl->tlv.p);
718} 774}
719 775
720static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, 776static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
721 struct snd_emu10k1_fx8010_code *icode) 777 struct snd_emu10k1_fx8010_code *icode)
722{ 778{
723 unsigned int i, j; 779 unsigned int i, j;
724 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
725 struct snd_emu10k1_fx8010_control_gpr *gctl; 780 struct snd_emu10k1_fx8010_control_gpr *gctl;
726 struct snd_emu10k1_fx8010_ctl *ctl, *nctl; 781 struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
727 struct snd_kcontrol_new knew; 782 struct snd_kcontrol_new knew;
@@ -737,9 +792,8 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
737 goto __error; 792 goto __error;
738 } 793 }
739 794
740 for (i = 0, _gctl = icode->gpr_add_controls; 795 for (i = 0; i < icode->gpr_add_control_count; i++) {
741 i < icode->gpr_add_control_count; i++, _gctl++) { 796 if (copy_gctl(emu, gctl, icode->gpr_add_controls, i)) {
742 if (copy_from_user(gctl, _gctl, sizeof(*gctl))) {
743 err = -EFAULT; 797 err = -EFAULT;
744 goto __error; 798 goto __error;
745 } 799 }
@@ -760,11 +814,10 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
760 knew.device = gctl->id.device; 814 knew.device = gctl->id.device;
761 knew.subdevice = gctl->id.subdevice; 815 knew.subdevice = gctl->id.subdevice;
762 knew.info = snd_emu10k1_gpr_ctl_info; 816 knew.info = snd_emu10k1_gpr_ctl_info;
763 if (gctl->tlv.p) { 817 knew.tlv.p = copy_tlv(gctl->tlv);
764 knew.tlv.p = gctl->tlv.p; 818 if (knew.tlv.p)
765 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 819 knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
766 SNDRV_CTL_ELEM_ACCESS_TLV_READ; 820 SNDRV_CTL_ELEM_ACCESS_TLV_READ;
767 }
768 knew.get = snd_emu10k1_gpr_ctl_get; 821 knew.get = snd_emu10k1_gpr_ctl_get;
769 knew.put = snd_emu10k1_gpr_ctl_put; 822 knew.put = snd_emu10k1_gpr_ctl_put;
770 memset(nctl, 0, sizeof(*nctl)); 823 memset(nctl, 0, sizeof(*nctl));
@@ -782,12 +835,14 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
782 ctl = kmalloc(sizeof(*ctl), GFP_KERNEL); 835 ctl = kmalloc(sizeof(*ctl), GFP_KERNEL);
783 if (ctl == NULL) { 836 if (ctl == NULL) {
784 err = -ENOMEM; 837 err = -ENOMEM;
838 kfree(knew.tlv.p);
785 goto __error; 839 goto __error;
786 } 840 }
787 knew.private_value = (unsigned long)ctl; 841 knew.private_value = (unsigned long)ctl;
788 *ctl = *nctl; 842 *ctl = *nctl;
789 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) { 843 if ((err = snd_ctl_add(emu->card, kctl = snd_ctl_new1(&knew, emu))) < 0) {
790 kfree(ctl); 844 kfree(ctl);
845 kfree(knew.tlv.p);
791 goto __error; 846 goto __error;
792 } 847 }
793 kctl->private_free = snd_emu10k1_ctl_private_free; 848 kctl->private_free = snd_emu10k1_ctl_private_free;
@@ -838,7 +893,6 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
838 unsigned int i = 0, j; 893 unsigned int i = 0, j;
839 unsigned int total = 0; 894 unsigned int total = 0;
840 struct snd_emu10k1_fx8010_control_gpr *gctl; 895 struct snd_emu10k1_fx8010_control_gpr *gctl;
841 struct snd_emu10k1_fx8010_control_gpr __user *_gctl;
842 struct snd_emu10k1_fx8010_ctl *ctl; 896 struct snd_emu10k1_fx8010_ctl *ctl;
843 struct snd_ctl_elem_id *id; 897 struct snd_ctl_elem_id *id;
844 struct list_head *list; 898 struct list_head *list;
@@ -847,11 +901,11 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
847 if (! gctl) 901 if (! gctl)
848 return -ENOMEM; 902 return -ENOMEM;
849 903
850 _gctl = icode->gpr_list_controls;
851 list_for_each(list, &emu->fx8010.gpr_ctl) { 904 list_for_each(list, &emu->fx8010.gpr_ctl) {
852 ctl = emu10k1_gpr_ctl(list); 905 ctl = emu10k1_gpr_ctl(list);
853 total++; 906 total++;
854 if (_gctl && i < icode->gpr_list_control_count) { 907 if (icode->gpr_list_controls &&
908 i < icode->gpr_list_control_count) {
855 memset(gctl, 0, sizeof(*gctl)); 909 memset(gctl, 0, sizeof(*gctl));
856 id = &ctl->kcontrol->id; 910 id = &ctl->kcontrol->id;
857 gctl->id.iface = id->iface; 911 gctl->id.iface = id->iface;
@@ -868,11 +922,11 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
868 gctl->min = ctl->min; 922 gctl->min = ctl->min;
869 gctl->max = ctl->max; 923 gctl->max = ctl->max;
870 gctl->translation = ctl->translation; 924 gctl->translation = ctl->translation;
871 if (copy_to_user(_gctl, gctl, sizeof(*gctl))) { 925 if (copy_gctl_to_user(emu, icode->gpr_list_controls,
926 gctl, i)) {
872 kfree(gctl); 927 kfree(gctl);
873 return -EFAULT; 928 return -EFAULT;
874 } 929 }
875 _gctl++;
876 i++; 930 i++;
877 } 931 }
878 } 932 }
@@ -1023,7 +1077,7 @@ snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1023 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval; 1077 ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
1024 ctl->min = 0; 1078 ctl->min = 0;
1025 ctl->max = 100; 1079 ctl->max = 100;
1026 ctl->tlv.p = snd_emu10k1_db_scale1; 1080 ctl->tlv = snd_emu10k1_db_scale1;
1027 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; 1081 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1028} 1082}
1029 1083
@@ -1038,7 +1092,7 @@ snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
1038 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval; 1092 ctl->gpr[1] = gpr + 1; ctl->value[1] = defval;
1039 ctl->min = 0; 1093 ctl->min = 0;
1040 ctl->max = 100; 1094 ctl->max = 100;
1041 ctl->tlv.p = snd_emu10k1_db_scale1; 1095 ctl->tlv = snd_emu10k1_db_scale1;
1042 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100; 1096 ctl->translation = EMU10K1_GPR_TRANSLATION_TABLE100;
1043} 1097}
1044 1098
@@ -1069,6 +1123,21 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl
1069 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF; 1123 ctl->translation = EMU10K1_GPR_TRANSLATION_ONOFF;
1070} 1124}
1071 1125
1126static int snd_emu10k1_audigy_dsp_convert_32_to_2x16(
1127 struct snd_emu10k1_fx8010_code *icode,
1128 u32 *ptr, int tmp, int bit_shifter16,
1129 int reg_in, int reg_out)
1130{
1131 A_OP(icode, ptr, iACC3, A_GPR(tmp + 1), reg_in, A_C_00000000, A_C_00000000);
1132 A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp + 1), A_GPR(bit_shifter16 - 1), A_C_00000000);
1133 A_OP(icode, ptr, iTSTNEG, A_GPR(tmp + 2), A_GPR(tmp), A_C_80000000, A_GPR(bit_shifter16 - 2));
1134 A_OP(icode, ptr, iANDXOR, A_GPR(tmp + 2), A_GPR(tmp + 2), A_C_80000000, A_C_00000000);
1135 A_OP(icode, ptr, iANDXOR, A_GPR(tmp), A_GPR(tmp), A_GPR(bit_shifter16 - 3), A_C_00000000);
1136 A_OP(icode, ptr, iMACINT0, A_GPR(tmp), A_C_00000000, A_GPR(tmp), A_C_00010000);
1137 A_OP(icode, ptr, iANDXOR, reg_out, A_GPR(tmp), A_C_ffffffff, A_GPR(tmp + 2));
1138 A_OP(icode, ptr, iACC3, reg_out + 1, A_GPR(tmp + 1), A_C_00000000, A_C_00000000);
1139 return 1;
1140}
1072 1141
1073/* 1142/*
1074 * initial DSP configuration for Audigy 1143 * initial DSP configuration for Audigy
@@ -1077,6 +1146,7 @@ snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl
1077static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) 1146static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1078{ 1147{
1079 int err, i, z, gpr, nctl; 1148 int err, i, z, gpr, nctl;
1149 int bit_shifter16;
1080 const int playback = 10; 1150 const int playback = 10;
1081 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */ 1151 const int capture = playback + (SND_EMU10K1_PLAYBACK_CHANNELS * 2); /* we reserve 10 voices */
1082 const int stereo_mix = capture + 2; 1152 const int stereo_mix = capture + 2;
@@ -1114,17 +1184,14 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1114 ptr = 0; 1184 ptr = 0;
1115 nctl = 0; 1185 nctl = 0;
1116 gpr = stereo_mix + 10; 1186 gpr = stereo_mix + 10;
1187 gpr_map[gpr++] = 0x00007fff;
1188 gpr_map[gpr++] = 0x00008000;
1189 gpr_map[gpr++] = 0x0000ffff;
1190 bit_shifter16 = gpr;
1117 1191
1118 /* stop FX processor */ 1192 /* stop FX processor */
1119 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP); 1193 snd_emu10k1_ptr_write(emu, A_DBG, 0, (emu->fx8010.dbg = 0) | A_DBG_SINGLE_STEP);
1120 1194
1121#if 0
1122 /* FIX: jcd test */
1123 for (z = 0; z < 80; z=z+2) {
1124 A_OP(icode, &ptr, iACC3, A_EXTOUT(z), A_FXBUS(FXBUS_PCM_LEFT_FRONT), A_C_00000000, A_C_00000000); /* left */
1125 A_OP(icode, &ptr, iACC3, A_EXTOUT(z+1), A_FXBUS(FXBUS_PCM_RIGHT_FRONT), A_C_00000000, A_C_00000000); /* right */
1126 }
1127#endif /* jcd test */
1128#if 1 1195#if 1
1129 /* PCM front Playback Volume (independent from stereo mix) */ 1196 /* PCM front Playback Volume (independent from stereo mix) */
1130 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT)); 1197 A_OP(icode, &ptr, iMAC0, A_GPR(playback), A_C_00000000, A_GPR(gpr), A_FXBUS(FXBUS_PCM_LEFT_FRONT));
@@ -1182,13 +1249,20 @@ static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
1182 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT)); 1249 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_FXBUS(FXBUS_MIDI_RIGHT));
1183 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0); 1250 snd_emu10k1_init_stereo_control(&controls[nctl++], "Synth Capture Volume", gpr, 0);
1184 gpr += 2; 1251 gpr += 2;
1185 1252
1186 /* 1253 /*
1187 * inputs 1254 * inputs
1188 */ 1255 */
1189#define A_ADD_VOLUME_IN(var,vol,input) \ 1256#define A_ADD_VOLUME_IN(var,vol,input) \
1190A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) 1257A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1191 1258
1259 /* emu1212 DSP 0 and DSP 1 Capture */
1260 if (emu->card_capabilities->emu1010) {
1261 A_OP(icode, &ptr, iMAC0, A_GPR(capture+0), A_GPR(capture+0), A_GPR(gpr), A_P16VIN(0x0));
1262 A_OP(icode, &ptr, iMAC0, A_GPR(capture+1), A_GPR(capture+1), A_GPR(gpr+1), A_P16VIN(0x1));
1263 snd_emu10k1_init_stereo_control(&controls[nctl++], "EMU Capture Volume", gpr, 0);
1264 gpr += 2;
1265 }
1192 /* AC'97 Playback Volume - used only for mic (renamed later) */ 1266 /* AC'97 Playback Volume - used only for mic (renamed later) */
1193 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L); 1267 A_ADD_VOLUME_IN(stereo_mix, gpr, A_EXTIN_AC97_L);
1194 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R); 1268 A_ADD_VOLUME_IN(stereo_mix+1, gpr+1, A_EXTIN_AC97_R);
@@ -1429,6 +1503,13 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1429 1503
1430 /* digital outputs */ 1504 /* digital outputs */
1431 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */ 1505 /* A_PUT_STEREO_OUTPUT(A_EXTOUT_FRONT_L, A_EXTOUT_FRONT_R, playback + SND_EMU10K1_PLAYBACK_CHANNELS); */
1506 if (emu->card_capabilities->emu1010) {
1507 /* EMU1010 Outputs from PCM Front, Rear, Center, LFE, Side */
1508 snd_printk("EMU outputs on\n");
1509 for (z = 0; z < 8; z++) {
1510 A_OP(icode, &ptr, iACC3, A_EMU32OUTL(z), A_GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + z), A_C_00000000, A_C_00000000);
1511 }
1512 }
1432 1513
1433 /* IEC958 Optical Raw Playback Switch */ 1514 /* IEC958 Optical Raw Playback Switch */
1434 gpr_map[gpr++] = 0; 1515 gpr_map[gpr++] = 0;
@@ -1466,9 +1547,57 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1466 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1); 1547 A_PUT_OUTPUT(A_EXTOUT_ADC_CAP_R, capture+1);
1467#endif 1548#endif
1468 1549
1469 /* EFX capture - capture the 16 EXTINs */ 1550 if (emu->card_capabilities->emu1010) {
1470 for (z = 0; z < 16; z++) { 1551 snd_printk("EMU inputs on\n");
1471 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z)); 1552 /* Capture 8 channels of S32_LE sound */
1553
1554 /* printk("emufx.c: gpr=0x%x, tmp=0x%x\n",gpr, tmp); */
1555 /* For the EMU1010: How to get 32bit values from the DSP. High 16bits into L, low 16bits into R. */
1556 /* A_P16VIN(0) is delayed by one sample,
1557 * so all other A_P16VIN channels will need to also be delayed
1558 */
1559 /* Left ADC in. 1 of 2 */
1560 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_P16VIN(0x0), A_FXBUS2(0) );
1561 /* Right ADC in 1 of 2 */
1562 gpr_map[gpr++] = 0x00000000;
1563 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(2) );
1564 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x1), A_C_00000000, A_C_00000000);
1565 gpr_map[gpr++] = 0x00000000;
1566 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(4) );
1567 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x2), A_C_00000000, A_C_00000000);
1568 gpr_map[gpr++] = 0x00000000;
1569 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(6) );
1570 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x3), A_C_00000000, A_C_00000000);
1571 /* For 96kHz mode */
1572 /* Left ADC in. 2 of 2 */
1573 gpr_map[gpr++] = 0x00000000;
1574 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0x8) );
1575 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x4), A_C_00000000, A_C_00000000);
1576 /* Right ADC in 2 of 2 */
1577 gpr_map[gpr++] = 0x00000000;
1578 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xa) );
1579 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x5), A_C_00000000, A_C_00000000);
1580 gpr_map[gpr++] = 0x00000000;
1581 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xc) );
1582 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x6), A_C_00000000, A_C_00000000);
1583 gpr_map[gpr++] = 0x00000000;
1584 snd_emu10k1_audigy_dsp_convert_32_to_2x16( icode, &ptr, tmp, bit_shifter16, A_GPR(gpr - 1), A_FXBUS2(0xe) );
1585 A_OP(icode, &ptr, iACC3, A_GPR(gpr - 1), A_P16VIN(0x7), A_C_00000000, A_C_00000000);
1586
1587#if 0
1588 for (z = 4; z < 8; z++) {
1589 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
1590 }
1591 for (z = 0xc; z < 0x10; z++) {
1592 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_C_00000000);
1593 }
1594#endif
1595 } else {
1596 /* EFX capture - capture the 16 EXTINs */
1597 /* Capture 16 channels of S16_LE sound */
1598 for (z = 0; z < 16; z++) {
1599 A_OP(icode, &ptr, iACC3, A_FXBUS2(z), A_C_00000000, A_C_00000000, A_EXTIN(z));
1600 }
1472 } 1601 }
1473 1602
1474#endif /* JCD test */ 1603#endif /* JCD test */
@@ -1488,7 +1617,9 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
1488 seg = snd_enter_user(); 1617 seg = snd_enter_user();
1489 icode->gpr_add_control_count = nctl; 1618 icode->gpr_add_control_count = nctl;
1490 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls; 1619 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
1620 emu->support_tlv = 1; /* support TLV */
1491 err = snd_emu10k1_icode_poke(emu, icode); 1621 err = snd_emu10k1_icode_poke(emu, icode);
1622 emu->support_tlv = 0; /* clear again */
1492 snd_leave_user(seg); 1623 snd_leave_user(seg);
1493 1624
1494 __err: 1625 __err:
@@ -2105,7 +2236,9 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
2105 seg = snd_enter_user(); 2236 seg = snd_enter_user();
2106 icode->gpr_add_control_count = i; 2237 icode->gpr_add_control_count = i;
2107 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls; 2238 icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
2239 emu->support_tlv = 1; /* support TLV */
2108 err = snd_emu10k1_icode_poke(emu, icode); 2240 err = snd_emu10k1_icode_poke(emu, icode);
2241 emu->support_tlv = 0; /* clear again */
2109 snd_leave_user(seg); 2242 snd_leave_user(seg);
2110 if (err >= 0) 2243 if (err >= 0)
2111 err = snd_emu10k1_ipcm_poke(emu, ipcm); 2244 err = snd_emu10k1_ipcm_poke(emu, ipcm);
@@ -2138,7 +2271,7 @@ void snd_emu10k1_free_efx(struct snd_emu10k1 *emu)
2138 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP); 2271 snd_emu10k1_ptr_write(emu, DBG, 0, emu->fx8010.dbg = EMU10K1_DBG_SINGLE_STEP);
2139} 2272}
2140 2273
2141#if 0 // FIXME: who use them? 2274#if 0 /* FIXME: who use them? */
2142int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output) 2275int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output)
2143{ 2276{
2144 if (output < 0 || output >= 6) 2277 if (output < 0 || output >= 6)
@@ -2249,6 +2382,9 @@ static int snd_emu10k1_fx8010_ioctl(struct snd_hwdep * hw, struct file *file, un
2249 int res; 2382 int res;
2250 2383
2251 switch (cmd) { 2384 switch (cmd) {
2385 case SNDRV_EMU10K1_IOCTL_PVERSION:
2386 emu->support_tlv = 1;
2387 return put_user(SNDRV_EMU10K1_VERSION, (int __user *)argp);
2252 case SNDRV_EMU10K1_IOCTL_INFO: 2388 case SNDRV_EMU10K1_IOCTL_INFO:
2253 info = kmalloc(sizeof(*info), GFP_KERNEL); 2389 info = kmalloc(sizeof(*info), GFP_KERNEL);
2254 if (!info) 2390 if (!info)
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c
index c31f3d0877fa..4db6e1ca1665 100644
--- a/sound/pci/emu10k1/emumixer.c
+++ b/sound/pci/emu10k1/emumixer.c
@@ -5,6 +5,9 @@
5 * Routines for control of EMU10K1 chips / mixer routines 5 * Routines for control of EMU10K1 chips / mixer routines
6 * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com> 6 * Multichannel PCM support Copyright (c) Lee Revell <rlrevell@joe-job.com>
7 * 7 *
8 * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
9 * Added EMU 1010 support.
10 *
8 * BUGS: 11 * BUGS:
9 * -- 12 * --
10 * 13 *
@@ -32,9 +35,15 @@
32#include <linux/init.h> 35#include <linux/init.h>
33#include <sound/core.h> 36#include <sound/core.h>
34#include <sound/emu10k1.h> 37#include <sound/emu10k1.h>
38#include <linux/delay.h>
39#include <sound/tlv.h>
40
41#include "p17v.h"
35 42
36#define AC97_ID_STAC9758 0x83847658 43#define AC97_ID_STAC9758 0x83847658
37 44
45static const DECLARE_TLV_DB_SCALE(snd_audigy_db_scale2, -10350, 50, 1); /* WM8775 gain scale */
46
38static int snd_emu10k1_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 47static int snd_emu10k1_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
39{ 48{
40 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; 49 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
@@ -68,6 +77,669 @@ static int snd_emu10k1_spdif_get_mask(struct snd_kcontrol *kcontrol,
68 return 0; 77 return 0;
69} 78}
70 79
80static char *emu1010_src_texts[] = {
81 "Silence",
82 "Dock Mic A",
83 "Dock Mic B",
84 "Dock ADC1 Left",
85 "Dock ADC1 Right",
86 "Dock ADC2 Left",
87 "Dock ADC2 Right",
88 "Dock ADC3 Left",
89 "Dock ADC3 Right",
90 "0202 ADC Left",
91 "0202 ADC Right",
92 "0202 SPDIF Left",
93 "0202 SPDIF Right",
94 "ADAT 0",
95 "ADAT 1",
96 "ADAT 2",
97 "ADAT 3",
98 "ADAT 4",
99 "ADAT 5",
100 "ADAT 6",
101 "ADAT 7",
102 "DSP 0",
103 "DSP 1",
104 "DSP 2",
105 "DSP 3",
106 "DSP 4",
107 "DSP 5",
108 "DSP 6",
109 "DSP 7",
110 "DSP 8",
111 "DSP 9",
112 "DSP 10",
113 "DSP 11",
114 "DSP 12",
115 "DSP 13",
116 "DSP 14",
117 "DSP 15",
118 "DSP 16",
119 "DSP 17",
120 "DSP 18",
121 "DSP 19",
122 "DSP 20",
123 "DSP 21",
124 "DSP 22",
125 "DSP 23",
126 "DSP 24",
127 "DSP 25",
128 "DSP 26",
129 "DSP 27",
130 "DSP 28",
131 "DSP 29",
132 "DSP 30",
133 "DSP 31",
134};
135
136static unsigned int emu1010_src_regs[] = {
137 EMU_SRC_SILENCE,/* 0 */
138 EMU_SRC_DOCK_MIC_A1, /* 1 */
139 EMU_SRC_DOCK_MIC_B1, /* 2 */
140 EMU_SRC_DOCK_ADC1_LEFT1, /* 3 */
141 EMU_SRC_DOCK_ADC1_RIGHT1, /* 4 */
142 EMU_SRC_DOCK_ADC2_LEFT1, /* 5 */
143 EMU_SRC_DOCK_ADC2_RIGHT1, /* 6 */
144 EMU_SRC_DOCK_ADC3_LEFT1, /* 7 */
145 EMU_SRC_DOCK_ADC3_RIGHT1, /* 8 */
146 EMU_SRC_HAMOA_ADC_LEFT1, /* 9 */
147 EMU_SRC_HAMOA_ADC_RIGHT1, /* 10 */
148 EMU_SRC_HANA_SPDIF_LEFT1, /* 11 */
149 EMU_SRC_HANA_SPDIF_RIGHT1, /* 12 */
150 EMU_SRC_HANA_ADAT, /* 13 */
151 EMU_SRC_HANA_ADAT+1, /* 14 */
152 EMU_SRC_HANA_ADAT+2, /* 15 */
153 EMU_SRC_HANA_ADAT+3, /* 16 */
154 EMU_SRC_HANA_ADAT+4, /* 17 */
155 EMU_SRC_HANA_ADAT+5, /* 18 */
156 EMU_SRC_HANA_ADAT+6, /* 19 */
157 EMU_SRC_HANA_ADAT+7, /* 20 */
158 EMU_SRC_ALICE_EMU32A, /* 21 */
159 EMU_SRC_ALICE_EMU32A+1, /* 22 */
160 EMU_SRC_ALICE_EMU32A+2, /* 23 */
161 EMU_SRC_ALICE_EMU32A+3, /* 24 */
162 EMU_SRC_ALICE_EMU32A+4, /* 25 */
163 EMU_SRC_ALICE_EMU32A+5, /* 26 */
164 EMU_SRC_ALICE_EMU32A+6, /* 27 */
165 EMU_SRC_ALICE_EMU32A+7, /* 28 */
166 EMU_SRC_ALICE_EMU32A+8, /* 29 */
167 EMU_SRC_ALICE_EMU32A+9, /* 30 */
168 EMU_SRC_ALICE_EMU32A+0xa, /* 31 */
169 EMU_SRC_ALICE_EMU32A+0xb, /* 32 */
170 EMU_SRC_ALICE_EMU32A+0xc, /* 33 */
171 EMU_SRC_ALICE_EMU32A+0xd, /* 34 */
172 EMU_SRC_ALICE_EMU32A+0xe, /* 35 */
173 EMU_SRC_ALICE_EMU32A+0xf, /* 36 */
174 EMU_SRC_ALICE_EMU32B, /* 37 */
175 EMU_SRC_ALICE_EMU32B+1, /* 38 */
176 EMU_SRC_ALICE_EMU32B+2, /* 39 */
177 EMU_SRC_ALICE_EMU32B+3, /* 40 */
178 EMU_SRC_ALICE_EMU32B+4, /* 41 */
179 EMU_SRC_ALICE_EMU32B+5, /* 42 */
180 EMU_SRC_ALICE_EMU32B+6, /* 43 */
181 EMU_SRC_ALICE_EMU32B+7, /* 44 */
182 EMU_SRC_ALICE_EMU32B+8, /* 45 */
183 EMU_SRC_ALICE_EMU32B+9, /* 46 */
184 EMU_SRC_ALICE_EMU32B+0xa, /* 47 */
185 EMU_SRC_ALICE_EMU32B+0xb, /* 48 */
186 EMU_SRC_ALICE_EMU32B+0xc, /* 49 */
187 EMU_SRC_ALICE_EMU32B+0xd, /* 50 */
188 EMU_SRC_ALICE_EMU32B+0xe, /* 51 */
189 EMU_SRC_ALICE_EMU32B+0xf, /* 52 */
190};
191
192static unsigned int emu1010_output_dst[] = {
193 EMU_DST_DOCK_DAC1_LEFT1, /* 0 */
194 EMU_DST_DOCK_DAC1_RIGHT1, /* 1 */
195 EMU_DST_DOCK_DAC2_LEFT1, /* 2 */
196 EMU_DST_DOCK_DAC2_RIGHT1, /* 3 */
197 EMU_DST_DOCK_DAC3_LEFT1, /* 4 */
198 EMU_DST_DOCK_DAC3_RIGHT1, /* 5 */
199 EMU_DST_DOCK_DAC4_LEFT1, /* 6 */
200 EMU_DST_DOCK_DAC4_RIGHT1, /* 7 */
201 EMU_DST_DOCK_PHONES_LEFT1, /* 8 */
202 EMU_DST_DOCK_PHONES_RIGHT1, /* 9 */
203 EMU_DST_DOCK_SPDIF_LEFT1, /* 10 */
204 EMU_DST_DOCK_SPDIF_RIGHT1, /* 11 */
205 EMU_DST_HANA_SPDIF_LEFT1, /* 12 */
206 EMU_DST_HANA_SPDIF_RIGHT1, /* 13 */
207 EMU_DST_HAMOA_DAC_LEFT1, /* 14 */
208 EMU_DST_HAMOA_DAC_RIGHT1, /* 15 */
209 EMU_DST_HANA_ADAT, /* 16 */
210 EMU_DST_HANA_ADAT+1, /* 17 */
211 EMU_DST_HANA_ADAT+2, /* 18 */
212 EMU_DST_HANA_ADAT+3, /* 19 */
213 EMU_DST_HANA_ADAT+4, /* 20 */
214 EMU_DST_HANA_ADAT+5, /* 21 */
215 EMU_DST_HANA_ADAT+6, /* 22 */
216 EMU_DST_HANA_ADAT+7, /* 23 */
217};
218
219static unsigned int emu1010_input_dst[] = {
220 EMU_DST_ALICE2_EMU32_0,
221 EMU_DST_ALICE2_EMU32_1,
222 EMU_DST_ALICE2_EMU32_2,
223 EMU_DST_ALICE2_EMU32_3,
224 EMU_DST_ALICE2_EMU32_4,
225 EMU_DST_ALICE2_EMU32_5,
226 EMU_DST_ALICE2_EMU32_6,
227 EMU_DST_ALICE2_EMU32_7,
228 EMU_DST_ALICE2_EMU32_8,
229 EMU_DST_ALICE2_EMU32_9,
230 EMU_DST_ALICE2_EMU32_A,
231 EMU_DST_ALICE2_EMU32_B,
232 EMU_DST_ALICE2_EMU32_C,
233 EMU_DST_ALICE2_EMU32_D,
234 EMU_DST_ALICE2_EMU32_E,
235 EMU_DST_ALICE2_EMU32_F,
236 EMU_DST_ALICE_I2S0_LEFT,
237 EMU_DST_ALICE_I2S0_RIGHT,
238 EMU_DST_ALICE_I2S1_LEFT,
239 EMU_DST_ALICE_I2S1_RIGHT,
240 EMU_DST_ALICE_I2S2_LEFT,
241 EMU_DST_ALICE_I2S2_RIGHT,
242};
243
244static int snd_emu1010_input_output_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
245{
246 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
247 uinfo->count = 1;
248 uinfo->value.enumerated.items = 53;
249 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
250 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
251 strcpy(uinfo->value.enumerated.name, emu1010_src_texts[uinfo->value.enumerated.item]);
252 return 0;
253}
254
255static int snd_emu1010_output_source_get(struct snd_kcontrol *kcontrol,
256 struct snd_ctl_elem_value *ucontrol)
257{
258 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
259 int channel;
260
261 channel = (kcontrol->private_value) & 0xff;
262 ucontrol->value.enumerated.item[0] = emu->emu1010.output_source[channel];
263 return 0;
264}
265
266static int snd_emu1010_output_source_put(struct snd_kcontrol *kcontrol,
267 struct snd_ctl_elem_value *ucontrol)
268{
269 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
270 int change = 0;
271 unsigned int val;
272 int channel;
273
274 channel = (kcontrol->private_value) & 0xff;
275 if (emu->emu1010.output_source[channel] != ucontrol->value.enumerated.item[0]) {
276 val = emu->emu1010.output_source[channel] = ucontrol->value.enumerated.item[0];
277 change = 1;
278 snd_emu1010_fpga_link_dst_src_write(emu,
279 emu1010_output_dst[channel], emu1010_src_regs[val]);
280 }
281 return change;
282}
283
284static int snd_emu1010_input_source_get(struct snd_kcontrol *kcontrol,
285 struct snd_ctl_elem_value *ucontrol)
286{
287 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
288 int channel;
289
290 channel = (kcontrol->private_value) & 0xff;
291 ucontrol->value.enumerated.item[0] = emu->emu1010.input_source[channel];
292 return 0;
293}
294
295static int snd_emu1010_input_source_put(struct snd_kcontrol *kcontrol,
296 struct snd_ctl_elem_value *ucontrol)
297{
298 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
299 int change = 0;
300 unsigned int val;
301 int channel;
302
303 channel = (kcontrol->private_value) & 0xff;
304 if (emu->emu1010.input_source[channel] != ucontrol->value.enumerated.item[0]) {
305 val = emu->emu1010.input_source[channel] = ucontrol->value.enumerated.item[0];
306 change = 1;
307 snd_emu1010_fpga_link_dst_src_write(emu,
308 emu1010_input_dst[channel], emu1010_src_regs[val]);
309 }
310 return change;
311}
312
313#define EMU1010_SOURCE_OUTPUT(xname,chid) \
314{ \
315 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
316 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
317 .info = snd_emu1010_input_output_source_info, \
318 .get = snd_emu1010_output_source_get, \
319 .put = snd_emu1010_output_source_put, \
320 .private_value = chid \
321}
322
323static struct snd_kcontrol_new snd_emu1010_output_enum_ctls[] __devinitdata = {
324 EMU1010_SOURCE_OUTPUT("Dock DAC1 Left Playback Enum", 0),
325 EMU1010_SOURCE_OUTPUT("Dock DAC1 Right Playback Enum", 1),
326 EMU1010_SOURCE_OUTPUT("Dock DAC2 Left Playback Enum", 2),
327 EMU1010_SOURCE_OUTPUT("Dock DAC2 Right Playback Enum", 3),
328 EMU1010_SOURCE_OUTPUT("Dock DAC3 Left Playback Enum", 4),
329 EMU1010_SOURCE_OUTPUT("Dock DAC3 Right Playback Enum", 5),
330 EMU1010_SOURCE_OUTPUT("Dock DAC4 Left Playback Enum", 6),
331 EMU1010_SOURCE_OUTPUT("Dock DAC4 Right Playback Enum", 7),
332 EMU1010_SOURCE_OUTPUT("Dock Phones Left Playback Enum", 8),
333 EMU1010_SOURCE_OUTPUT("Dock Phones Right Playback Enum", 9),
334 EMU1010_SOURCE_OUTPUT("Dock SPDIF Left Playback Enum", 0xa),
335 EMU1010_SOURCE_OUTPUT("Dock SPDIF Right Playback Enum", 0xb),
336 EMU1010_SOURCE_OUTPUT("1010 SPDIF Left Playback Enum", 0xc),
337 EMU1010_SOURCE_OUTPUT("1010 SPDIF Right Playback Enum", 0xd),
338 EMU1010_SOURCE_OUTPUT("0202 DAC Left Playback Enum", 0xe),
339 EMU1010_SOURCE_OUTPUT("0202 DAC Right Playback Enum", 0xf),
340 EMU1010_SOURCE_OUTPUT("1010 ADAT 0 Playback Enum", 0x10),
341 EMU1010_SOURCE_OUTPUT("1010 ADAT 1 Playback Enum", 0x11),
342 EMU1010_SOURCE_OUTPUT("1010 ADAT 2 Playback Enum", 0x12),
343 EMU1010_SOURCE_OUTPUT("1010 ADAT 3 Playback Enum", 0x13),
344 EMU1010_SOURCE_OUTPUT("1010 ADAT 4 Playback Enum", 0x14),
345 EMU1010_SOURCE_OUTPUT("1010 ADAT 5 Playback Enum", 0x15),
346 EMU1010_SOURCE_OUTPUT("1010 ADAT 6 Playback Enum", 0x16),
347 EMU1010_SOURCE_OUTPUT("1010 ADAT 7 Playback Enum", 0x17),
348};
349
350#define EMU1010_SOURCE_INPUT(xname,chid) \
351{ \
352 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
353 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
354 .info = snd_emu1010_input_output_source_info, \
355 .get = snd_emu1010_input_source_get, \
356 .put = snd_emu1010_input_source_put, \
357 .private_value = chid \
358}
359
360static struct snd_kcontrol_new snd_emu1010_input_enum_ctls[] __devinitdata = {
361 EMU1010_SOURCE_INPUT("DSP 0 Capture Enum", 0),
362 EMU1010_SOURCE_INPUT("DSP 1 Capture Enum", 1),
363 EMU1010_SOURCE_INPUT("DSP 2 Capture Enum", 2),
364 EMU1010_SOURCE_INPUT("DSP 3 Capture Enum", 3),
365 EMU1010_SOURCE_INPUT("DSP 4 Capture Enum", 4),
366 EMU1010_SOURCE_INPUT("DSP 5 Capture Enum", 5),
367 EMU1010_SOURCE_INPUT("DSP 6 Capture Enum", 6),
368 EMU1010_SOURCE_INPUT("DSP 7 Capture Enum", 7),
369 EMU1010_SOURCE_INPUT("DSP 8 Capture Enum", 8),
370 EMU1010_SOURCE_INPUT("DSP 9 Capture Enum", 9),
371 EMU1010_SOURCE_INPUT("DSP A Capture Enum", 0xa),
372 EMU1010_SOURCE_INPUT("DSP B Capture Enum", 0xb),
373 EMU1010_SOURCE_INPUT("DSP C Capture Enum", 0xc),
374 EMU1010_SOURCE_INPUT("DSP D Capture Enum", 0xd),
375 EMU1010_SOURCE_INPUT("DSP E Capture Enum", 0xe),
376 EMU1010_SOURCE_INPUT("DSP F Capture Enum", 0xf),
377 EMU1010_SOURCE_INPUT("DSP 10 Capture Enum", 0x10),
378 EMU1010_SOURCE_INPUT("DSP 11 Capture Enum", 0x11),
379 EMU1010_SOURCE_INPUT("DSP 12 Capture Enum", 0x12),
380 EMU1010_SOURCE_INPUT("DSP 13 Capture Enum", 0x13),
381 EMU1010_SOURCE_INPUT("DSP 14 Capture Enum", 0x14),
382 EMU1010_SOURCE_INPUT("DSP 15 Capture Enum", 0x15),
383};
384
385
386
387
388static int snd_emu1010_adc_pads_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
389{
390 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
391 uinfo->count = 1;
392 uinfo->value.integer.min = 0;
393 uinfo->value.integer.max = 1;
394 return 0;
395}
396
397static int snd_emu1010_adc_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
398{
399 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
400 unsigned int mask = kcontrol->private_value & 0xff;
401 ucontrol->value.integer.value[0] = (emu->emu1010.adc_pads & mask) ? 1 : 0;
402 return 0;
403}
404
405static int snd_emu1010_adc_pads_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
406{
407 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
408 unsigned int mask = kcontrol->private_value & 0xff;
409 unsigned int val, cache;
410 val = ucontrol->value.integer.value[0];
411 cache = emu->emu1010.adc_pads;
412 if (val == 1)
413 cache = cache | mask;
414 else
415 cache = cache & ~mask;
416 if (cache != emu->emu1010.adc_pads) {
417 snd_emu1010_fpga_write(emu, EMU_HANA_ADC_PADS, cache );
418 emu->emu1010.adc_pads = cache;
419 }
420
421 return 0;
422}
423
424
425
426#define EMU1010_ADC_PADS(xname,chid) \
427{ \
428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
429 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
430 .info = snd_emu1010_adc_pads_info, \
431 .get = snd_emu1010_adc_pads_get, \
432 .put = snd_emu1010_adc_pads_put, \
433 .private_value = chid \
434}
435
436static struct snd_kcontrol_new snd_emu1010_adc_pads[] __devinitdata = {
437 EMU1010_ADC_PADS("ADC1 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD1),
438 EMU1010_ADC_PADS("ADC2 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD2),
439 EMU1010_ADC_PADS("ADC3 14dB PAD Audio Dock Capture Switch", EMU_HANA_DOCK_ADC_PAD3),
440 EMU1010_ADC_PADS("ADC1 14dB PAD 0202 Capture Switch", EMU_HANA_0202_ADC_PAD1),
441};
442
443static int snd_emu1010_dac_pads_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
444{
445 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
446 uinfo->count = 1;
447 uinfo->value.integer.min = 0;
448 uinfo->value.integer.max = 1;
449 return 0;
450}
451
452static int snd_emu1010_dac_pads_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
453{
454 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
455 unsigned int mask = kcontrol->private_value & 0xff;
456 ucontrol->value.integer.value[0] = (emu->emu1010.dac_pads & mask) ? 1 : 0;
457 return 0;
458}
459
460static int snd_emu1010_dac_pads_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
461{
462 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
463 unsigned int mask = kcontrol->private_value & 0xff;
464 unsigned int val, cache;
465 val = ucontrol->value.integer.value[0];
466 cache = emu->emu1010.dac_pads;
467 if (val == 1)
468 cache = cache | mask;
469 else
470 cache = cache & ~mask;
471 if (cache != emu->emu1010.dac_pads) {
472 snd_emu1010_fpga_write(emu, EMU_HANA_DAC_PADS, cache );
473 emu->emu1010.dac_pads = cache;
474 }
475
476 return 0;
477}
478
479
480
481#define EMU1010_DAC_PADS(xname,chid) \
482{ \
483 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
484 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
485 .info = snd_emu1010_dac_pads_info, \
486 .get = snd_emu1010_dac_pads_get, \
487 .put = snd_emu1010_dac_pads_put, \
488 .private_value = chid \
489}
490
491static struct snd_kcontrol_new snd_emu1010_dac_pads[] __devinitdata = {
492 EMU1010_DAC_PADS("DAC1 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD1),
493 EMU1010_DAC_PADS("DAC2 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD2),
494 EMU1010_DAC_PADS("DAC3 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD3),
495 EMU1010_DAC_PADS("DAC4 Audio Dock 14dB PAD Playback Switch", EMU_HANA_DOCK_DAC_PAD4),
496 EMU1010_DAC_PADS("DAC1 0202 14dB PAD Playback Switch", EMU_HANA_0202_DAC_PAD1),
497};
498
499
500static int snd_emu1010_internal_clock_info(struct snd_kcontrol *kcontrol,
501 struct snd_ctl_elem_info *uinfo)
502{
503 static char *texts[2] = {
504 "44100", "48000"
505 };
506
507 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
508 uinfo->count = 1;
509 uinfo->value.enumerated.items = 2;
510 if (uinfo->value.enumerated.item > 1)
511 uinfo->value.enumerated.item = 1;
512 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
513 return 0;
514}
515
516static int snd_emu1010_internal_clock_get(struct snd_kcontrol *kcontrol,
517 struct snd_ctl_elem_value *ucontrol)
518{
519 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
520
521 ucontrol->value.enumerated.item[0] = emu->emu1010.internal_clock;
522 return 0;
523}
524
525static int snd_emu1010_internal_clock_put(struct snd_kcontrol *kcontrol,
526 struct snd_ctl_elem_value *ucontrol)
527{
528 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
529 unsigned int val;
530 int change = 0;
531
532 val = ucontrol->value.enumerated.item[0] ;
533 change = (emu->emu1010.internal_clock != val);
534 if (change) {
535 emu->emu1010.internal_clock = val;
536 switch (val) {
537 case 0:
538 /* 44100 */
539 /* Mute all */
540 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
541 /* Default fallback clock 48kHz */
542 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_44_1K );
543 /* Word Clock source, Internal 44.1kHz x1 */
544 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
545 EMU_HANA_WCLOCK_INT_44_1K | EMU_HANA_WCLOCK_1X );
546 /* Set LEDs on Audio Dock */
547 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,
548 EMU_HANA_DOCK_LEDS_2_44K | EMU_HANA_DOCK_LEDS_2_LOCK );
549 /* Allow DLL to settle */
550 msleep(10);
551 /* Unmute all */
552 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
553 break;
554 case 1:
555 /* 48000 */
556 /* Mute all */
557 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_MUTE );
558 /* Default fallback clock 48kHz */
559 snd_emu1010_fpga_write(emu, EMU_HANA_DEFCLOCK, EMU_HANA_DEFCLOCK_48K );
560 /* Word Clock source, Internal 48kHz x1 */
561 snd_emu1010_fpga_write(emu, EMU_HANA_WCLOCK,
562 EMU_HANA_WCLOCK_INT_48K | EMU_HANA_WCLOCK_1X );
563 /* Set LEDs on Audio Dock */
564 snd_emu1010_fpga_write(emu, EMU_HANA_DOCK_LEDS_2,
565 EMU_HANA_DOCK_LEDS_2_48K | EMU_HANA_DOCK_LEDS_2_LOCK );
566 /* Allow DLL to settle */
567 msleep(10);
568 /* Unmute all */
569 snd_emu1010_fpga_write(emu, EMU_HANA_UNMUTE, EMU_UNMUTE );
570 break;
571 }
572 }
573 return change;
574}
575
576static struct snd_kcontrol_new snd_emu1010_internal_clock =
577{
578 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
579 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
580 .name = "Clock Internal Rate",
581 .count = 1,
582 .info = snd_emu1010_internal_clock_info,
583 .get = snd_emu1010_internal_clock_get,
584 .put = snd_emu1010_internal_clock_put
585};
586
587static int snd_audigy_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
588 struct snd_ctl_elem_info *uinfo)
589{
590#if 0
591 static char *texts[4] = {
592 "Unknown1", "Unknown2", "Mic", "Line"
593 };
594#endif
595 static char *texts[2] = {
596 "Mic", "Line"
597 };
598
599 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
600 uinfo->count = 1;
601 uinfo->value.enumerated.items = 2;
602 if (uinfo->value.enumerated.item > 1)
603 uinfo->value.enumerated.item = 1;
604 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
605 return 0;
606}
607
608static int snd_audigy_i2c_capture_source_get(struct snd_kcontrol *kcontrol,
609 struct snd_ctl_elem_value *ucontrol)
610{
611 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
612
613 ucontrol->value.enumerated.item[0] = emu->i2c_capture_source;
614 return 0;
615}
616
617static int snd_audigy_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
618 struct snd_ctl_elem_value *ucontrol)
619{
620 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
621 unsigned int source_id;
622 unsigned int ngain, ogain;
623 u32 gpio;
624 int change = 0;
625 unsigned long flags;
626 u32 source;
627 /* If the capture source has changed,
628 * update the capture volume from the cached value
629 * for the particular source.
630 */
631 source_id = ucontrol->value.enumerated.item[0]; /* Use 2 and 3 */
632 change = (emu->i2c_capture_source != source_id);
633 if (change) {
634 snd_emu10k1_i2c_write(emu, ADC_MUX, 0); /* Mute input */
635 spin_lock_irqsave(&emu->emu_lock, flags);
636 gpio = inl(emu->port + A_IOCFG);
637 if (source_id==0)
638 outl(gpio | 0x4, emu->port + A_IOCFG);
639 else
640 outl(gpio & ~0x4, emu->port + A_IOCFG);
641 spin_unlock_irqrestore(&emu->emu_lock, flags);
642
643 ngain = emu->i2c_capture_volume[source_id][0]; /* Left */
644 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][0]; /* Left */
645 if (ngain != ogain)
646 snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff));
647 ngain = emu->i2c_capture_volume[source_id][1]; /* Right */
648 ogain = emu->i2c_capture_volume[emu->i2c_capture_source][1]; /* Right */
649 if (ngain != ogain)
650 snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
651
652 source = 1 << (source_id + 2);
653 snd_emu10k1_i2c_write(emu, ADC_MUX, source); /* Set source */
654 emu->i2c_capture_source = source_id;
655 }
656 return change;
657}
658
659static struct snd_kcontrol_new snd_audigy_i2c_capture_source =
660{
661 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
662 .name = "Capture Source",
663 .info = snd_audigy_i2c_capture_source_info,
664 .get = snd_audigy_i2c_capture_source_get,
665 .put = snd_audigy_i2c_capture_source_put
666};
667
668static int snd_audigy_i2c_volume_info(struct snd_kcontrol *kcontrol,
669 struct snd_ctl_elem_info *uinfo)
670{
671 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
672 uinfo->count = 2;
673 uinfo->value.integer.min = 0;
674 uinfo->value.integer.max = 255;
675 return 0;
676}
677
678static int snd_audigy_i2c_volume_get(struct snd_kcontrol *kcontrol,
679 struct snd_ctl_elem_value *ucontrol)
680{
681 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
682 int source_id;
683
684 source_id = kcontrol->private_value;
685
686 ucontrol->value.integer.value[0] = emu->i2c_capture_volume[source_id][0];
687 ucontrol->value.integer.value[1] = emu->i2c_capture_volume[source_id][1];
688 return 0;
689}
690
691static int snd_audigy_i2c_volume_put(struct snd_kcontrol *kcontrol,
692 struct snd_ctl_elem_value *ucontrol)
693{
694 struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
695 unsigned int ogain;
696 unsigned int ngain;
697 int source_id;
698 int change = 0;
699
700 source_id = kcontrol->private_value;
701 ogain = emu->i2c_capture_volume[source_id][0]; /* Left */
702 ngain = ucontrol->value.integer.value[0];
703 if (ngain > 0xff)
704 return 0;
705 if (ogain != ngain) {
706 if (emu->i2c_capture_source == source_id)
707 snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCL, ((ngain) & 0xff) );
708 emu->i2c_capture_volume[source_id][0] = ucontrol->value.integer.value[0];
709 change = 1;
710 }
711 ogain = emu->i2c_capture_volume[source_id][1]; /* Right */
712 ngain = ucontrol->value.integer.value[1];
713 if (ngain > 0xff)
714 return 0;
715 if (ogain != ngain) {
716 if (emu->i2c_capture_source == source_id)
717 snd_emu10k1_i2c_write(emu, ADC_ATTEN_ADCR, ((ngain) & 0xff));
718 emu->i2c_capture_volume[source_id][1] = ucontrol->value.integer.value[1];
719 change = 1;
720 }
721
722 return change;
723}
724
725#define I2C_VOLUME(xname,chid) \
726{ \
727 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
728 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
729 SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
730 .info = snd_audigy_i2c_volume_info, \
731 .get = snd_audigy_i2c_volume_get, \
732 .put = snd_audigy_i2c_volume_put, \
733 .tlv = { .p = snd_audigy_db_scale2 }, \
734 .private_value = chid \
735}
736
737
738static struct snd_kcontrol_new snd_audigy_i2c_volume_ctls[] __devinitdata = {
739 I2C_VOLUME("Mic Capture Volume", 0),
740 I2C_VOLUME("Line Capture Volume", 0)
741};
742
71#if 0 743#if 0
72static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 744static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
73{ 745{
@@ -668,7 +1340,9 @@ static int snd_emu10k1_shared_spdif_put(struct snd_kcontrol *kcontrol,
668 int change = 0; 1340 int change = 0;
669 1341
670 spin_lock_irqsave(&emu->reg_lock, flags); 1342 spin_lock_irqsave(&emu->reg_lock, flags);
671 if (emu->audigy) { 1343 if ( emu->card_capabilities->i2c_adc) {
1344 /* Do nothing for Audigy 2 ZS Notebook */
1345 } else if (emu->audigy) {
672 reg = inl(emu->port + A_IOCFG); 1346 reg = inl(emu->port + A_IOCFG);
673 val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0; 1347 val = ucontrol->value.integer.value[0] ? A_IOCFG_GPOUT0 : 0;
674 change = (reg & A_IOCFG_GPOUT0) != val; 1348 change = (reg & A_IOCFG_GPOUT0) != val;
@@ -806,6 +1480,24 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
806 "AMic Playback Volume", "Mic Playback Volume", 1480 "AMic Playback Volume", "Mic Playback Volume",
807 NULL 1481 NULL
808 }; 1482 };
1483 static char *audigy_rename_ctls_i2c_adc[] = {
1484 //"Analog Mix Capture Volume","OLD Analog Mix Capture Volume",
1485 "Line Capture Volume", "Analog Mix Capture Volume",
1486 "Wave Playback Volume", "OLD PCM Playback Volume",
1487 "Wave Master Playback Volume", "Master Playback Volume",
1488 "AMic Playback Volume", "Old Mic Playback Volume",
1489 "CD Capture Volume", "IEC958 Optical Capture Volume",
1490 NULL
1491 };
1492 static char *audigy_remove_ctls_i2c_adc[] = {
1493 /* On the Audigy2 ZS Notebook
1494 * Capture via WM8775 */
1495 "Mic Capture Volume",
1496 "Analog Mix Capture Volume",
1497 "Aux Capture Volume",
1498 "IEC958 Optical Capture Volume",
1499 NULL
1500 };
809 static char *audigy_remove_ctls_1361t_adc[] = { 1501 static char *audigy_remove_ctls_1361t_adc[] = {
810 /* On the Audigy2 the AC97 playback is piped into 1502 /* On the Audigy2 the AC97 playback is piped into
811 * the Philips ADC for 24bit capture */ 1503 * the Philips ADC for 24bit capture */
@@ -890,6 +1582,7 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
890 if (emu->ac97->id == AC97_ID_STAC9758) { 1582 if (emu->ac97->id == AC97_ID_STAC9758) {
891 emu->rear_ac97 = 1; 1583 emu->rear_ac97 = 1;
892 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT); 1584 snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT);
1585 snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202);
893 } 1586 }
894 /* remove unused AC97 controls */ 1587 /* remove unused AC97 controls */
895 snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202); 1588 snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202);
@@ -898,6 +1591,10 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
898 } 1591 }
899 for (; *c; c++) 1592 for (; *c; c++)
900 remove_ctl(card, *c); 1593 remove_ctl(card, *c);
1594 } else if (emu->card_capabilities->i2c_adc) {
1595 c = audigy_remove_ctls_i2c_adc;
1596 for (; *c; c++)
1597 remove_ctl(card, *c);
901 } else { 1598 } else {
902 no_ac97: 1599 no_ac97:
903 if (emu->card_capabilities->ecard) 1600 if (emu->card_capabilities->ecard)
@@ -911,6 +1608,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
911 if (emu->audigy) 1608 if (emu->audigy)
912 if (emu->card_capabilities->adc_1361t) 1609 if (emu->card_capabilities->adc_1361t)
913 c = audigy_rename_ctls_1361t_adc; 1610 c = audigy_rename_ctls_1361t_adc;
1611 else if (emu->card_capabilities->i2c_adc)
1612 c = audigy_rename_ctls_i2c_adc;
914 else 1613 else
915 c = audigy_rename_ctls; 1614 c = audigy_rename_ctls;
916 else 1615 else
@@ -1021,7 +1720,7 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1021 return err; 1720 return err;
1022 } 1721 }
1023 1722
1024 if ( emu->card_capabilities->emu1212m) { 1723 if ( emu->card_capabilities->emu1010) {
1025 ; /* Disable the snd_audigy_spdif_shared_spdif */ 1724 ; /* Disable the snd_audigy_spdif_shared_spdif */
1026 } else if (emu->audigy) { 1725 } else if (emu->audigy) {
1027 if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL) 1726 if ((kctl = snd_ctl_new1(&snd_audigy_shared_spdif, emu)) == NULL)
@@ -1045,6 +1744,48 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu,
1045 if ((err = snd_p16v_mixer(emu))) 1744 if ((err = snd_p16v_mixer(emu)))
1046 return err; 1745 return err;
1047 } 1746 }
1747
1748 if ( emu->card_capabilities->emu1010) {
1749 int i;
1750
1751 for (i = 0; i < ARRAY_SIZE(snd_emu1010_output_enum_ctls); i++) {
1752 err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_output_enum_ctls[i], emu));
1753 if (err < 0)
1754 return err;
1755 }
1756 for (i = 0; i < ARRAY_SIZE(snd_emu1010_input_enum_ctls); i++) {
1757 err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_input_enum_ctls[i], emu));
1758 if (err < 0)
1759 return err;
1760 }
1761 for (i = 0; i < ARRAY_SIZE(snd_emu1010_adc_pads); i++) {
1762 err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_adc_pads[i], emu));
1763 if (err < 0)
1764 return err;
1765 }
1766 for (i = 0; i < ARRAY_SIZE(snd_emu1010_dac_pads); i++) {
1767 err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_dac_pads[i], emu));
1768 if (err < 0)
1769 return err;
1770 }
1771 err = snd_ctl_add(card, snd_ctl_new1(&snd_emu1010_internal_clock, emu));
1772 if (err < 0)
1773 return err;
1774 }
1775
1776 if ( emu->card_capabilities->i2c_adc) {
1777 int i;
1778
1779 err = snd_ctl_add(card, snd_ctl_new1(&snd_audigy_i2c_capture_source, emu));
1780 if (err < 0)
1781 return err;
1782
1783 for (i = 0; i < ARRAY_SIZE(snd_audigy_i2c_volume_ctls); i++) {
1784 err = snd_ctl_add(card, snd_ctl_new1(&snd_audigy_i2c_volume_ctls[i], emu));
1785 if (err < 0)
1786 return err;
1787 }
1788 }
1048 1789
1049 return 0; 1790 return 0;
1050} 1791}
diff --git a/sound/pci/emu10k1/emupcm.c b/sound/pci/emu10k1/emupcm.c
index 717e92ec9e0a..ab4f5df5241b 100644
--- a/sound/pci/emu10k1/emupcm.c
+++ b/sound/pci/emu10k1/emupcm.c
@@ -147,7 +147,7 @@ static int snd_emu10k1_pcm_channel_alloc(struct snd_emu10k1_pcm * epcm, int voic
147 1, 147 1,
148 &epcm->extra); 148 &epcm->extra);
149 if (err < 0) { 149 if (err < 0) {
150 // printk("pcm_channel_alloc: failed extra: voices=%d, frame=%d\n", voices, frame); 150 /* printk("pcm_channel_alloc: failed extra: voices=%d, frame=%d\n", voices, frame); */
151 for (i = 0; i < voices; i++) { 151 for (i = 0; i < voices; i++) {
152 snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]); 152 snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
153 epcm->voices[i] = NULL; 153 epcm->voices[i] = NULL;
@@ -339,7 +339,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
339 } 339 }
340 } 340 }
341 341
342 // setup routing 342 /* setup routing */
343 if (emu->audigy) { 343 if (emu->audigy) {
344 snd_emu10k1_ptr_write(emu, A_FXRT1, voice, 344 snd_emu10k1_ptr_write(emu, A_FXRT1, voice,
345 snd_emu10k1_compose_audigy_fxrt1(send_routing)); 345 snd_emu10k1_compose_audigy_fxrt1(send_routing));
@@ -353,12 +353,15 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
353 } else 353 } else
354 snd_emu10k1_ptr_write(emu, FXRT, voice, 354 snd_emu10k1_ptr_write(emu, FXRT, voice,
355 snd_emu10k1_compose_send_routing(send_routing)); 355 snd_emu10k1_compose_send_routing(send_routing));
356 // Stop CA 356 /* Stop CA */
357 // Assumption that PT is already 0 so no harm overwriting 357 /* Assumption that PT is already 0 so no harm overwriting */
358 snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]); 358 snd_emu10k1_ptr_write(emu, PTRX, voice, (send_amount[0] << 8) | send_amount[1]);
359 snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24)); 359 snd_emu10k1_ptr_write(emu, DSL, voice, end_addr | (send_amount[3] << 24));
360 snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24)); 360 snd_emu10k1_ptr_write(emu, PSST, voice, start_addr | (send_amount[2] << 24));
361 pitch_target = emu10k1_calc_pitch_target(runtime->rate); 361 if (emu->card_capabilities->emu1010)
362 pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */
363 else
364 pitch_target = emu10k1_calc_pitch_target(runtime->rate);
362 if (extra) 365 if (extra)
363 snd_emu10k1_ptr_write(emu, CCCA, voice, start_addr | 366 snd_emu10k1_ptr_write(emu, CCCA, voice, start_addr |
364 emu10k1_select_interprom(pitch_target) | 367 emu10k1_select_interprom(pitch_target) |
@@ -367,14 +370,14 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
367 snd_emu10k1_ptr_write(emu, CCCA, voice, (start_addr + ccis) | 370 snd_emu10k1_ptr_write(emu, CCCA, voice, (start_addr + ccis) |
368 emu10k1_select_interprom(pitch_target) | 371 emu10k1_select_interprom(pitch_target) |
369 (w_16 ? 0 : CCCA_8BITSELECT)); 372 (w_16 ? 0 : CCCA_8BITSELECT));
370 // Clear filter delay memory 373 /* Clear filter delay memory */
371 snd_emu10k1_ptr_write(emu, Z1, voice, 0); 374 snd_emu10k1_ptr_write(emu, Z1, voice, 0);
372 snd_emu10k1_ptr_write(emu, Z2, voice, 0); 375 snd_emu10k1_ptr_write(emu, Z2, voice, 0);
373 // invalidate maps 376 /* invalidate maps */
374 silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK; 377 silent_page = ((unsigned int)emu->silent_page.addr << 1) | MAP_PTI_MASK;
375 snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page); 378 snd_emu10k1_ptr_write(emu, MAPA, voice, silent_page);
376 snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page); 379 snd_emu10k1_ptr_write(emu, MAPB, voice, silent_page);
377 // modulation envelope 380 /* modulation envelope */
378 snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff); 381 snd_emu10k1_ptr_write(emu, CVCF, voice, 0xffff);
379 snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff); 382 snd_emu10k1_ptr_write(emu, VTFT, voice, 0xffff);
380 snd_emu10k1_ptr_write(emu, ATKHLDM, voice, 0); 383 snd_emu10k1_ptr_write(emu, ATKHLDM, voice, 0);
@@ -385,12 +388,12 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
385 snd_emu10k1_ptr_write(emu, TREMFRQ, voice, 0); 388 snd_emu10k1_ptr_write(emu, TREMFRQ, voice, 0);
386 snd_emu10k1_ptr_write(emu, FM2FRQ2, voice, 0); 389 snd_emu10k1_ptr_write(emu, FM2FRQ2, voice, 0);
387 snd_emu10k1_ptr_write(emu, ENVVAL, voice, 0x8000); 390 snd_emu10k1_ptr_write(emu, ENVVAL, voice, 0x8000);
388 // volume envelope 391 /* volume envelope */
389 snd_emu10k1_ptr_write(emu, ATKHLDV, voice, 0x7f7f); 392 snd_emu10k1_ptr_write(emu, ATKHLDV, voice, 0x7f7f);
390 snd_emu10k1_ptr_write(emu, ENVVOL, voice, 0x0000); 393 snd_emu10k1_ptr_write(emu, ENVVOL, voice, 0x0000);
391 // filter envelope 394 /* filter envelope */
392 snd_emu10k1_ptr_write(emu, PEFE_FILTERAMOUNT, voice, 0x7f); 395 snd_emu10k1_ptr_write(emu, PEFE_FILTERAMOUNT, voice, 0x7f);
393 // pitch envelope 396 /* pitch envelope */
394 snd_emu10k1_ptr_write(emu, PEFE_PITCHAMOUNT, voice, 0); 397 snd_emu10k1_ptr_write(emu, PEFE_PITCHAMOUNT, voice, 0);
395 398
396 spin_unlock_irqrestore(&emu->reg_lock, flags); 399 spin_unlock_irqrestore(&emu->reg_lock, flags);
@@ -468,7 +471,7 @@ static int snd_emu10k1_efx_playback_hw_free(struct snd_pcm_substream *substream)
468 snd_emu10k1_voice_free(epcm->emu, epcm->extra); 471 snd_emu10k1_voice_free(epcm->emu, epcm->extra);
469 epcm->extra = NULL; 472 epcm->extra = NULL;
470 } 473 }
471 for (i=0; i < NUM_EFX_PLAYBACK; i++) { 474 for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
472 if (epcm->voices[i]) { 475 if (epcm->voices[i]) {
473 snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]); 476 snd_emu10k1_voice_free(epcm->emu, epcm->voices[i]);
474 epcm->voices[i] = NULL; 477 epcm->voices[i] = NULL;
@@ -637,7 +640,7 @@ static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int e
637 stereo = (!extra && runtime->channels == 2); 640 stereo = (!extra && runtime->channels == 2);
638 sample = snd_pcm_format_width(runtime->format) == 16 ? 0 : 0x80808080; 641 sample = snd_pcm_format_width(runtime->format) == 16 ? 0 : 0x80808080;
639 ccis = emu10k1_ccis(stereo, sample == 0); 642 ccis = emu10k1_ccis(stereo, sample == 0);
640 // set cs to 2 * number of cache registers beside the invalidated 643 /* set cs to 2 * number of cache registers beside the invalidated */
641 cs = (sample == 0) ? (32-ccis) : (64-ccis+1) >> 1; 644 cs = (sample == 0) ? (32-ccis) : (64-ccis+1) >> 1;
642 if (cs > 16) cs = 16; 645 if (cs > 16) cs = 16;
643 for (i = 0; i < cs; i++) { 646 for (i = 0; i < cs; i++) {
@@ -646,14 +649,14 @@ static void snd_emu10k1_playback_invalidate_cache(struct snd_emu10k1 *emu, int e
646 snd_emu10k1_ptr_write(emu, CD0 + i, voice + 1, sample); 649 snd_emu10k1_ptr_write(emu, CD0 + i, voice + 1, sample);
647 } 650 }
648 } 651 }
649 // reset cache 652 /* reset cache */
650 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, 0); 653 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, 0);
651 snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice, cra); 654 snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice, cra);
652 if (stereo) { 655 if (stereo) {
653 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice + 1, 0); 656 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice + 1, 0);
654 snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice + 1, cra); 657 snd_emu10k1_ptr_write(emu, CCR_READADDRESS, voice + 1, cra);
655 } 658 }
656 // fill cache 659 /* fill cache */
657 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, ccis); 660 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice, ccis);
658 if (stereo) { 661 if (stereo) {
659 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice+1, ccis); 662 snd_emu10k1_ptr_write(emu, CCR_CACHEINVALIDSIZE, voice+1, ccis);
@@ -698,7 +701,10 @@ static void snd_emu10k1_playback_trigger_voice(struct snd_emu10k1 *emu, struct s
698 voice = evoice->number; 701 voice = evoice->number;
699 702
700 pitch = snd_emu10k1_rate_to_pitch(runtime->rate) >> 8; 703 pitch = snd_emu10k1_rate_to_pitch(runtime->rate) >> 8;
701 pitch_target = emu10k1_calc_pitch_target(runtime->rate); 704 if (emu->card_capabilities->emu1010)
705 pitch_target = PITCH_48000; /* Disable interpolators on emu1010 card */
706 else
707 pitch_target = emu10k1_calc_pitch_target(runtime->rate);
702 snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, pitch_target); 708 snd_emu10k1_ptr_write(emu, PTRX_PITCHTARGET, voice, pitch_target);
703 if (master || evoice->epcm->type == PLAYBACK_EFX) 709 if (master || evoice->epcm->type == PLAYBACK_EFX)
704 snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target); 710 snd_emu10k1_ptr_write(emu, CPF_CURRENTPITCH, voice, pitch_target);
@@ -732,7 +738,7 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
732 struct snd_emu10k1_pcm_mixer *mix; 738 struct snd_emu10k1_pcm_mixer *mix;
733 int result = 0; 739 int result = 0;
734 740
735 // printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream)); 741 /* printk("trigger - emu10k1 = 0x%x, cmd = %i, pointer = %i\n", (int)emu, cmd, substream->ops->pointer(substream)); */
736 spin_lock(&emu->reg_lock); 742 spin_lock(&emu->reg_lock);
737 switch (cmd) { 743 switch (cmd) {
738 case SNDRV_PCM_TRIGGER_START: 744 case SNDRV_PCM_TRIGGER_START:
@@ -778,10 +784,10 @@ static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream,
778 switch (cmd) { 784 switch (cmd) {
779 case SNDRV_PCM_TRIGGER_START: 785 case SNDRV_PCM_TRIGGER_START:
780 case SNDRV_PCM_TRIGGER_RESUME: 786 case SNDRV_PCM_TRIGGER_RESUME:
781 // hmm this should cause full and half full interrupt to be raised? 787 /* hmm this should cause full and half full interrupt to be raised? */
782 outl(epcm->capture_ipr, emu->port + IPR); 788 outl(epcm->capture_ipr, emu->port + IPR);
783 snd_emu10k1_intr_enable(emu, epcm->capture_inte); 789 snd_emu10k1_intr_enable(emu, epcm->capture_inte);
784 // printk("adccr = 0x%x, adcbs = 0x%x\n", epcm->adccr, epcm->adcbs); 790 /* printk("adccr = 0x%x, adcbs = 0x%x\n", epcm->adccr, epcm->adcbs); */
785 switch (epcm->type) { 791 switch (epcm->type) {
786 case CAPTURE_AC97ADC: 792 case CAPTURE_AC97ADC:
787 snd_emu10k1_ptr_write(emu, ADCCR, 0, epcm->capture_cr_val); 793 snd_emu10k1_ptr_write(emu, ADCCR, 0, epcm->capture_cr_val);
@@ -790,6 +796,7 @@ static int snd_emu10k1_capture_trigger(struct snd_pcm_substream *substream,
790 if (emu->audigy) { 796 if (emu->audigy) {
791 snd_emu10k1_ptr_write(emu, A_FXWC1, 0, epcm->capture_cr_val); 797 snd_emu10k1_ptr_write(emu, A_FXWC1, 0, epcm->capture_cr_val);
792 snd_emu10k1_ptr_write(emu, A_FXWC2, 0, epcm->capture_cr_val2); 798 snd_emu10k1_ptr_write(emu, A_FXWC2, 0, epcm->capture_cr_val2);
799 snd_printdd("cr_val=0x%x, cr_val2=0x%x\n", epcm->capture_cr_val, epcm->capture_cr_val2);
793 } else 800 } else
794 snd_emu10k1_ptr_write(emu, FXWC, 0, epcm->capture_cr_val); 801 snd_emu10k1_ptr_write(emu, FXWC, 0, epcm->capture_cr_val);
795 break; 802 break;
@@ -851,7 +858,7 @@ static snd_pcm_uframes_t snd_emu10k1_playback_pointer(struct snd_pcm_substream *
851 ptr -= runtime->buffer_size; 858 ptr -= runtime->buffer_size;
852 } 859 }
853#endif 860#endif
854 // printk("ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", ptr, runtime->buffer_size, runtime->period_size); 861 /* printk("ptr = 0x%x, buffer_size = 0x%x, period_size = 0x%x\n", ptr, runtime->buffer_size, runtime->period_size); */
855 return ptr; 862 return ptr;
856} 863}
857 864
@@ -868,7 +875,7 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream,
868 spin_lock(&emu->reg_lock); 875 spin_lock(&emu->reg_lock);
869 switch (cmd) { 876 switch (cmd) {
870 case SNDRV_PCM_TRIGGER_START: 877 case SNDRV_PCM_TRIGGER_START:
871 // prepare voices 878 /* prepare voices */
872 for (i = 0; i < NUM_EFX_PLAYBACK; i++) { 879 for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
873 snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[i]); 880 snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[i]);
874 } 881 }
@@ -917,7 +924,7 @@ static snd_pcm_uframes_t snd_emu10k1_capture_pointer(struct snd_pcm_substream *s
917 if (!epcm->running) 924 if (!epcm->running)
918 return 0; 925 return 0;
919 if (epcm->first_ptr) { 926 if (epcm->first_ptr) {
920 udelay(50); // hack, it takes awhile until capture is started 927 udelay(50); /* hack, it takes awhile until capture is started */
921 epcm->first_ptr = 0; 928 epcm->first_ptr = 0;
922 } 929 }
923 ptr = snd_emu10k1_ptr_read(emu, epcm->capture_idx_reg, 0) & 0x0000ffff; 930 ptr = snd_emu10k1_ptr_read(emu, epcm->capture_idx_reg, 0) & 0x0000ffff;
@@ -972,6 +979,28 @@ static struct snd_pcm_hardware snd_emu10k1_capture =
972 .fifo_size = 0, 979 .fifo_size = 0,
973}; 980};
974 981
982static struct snd_pcm_hardware snd_emu10k1_capture_efx =
983{
984 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
985 SNDRV_PCM_INFO_BLOCK_TRANSFER |
986 SNDRV_PCM_INFO_RESUME |
987 SNDRV_PCM_INFO_MMAP_VALID),
988 .formats = SNDRV_PCM_FMTBIT_S16_LE,
989 .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
990 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
991 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
992 .rate_min = 44100,
993 .rate_max = 192000,
994 .channels_min = 8,
995 .channels_max = 8,
996 .buffer_bytes_max = (64*1024),
997 .period_bytes_min = 384,
998 .period_bytes_max = (64*1024),
999 .periods_min = 2,
1000 .periods_max = 2,
1001 .fifo_size = 0,
1002};
1003
975/* 1004/*
976 * 1005 *
977 */ 1006 */
@@ -1016,7 +1045,7 @@ static int snd_emu10k1_efx_playback_close(struct snd_pcm_substream *substream)
1016 struct snd_emu10k1_pcm_mixer *mix; 1045 struct snd_emu10k1_pcm_mixer *mix;
1017 int i; 1046 int i;
1018 1047
1019 for (i=0; i < NUM_EFX_PLAYBACK; i++) { 1048 for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
1020 mix = &emu->efx_pcm_mixer[i]; 1049 mix = &emu->efx_pcm_mixer[i];
1021 mix->epcm = NULL; 1050 mix->epcm = NULL;
1022 snd_emu10k1_pcm_efx_mixer_notify(emu, i, 0); 1051 snd_emu10k1_pcm_efx_mixer_notify(emu, i, 0);
@@ -1045,7 +1074,7 @@ static int snd_emu10k1_efx_playback_open(struct snd_pcm_substream *substream)
1045 runtime->private_free = snd_emu10k1_pcm_free_substream; 1074 runtime->private_free = snd_emu10k1_pcm_free_substream;
1046 runtime->hw = snd_emu10k1_efx_playback; 1075 runtime->hw = snd_emu10k1_efx_playback;
1047 1076
1048 for (i=0; i < NUM_EFX_PLAYBACK; i++) { 1077 for (i = 0; i < NUM_EFX_PLAYBACK; i++) {
1049 mix = &emu->efx_pcm_mixer[i]; 1078 mix = &emu->efx_pcm_mixer[i];
1050 mix->send_routing[0][0] = i; 1079 mix->send_routing[0][0] = i;
1051 memset(&mix->send_volume, 0, sizeof(mix->send_volume)); 1080 memset(&mix->send_volume, 0, sizeof(mix->send_volume));
@@ -1199,15 +1228,69 @@ static int snd_emu10k1_capture_efx_open(struct snd_pcm_substream *substream)
1199 epcm->capture_idx_reg = FXIDX; 1228 epcm->capture_idx_reg = FXIDX;
1200 substream->runtime->private_data = epcm; 1229 substream->runtime->private_data = epcm;
1201 substream->runtime->private_free = snd_emu10k1_pcm_free_substream; 1230 substream->runtime->private_free = snd_emu10k1_pcm_free_substream;
1202 runtime->hw = snd_emu10k1_capture; 1231 runtime->hw = snd_emu10k1_capture_efx;
1203 runtime->hw.rates = SNDRV_PCM_RATE_48000; 1232 runtime->hw.rates = SNDRV_PCM_RATE_48000;
1204 runtime->hw.rate_min = runtime->hw.rate_max = 48000; 1233 runtime->hw.rate_min = runtime->hw.rate_max = 48000;
1205 spin_lock_irq(&emu->reg_lock); 1234 spin_lock_irq(&emu->reg_lock);
1206 runtime->hw.channels_min = runtime->hw.channels_max = 0; 1235 if (emu->card_capabilities->emu1010) {
1207 for (idx = 0; idx < nefx; idx++) { 1236 /* TODO
1208 if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) { 1237 * SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE
1209 runtime->hw.channels_min++; 1238 * SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
1210 runtime->hw.channels_max++; 1239 * SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
1240 * SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000
1241 * rate_min = 44100,
1242 * rate_max = 192000,
1243 * channels_min = 8,
1244 * channels_max = 8,
1245 * Need to add mixer control to fix sample rate
1246 *
1247 * There are 16 mono channels of 16bits each.
1248 * 24bit Audio uses 2x channels over 16bit
1249 * 96kHz uses 2x channels over 48kHz
1250 * 192kHz uses 4x channels over 48kHz
1251 * So, for 48kHz 24bit, one has 8 channels
1252 * for 96kHz 24bit, one has 4 channels
1253 * for 192kHz 24bit, one has 2 channels
1254 */
1255#if 1
1256 switch (emu->emu1010.internal_clock) {
1257 case 0:
1258 /* For 44.1kHz */
1259 runtime->hw.rates = SNDRV_PCM_RATE_44100;
1260 runtime->hw.rate_min = runtime->hw.rate_max = 44100;
1261 runtime->hw.channels_min = runtime->hw.channels_max = 8;
1262 break;
1263 case 1:
1264 /* For 48kHz */
1265 runtime->hw.rates = SNDRV_PCM_RATE_48000;
1266 runtime->hw.rate_min = runtime->hw.rate_max = 48000;
1267 runtime->hw.channels_min = runtime->hw.channels_max = 8;
1268 break;
1269 };
1270#endif
1271#if 0
1272 /* For 96kHz */
1273 runtime->hw.rates = SNDRV_PCM_RATE_96000;
1274 runtime->hw.rate_min = runtime->hw.rate_max = 96000;
1275 runtime->hw.channels_min = runtime->hw.channels_max = 4;
1276#endif
1277#if 0
1278 /* For 192kHz */
1279 runtime->hw.rates = SNDRV_PCM_RATE_192000;
1280 runtime->hw.rate_min = runtime->hw.rate_max = 192000;
1281 runtime->hw.channels_min = runtime->hw.channels_max = 2;
1282#endif
1283 runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE;
1284 /* efx_voices_mask[0] is expected to be zero
1285 * efx_voices_mask[1] is expected to have 16bits set
1286 */
1287 } else {
1288 runtime->hw.channels_min = runtime->hw.channels_max = 0;
1289 for (idx = 0; idx < nefx; idx++) {
1290 if (emu->efx_voices_mask[idx/32] & (1 << (idx%32))) {
1291 runtime->hw.channels_min++;
1292 runtime->hw.channels_max++;
1293 }
1211 } 1294 }
1212 } 1295 }
1213 epcm->capture_cr_val = emu->efx_voices_mask[0]; 1296 epcm->capture_cr_val = emu->efx_voices_mask[0];
@@ -1460,7 +1543,7 @@ static void snd_emu10k1_fx8010_playback_tram_poke1(unsigned short *dst_left,
1460 unsigned int count, 1543 unsigned int count,
1461 unsigned int tram_shift) 1544 unsigned int tram_shift)
1462{ 1545{
1463 // printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count); 1546 /* printk("tram_poke1: dst_left = 0x%p, dst_right = 0x%p, src = 0x%p, count = 0x%x\n", dst_left, dst_right, src, count); */
1464 if ((tram_shift & 1) == 0) { 1547 if ((tram_shift & 1) == 0) {
1465 while (count--) { 1548 while (count--) {
1466 *dst_left-- = *src++; 1549 *dst_left-- = *src++;
@@ -1537,7 +1620,7 @@ static int snd_emu10k1_fx8010_playback_prepare(struct snd_pcm_substream *substre
1537 struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number]; 1620 struct snd_emu10k1_fx8010_pcm *pcm = &emu->fx8010.pcm[substream->number];
1538 unsigned int i; 1621 unsigned int i;
1539 1622
1540 // printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2); 1623 /* printk("prepare: etram_pages = 0x%p, dma_area = 0x%x, buffer_size = 0x%x (0x%x)\n", emu->fx8010.etram_pages, runtime->dma_area, runtime->buffer_size, runtime->buffer_size << 2); */
1541 memset(&pcm->pcm_rec, 0, sizeof(pcm->pcm_rec)); 1624 memset(&pcm->pcm_rec, 0, sizeof(pcm->pcm_rec));
1542 pcm->pcm_rec.hw_buffer_size = pcm->buffer_size * 2; /* byte size */ 1625 pcm->pcm_rec.hw_buffer_size = pcm->buffer_size * 2; /* byte size */
1543 pcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream); 1626 pcm->pcm_rec.sw_buffer_size = snd_pcm_lib_buffer_bytes(substream);
diff --git a/sound/pci/emu10k1/emuproc.c b/sound/pci/emu10k1/emuproc.c
index b939e03aaedf..2c1585991bc8 100644
--- a/sound/pci/emu10k1/emuproc.c
+++ b/sound/pci/emu10k1/emuproc.c
@@ -3,6 +3,9 @@
3 * Creative Labs, Inc. 3 * Creative Labs, Inc.
4 * Routines for control of EMU10K1 chips / proc interface routines 4 * Routines for control of EMU10K1 chips / proc interface routines
5 * 5 *
6 * Copyright (c) by James Courtier-Dutton <James@superbug.co.uk>
7 * Added EMU 1010 support.
8 *
6 * BUGS: 9 * BUGS:
7 * -- 10 * --
8 * 11 *
@@ -255,7 +258,7 @@ static void snd_emu10k1_proc_rates_read(struct snd_info_entry *entry,
255 unsigned int val, tmp, n; 258 unsigned int val, tmp, n;
256 val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0); 259 val = snd_emu10k1_ptr20_read(emu, CAPTURE_RATE_STATUS, 0);
257 tmp = (val >> 16) & 0x8; 260 tmp = (val >> 16) & 0x8;
258 for (n=0;n<4;n++) { 261 for (n = 0; n < 4; n++) {
259 tmp = val >> (16 + (n*4)); 262 tmp = val >> (16 + (n*4));
260 if (tmp & 0x8) snd_iprintf(buffer, "Channel %d: Rate=%d\n", n, samplerate[tmp & 0x7]); 263 if (tmp & 0x8) snd_iprintf(buffer, "Channel %d: Rate=%d\n", n, samplerate[tmp & 0x7]);
261 else snd_iprintf(buffer, "Channel %d: No input\n", n); 264 else snd_iprintf(buffer, "Channel %d: No input\n", n);
@@ -372,6 +375,27 @@ static void snd_emu10k1_proc_voices_read(struct snd_info_entry *entry,
372} 375}
373 376
374#ifdef CONFIG_SND_DEBUG 377#ifdef CONFIG_SND_DEBUG
378static void snd_emu_proc_emu1010_reg_read(struct snd_info_entry *entry,
379 struct snd_info_buffer *buffer)
380{
381 struct snd_emu10k1 *emu = entry->private_data;
382 unsigned long value;
383 unsigned long flags;
384 unsigned long regs;
385 int i;
386 snd_iprintf(buffer, "EMU1010 Registers:\n\n");
387
388 for(i = 0; i < 0x30; i+=1) {
389 spin_lock_irqsave(&emu->emu_lock, flags);
390 regs=i+0x40; /* 0x40 upwards are registers. */
391 outl(regs, emu->port + A_IOCFG);
392 outl(regs | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
393 value = inl(emu->port + A_IOCFG);
394 spin_unlock_irqrestore(&emu->emu_lock, flags);
395 snd_iprintf(buffer, "%02X: %08lX, %02lX\n", i, value, (value >> 8) & 0x7f);
396 }
397}
398
375static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry, 399static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry,
376 struct snd_info_buffer *buffer) 400 struct snd_info_buffer *buffer)
377{ 401{
@@ -398,7 +422,7 @@ static void snd_emu_proc_io_reg_write(struct snd_info_entry *entry,
398 while (!snd_info_get_line(buffer, line, sizeof(line))) { 422 while (!snd_info_get_line(buffer, line, sizeof(line))) {
399 if (sscanf(line, "%x %x", &reg, &val) != 2) 423 if (sscanf(line, "%x %x", &reg, &val) != 2)
400 continue; 424 continue;
401 if ((reg < 0x40) && (reg >=0) && (val <= 0xffffffff) ) { 425 if ((reg < 0x40) && (reg >= 0) && (val <= 0xffffffff) ) {
402 spin_lock_irqsave(&emu->emu_lock, flags); 426 spin_lock_irqsave(&emu->emu_lock, flags);
403 outl(val, emu->port + (reg & 0xfffffffc)); 427 outl(val, emu->port + (reg & 0xfffffffc));
404 spin_unlock_irqrestore(&emu->emu_lock, flags); 428 spin_unlock_irqrestore(&emu->emu_lock, flags);
@@ -474,7 +498,7 @@ static void snd_emu_proc_ptr_reg_write(struct snd_info_entry *entry,
474 while (!snd_info_get_line(buffer, line, sizeof(line))) { 498 while (!snd_info_get_line(buffer, line, sizeof(line))) {
475 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3) 499 if (sscanf(line, "%x %x %x", &reg, &channel_id, &val) != 3)
476 continue; 500 continue;
477 if ((reg < 0xa0) && (reg >=0) && (val <= 0xffffffff) && (channel_id >=0) && (channel_id <= 3) ) 501 if ((reg < 0xa0) && (reg >= 0) && (val <= 0xffffffff) && (channel_id >= 0) && (channel_id <= 3) )
478 snd_ptr_write(emu, iobase, reg, channel_id, val); 502 snd_ptr_write(emu, iobase, reg, channel_id, val);
479 } 503 }
480} 504}
@@ -531,6 +555,10 @@ int __devinit snd_emu10k1_proc_init(struct snd_emu10k1 * emu)
531{ 555{
532 struct snd_info_entry *entry; 556 struct snd_info_entry *entry;
533#ifdef CONFIG_SND_DEBUG 557#ifdef CONFIG_SND_DEBUG
558 if ((emu->card_capabilities->emu1010) &&
559 snd_card_proc_new(emu->card, "emu1010_regs", &entry)) {
560 snd_info_set_text_ops(entry, emu, snd_emu_proc_emu1010_reg_read);
561 }
534 if (! snd_card_proc_new(emu->card, "io_regs", &entry)) { 562 if (! snd_card_proc_new(emu->card, "io_regs", &entry)) {
535 snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read); 563 snd_info_set_text_ops(entry, emu, snd_emu_proc_io_reg_read);
536 entry->c.text.write = snd_emu_proc_io_reg_write; 564 entry->c.text.write = snd_emu_proc_io_reg_write;
diff --git a/sound/pci/emu10k1/io.c b/sound/pci/emu10k1/io.c
index 029e7856c43b..116e1c8d9361 100644
--- a/sound/pci/emu10k1/io.c
+++ b/sound/pci/emu10k1/io.c
@@ -30,6 +30,7 @@
30#include <sound/core.h> 30#include <sound/core.h>
31#include <sound/emu10k1.h> 31#include <sound/emu10k1.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include "p17v.h"
33 34
34unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn) 35unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn)
35{ 36{
@@ -167,6 +168,109 @@ int snd_emu10k1_spi_write(struct snd_emu10k1 * emu,
167 return 0; 168 return 0;
168} 169}
169 170
171/* The ADC does not support i2c read, so only write is implemented */
172int snd_emu10k1_i2c_write(struct snd_emu10k1 *emu,
173 u32 reg,
174 u32 value)
175{
176 u32 tmp;
177 int timeout = 0;
178 int status;
179 int retry;
180 if ((reg > 0x7f) || (value > 0x1ff)) {
181 snd_printk(KERN_ERR "i2c_write: invalid values.\n");
182 return -EINVAL;
183 }
184
185 tmp = reg << 25 | value << 16;
186 // snd_printk("I2C-write:reg=0x%x, value=0x%x\n", reg, value);
187 /* Not sure what this I2C channel controls. */
188 /* snd_emu10k1_ptr_write(emu, P17V_I2C_0, 0, tmp); */
189
190 /* This controls the I2C connected to the WM8775 ADC Codec */
191 snd_emu10k1_ptr20_write(emu, P17V_I2C_1, 0, tmp);
192 tmp = snd_emu10k1_ptr20_read(emu, P17V_I2C_1, 0); /* write post */
193
194 for (retry = 0; retry < 10; retry++) {
195 /* Send the data to i2c */
196 //tmp = snd_emu10k1_ptr_read(emu, P17V_I2C_ADDR, 0);
197 //tmp = tmp & ~(I2C_A_ADC_READ|I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD_MASK);
198 tmp = 0;
199 tmp = tmp | (I2C_A_ADC_LAST|I2C_A_ADC_START|I2C_A_ADC_ADD);
200 snd_emu10k1_ptr20_write(emu, P17V_I2C_ADDR, 0, tmp);
201
202 /* Wait till the transaction ends */
203 while (1) {
204 udelay(10);
205 status = snd_emu10k1_ptr20_read(emu, P17V_I2C_ADDR, 0);
206 // snd_printk("I2C:status=0x%x\n", status);
207 timeout++;
208 if ((status & I2C_A_ADC_START) == 0)
209 break;
210
211 if (timeout > 1000) {
212 snd_printk("emu10k1:I2C:timeout status=0x%x\n", status);
213 break;
214 }
215 }
216 //Read back and see if the transaction is successful
217 if ((status & I2C_A_ADC_ABORT) == 0)
218 break;
219 }
220
221 if (retry == 10) {
222 snd_printk(KERN_ERR "Writing to ADC failed!\n");
223 return -EINVAL;
224 }
225
226 return 0;
227}
228
229int snd_emu1010_fpga_write(struct snd_emu10k1 * emu, int reg, int value)
230{
231 if (reg < 0 || reg > 0x3f)
232 return 1;
233 reg += 0x40; /* 0x40 upwards are registers. */
234 if (value < 0 || value > 0x3f) /* 0 to 0x3f are values */
235 return 1;
236 outl(reg, emu->port + A_IOCFG);
237 udelay(10);
238 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
239 udelay(10);
240 outl(value, emu->port + A_IOCFG);
241 udelay(10);
242 outl(value | 0x80 , emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
243
244 return 0;
245}
246
247int snd_emu1010_fpga_read(struct snd_emu10k1 * emu, int reg, int *value)
248{
249 if (reg < 0 || reg > 0x3f)
250 return 1;
251 reg += 0x40; /* 0x40 upwards are registers. */
252 outl(reg, emu->port + A_IOCFG);
253 udelay(10);
254 outl(reg | 0x80, emu->port + A_IOCFG); /* High bit clocks the value into the fpga. */
255 udelay(10);
256 *value = ((inl(emu->port + A_IOCFG) >> 8) & 0x7f);
257
258 return 0;
259}
260
261/* Each Destination has one and only one Source,
262 * but one Source can feed any number of Destinations simultaneously.
263 */
264int snd_emu1010_fpga_link_dst_src_write(struct snd_emu10k1 * emu, int dst, int src)
265{
266 snd_emu1010_fpga_write(emu, 0x00, ((dst >> 8) & 0x3f) );
267 snd_emu1010_fpga_write(emu, 0x01, (dst & 0x3f) );
268 snd_emu1010_fpga_write(emu, 0x02, ((src >> 8) & 0x3f) );
269 snd_emu1010_fpga_write(emu, 0x03, (src & 0x3f) );
270
271 return 0;
272}
273
170void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb) 274void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb)
171{ 275{
172 unsigned long flags; 276 unsigned long flags;
diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c
index 4e0f95438f47..465f8d505329 100644
--- a/sound/pci/emu10k1/p16v.c
+++ b/sound/pci/emu10k1/p16v.c
@@ -253,7 +253,7 @@ static int snd_p16v_pcm_close_playback(struct snd_pcm_substream *substream)
253 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); 253 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
254 //struct snd_pcm_runtime *runtime = substream->runtime; 254 //struct snd_pcm_runtime *runtime = substream->runtime;
255 //struct snd_emu10k1_pcm *epcm = runtime->private_data; 255 //struct snd_emu10k1_pcm *epcm = runtime->private_data;
256 emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use=0; 256 emu->p16v_voices[substream->pcm->device - emu->p16v_device_offset].use = 0;
257 /* FIXME: maybe zero others */ 257 /* FIXME: maybe zero others */
258 return 0; 258 return 0;
259} 259}
@@ -264,7 +264,7 @@ static int snd_p16v_pcm_close_capture(struct snd_pcm_substream *substream)
264 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream); 264 struct snd_emu10k1 *emu = snd_pcm_substream_chip(substream);
265 //struct snd_pcm_runtime *runtime = substream->runtime; 265 //struct snd_pcm_runtime *runtime = substream->runtime;
266 //struct snd_emu10k1_pcm *epcm = runtime->private_data; 266 //struct snd_emu10k1_pcm *epcm = runtime->private_data;
267 emu->p16v_capture_voice.use=0; 267 emu->p16v_capture_voice.use = 0;
268 /* FIXME: maybe zero others */ 268 /* FIXME: maybe zero others */
269 return 0; 269 return 0;
270} 270}
@@ -349,7 +349,7 @@ static int snd_p16v_pcm_prepare_playback(struct snd_pcm_substream *substream)
349 break; 349 break;
350 } 350 }
351 /* FIXME: Check emu->buffer.size before actually writing to it. */ 351 /* FIXME: Check emu->buffer.size before actually writing to it. */
352 for(i=0; i < runtime->periods; i++) { 352 for(i = 0; i < runtime->periods; i++) {
353 table_base[i*2]=runtime->dma_addr+(i*period_size_bytes); 353 table_base[i*2]=runtime->dma_addr+(i*period_size_bytes);
354 table_base[(i*2)+1]=period_size_bytes<<16; 354 table_base[(i*2)+1]=period_size_bytes<<16;
355 } 355 }
@@ -394,7 +394,7 @@ static int snd_p16v_pcm_prepare_capture(struct snd_pcm_substream *substream)
394 /* FIXME: Check emu->buffer.size before actually writing to it. */ 394 /* FIXME: Check emu->buffer.size before actually writing to it. */
395 snd_emu10k1_ptr20_write(emu, 0x13, channel, 0); 395 snd_emu10k1_ptr20_write(emu, 0x13, channel, 0);
396 snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr); 396 snd_emu10k1_ptr20_write(emu, CAPTURE_DMA_ADDR, channel, runtime->dma_addr);
397 snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size)<<16); // buffer size in bytes 397 snd_emu10k1_ptr20_write(emu, CAPTURE_BUFFER_SIZE, channel, frames_to_bytes(runtime, runtime->buffer_size) << 16); // buffer size in bytes
398 snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0); 398 snd_emu10k1_ptr20_write(emu, CAPTURE_POINTER, channel, 0);
399 //snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */ 399 //snd_emu10k1_ptr20_write(emu, CAPTURE_SOURCE, 0x0, 0x333300e4); /* Select MIC or Line in */
400 //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel)); 400 //snd_emu10k1_ptr20_write(emu, EXTENDED_INT_MASK, 0, snd_emu10k1_ptr20_read(emu, EXTENDED_INT_MASK, 0) | (0x110000<<channel));
@@ -437,7 +437,7 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
437 struct snd_pcm_substream *s; 437 struct snd_pcm_substream *s;
438 u32 basic = 0; 438 u32 basic = 0;
439 u32 inte = 0; 439 u32 inte = 0;
440 int running=0; 440 int running = 0;
441 441
442 switch (cmd) { 442 switch (cmd) {
443 case SNDRV_PCM_TRIGGER_START: 443 case SNDRV_PCM_TRIGGER_START:
@@ -445,7 +445,7 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream,
445 break; 445 break;
446 case SNDRV_PCM_TRIGGER_STOP: 446 case SNDRV_PCM_TRIGGER_STOP:
447 default: 447 default:
448 running=0; 448 running = 0;
449 break; 449 break;
450 } 450 }
451 snd_pcm_group_for_each(pos, substream) { 451 snd_pcm_group_for_each(pos, substream) {
@@ -785,7 +785,7 @@ static int snd_p16v_capture_channel_put(struct snd_kcontrol *kcontrol,
785 } 785 }
786 return change; 786 return change;
787} 787}
788static DECLARE_TLV_DB_SCALE(snd_p16v_db_scale1, -5175, 25, 1); 788static const DECLARE_TLV_DB_SCALE(snd_p16v_db_scale1, -5175, 25, 1);
789 789
790#define P16V_VOL(xname,xreg,xhl) { \ 790#define P16V_VOL(xname,xreg,xhl) { \
791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ 791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
diff --git a/sound/pci/emu10k1/p17v.h b/sound/pci/emu10k1/p17v.h
index 7ddb5be632cf..4ef5f68a9cd0 100644
--- a/sound/pci/emu10k1/p17v.h
+++ b/sound/pci/emu10k1/p17v.h
@@ -43,6 +43,53 @@
43#define P17V_I2C_ADDR 0x3d /* I2C Address */ 43#define P17V_I2C_ADDR 0x3d /* I2C Address */
44#define P17V_I2C_0 0x3e /* I2C Data */ 44#define P17V_I2C_0 0x3e /* I2C Data */
45#define P17V_I2C_1 0x3f /* I2C Data */ 45#define P17V_I2C_1 0x3f /* I2C Data */
46/* I2C values */
47#define I2C_A_ADC_ADD_MASK 0x000000fe /*The address is a 7 bit address */
48#define I2C_A_ADC_RW_MASK 0x00000001 /*bit mask for R/W */
49#define I2C_A_ADC_TRANS_MASK 0x00000010 /*Bit mask for I2c address DAC value */
50#define I2C_A_ADC_ABORT_MASK 0x00000020 /*Bit mask for I2C transaction abort flag */
51#define I2C_A_ADC_LAST_MASK 0x00000040 /*Bit mask for Last word transaction */
52#define I2C_A_ADC_BYTE_MASK 0x00000080 /*Bit mask for Byte Mode */
53
54#define I2C_A_ADC_ADD 0x00000034 /*This is the Device address for ADC */
55#define I2C_A_ADC_READ 0x00000001 /*To perform a read operation */
56#define I2C_A_ADC_START 0x00000100 /*Start I2C transaction */
57#define I2C_A_ADC_ABORT 0x00000200 /*I2C transaction abort */
58#define I2C_A_ADC_LAST 0x00000400 /*I2C last transaction */
59#define I2C_A_ADC_BYTE 0x00000800 /*I2C one byte mode */
60
61#define I2C_D_ADC_REG_MASK 0xfe000000 /*ADC address register */
62#define I2C_D_ADC_DAT_MASK 0x01ff0000 /*ADC data register */
63
64#define ADC_TIMEOUT 0x00000007 /*ADC Timeout Clock Disable */
65#define ADC_IFC_CTRL 0x0000000b /*ADC Interface Control */
66#define ADC_MASTER 0x0000000c /*ADC Master Mode Control */
67#define ADC_POWER 0x0000000d /*ADC PowerDown Control */
68#define ADC_ATTEN_ADCL 0x0000000e /*ADC Attenuation ADCL */
69#define ADC_ATTEN_ADCR 0x0000000f /*ADC Attenuation ADCR */
70#define ADC_ALC_CTRL1 0x00000010 /*ADC ALC Control 1 */
71#define ADC_ALC_CTRL2 0x00000011 /*ADC ALC Control 2 */
72#define ADC_ALC_CTRL3 0x00000012 /*ADC ALC Control 3 */
73#define ADC_NOISE_CTRL 0x00000013 /*ADC Noise Gate Control */
74#define ADC_LIMIT_CTRL 0x00000014 /*ADC Limiter Control */
75#define ADC_MUX 0x00000015 /*ADC Mux offset */
76#if 0
77/* FIXME: Not tested yet. */
78#define ADC_GAIN_MASK 0x000000ff //Mask for ADC Gain
79#define ADC_ZERODB 0x000000cf //Value to set ADC to 0dB
80#define ADC_MUTE_MASK 0x000000c0 //Mask for ADC mute
81#define ADC_MUTE 0x000000c0 //Value to mute ADC
82#define ADC_OSR 0x00000008 //Mask for ADC oversample rate select
83#define ADC_TIMEOUT_DISABLE 0x00000008 //Value and mask to disable Timeout clock
84#define ADC_HPF_DISABLE 0x00000100 //Value and mask to disable High pass filter
85#define ADC_TRANWIN_MASK 0x00000070 //Mask for Length of Transient Window
86#endif
87
88#define ADC_MUX_MASK 0x0000000f //Mask for ADC Mux
89#define ADC_MUX_0 0x00000001 //Value to select Unknown at ADC Mux (Not used)
90#define ADC_MUX_1 0x00000002 //Value to select Unknown at ADC Mux (Not used)
91#define ADC_MUX_2 0x00000004 //Value to select Mic at ADC Mux
92#define ADC_MUX_3 0x00000008 //Value to select Line-In at ADC Mux
46 93
47#define P17V_START_AUDIO 0x40 /* Start Audio bit */ 94#define P17V_START_AUDIO 0x40 /* Start Audio bit */
48/* 41 - 47: Reserved */ 95/* 41 - 47: Reserved */
diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c
index 94eca82dd4fc..1db50fe61475 100644
--- a/sound/pci/emu10k1/voice.c
+++ b/sound/pci/emu10k1/voice.c
@@ -83,7 +83,7 @@ static int voice_alloc(struct snd_emu10k1 *emu, int type, int number,
83 if (first_voice == last_voice) 83 if (first_voice == last_voice)
84 return -ENOMEM; 84 return -ENOMEM;
85 85
86 for (i=0; i < number; i++) { 86 for (i = 0; i < number; i++) {
87 voice = &emu->voices[(first_voice + i) % NUM_G]; 87 voice = &emu->voices[(first_voice + i) % NUM_G];
88 // printk("voice alloc - %i, %i of %i\n", voice->number, idx-first_voice+1, number); 88 // printk("voice alloc - %i, %i of %i\n", voice->number, idx-first_voice+1, number);
89 voice->use = 1; 89 voice->use = 1;
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index a84f6b21024f..425b167522d5 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -413,8 +413,6 @@ struct ensoniq {
413 } u; 413 } u;
414 414
415 struct pci_dev *pci; 415 struct pci_dev *pci;
416 unsigned short subsystem_vendor_id;
417 unsigned short subsystem_device_id;
418 struct snd_card *card; 416 struct snd_card *card;
419 struct snd_pcm *pcm1; /* DAC1/ADC PCM */ 417 struct snd_pcm *pcm1; /* DAC1/ADC PCM */
420 struct snd_pcm *pcm2; /* DAC2 PCM */ 418 struct snd_pcm *pcm2; /* DAC2 PCM */
@@ -1607,11 +1605,26 @@ static void snd_ensoniq_mixer_free_ac97(struct snd_ac97 *ac97)
1607 ensoniq->u.es1371.ac97 = NULL; 1605 ensoniq->u.es1371.ac97 = NULL;
1608} 1606}
1609 1607
1610static struct { 1608struct es1371_quirk {
1611 unsigned short vid; /* vendor ID */ 1609 unsigned short vid; /* vendor ID */
1612 unsigned short did; /* device ID */ 1610 unsigned short did; /* device ID */
1613 unsigned char rev; /* revision */ 1611 unsigned char rev; /* revision */
1614} es1371_spdif_present[] __devinitdata = { 1612};
1613
1614static int __devinit es1371_quirk_lookup(struct ensoniq *ensoniq,
1615 struct es1371_quirk *list)
1616{
1617 while (list->vid != (unsigned short)PCI_ANY_ID) {
1618 if (ensoniq->pci->vendor == list->vid &&
1619 ensoniq->pci->device == list->did &&
1620 ensoniq->rev == list->rev)
1621 return 1;
1622 list++;
1623 }
1624 return 0;
1625}
1626
1627static struct es1371_quirk es1371_spdif_present[] __devinitdata = {
1615 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C }, 1628 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C },
1616 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D }, 1629 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
1617 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E }, 1630 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
@@ -1620,12 +1633,19 @@ static struct {
1620 { .vid = PCI_ANY_ID, .did = PCI_ANY_ID } 1633 { .vid = PCI_ANY_ID, .did = PCI_ANY_ID }
1621}; 1634};
1622 1635
1623static int snd_ensoniq_1371_mixer(struct ensoniq * ensoniq, int has_spdif, int has_line) 1636static struct snd_pci_quirk ens1373_line_quirk[] __devinitdata = {
1637 SND_PCI_QUIRK_ID(0x1274, 0x2000), /* GA-7DXR */
1638 SND_PCI_QUIRK_ID(0x1458, 0xa000), /* GA-8IEXP */
1639 { } /* end */
1640};
1641
1642static int __devinit snd_ensoniq_1371_mixer(struct ensoniq *ensoniq,
1643 int has_spdif, int has_line)
1624{ 1644{
1625 struct snd_card *card = ensoniq->card; 1645 struct snd_card *card = ensoniq->card;
1626 struct snd_ac97_bus *pbus; 1646 struct snd_ac97_bus *pbus;
1627 struct snd_ac97_template ac97; 1647 struct snd_ac97_template ac97;
1628 int err, idx; 1648 int err;
1629 static struct snd_ac97_bus_ops ops = { 1649 static struct snd_ac97_bus_ops ops = {
1630 .write = snd_es1371_codec_write, 1650 .write = snd_es1371_codec_write,
1631 .read = snd_es1371_codec_read, 1651 .read = snd_es1371_codec_read,
@@ -1641,33 +1661,28 @@ static int snd_ensoniq_1371_mixer(struct ensoniq * ensoniq, int has_spdif, int h
1641 ac97.scaps = AC97_SCAP_AUDIO; 1661 ac97.scaps = AC97_SCAP_AUDIO;
1642 if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0) 1662 if ((err = snd_ac97_mixer(pbus, &ac97, &ensoniq->u.es1371.ac97)) < 0)
1643 return err; 1663 return err;
1644 for (idx = 0; es1371_spdif_present[idx].vid != (unsigned short)PCI_ANY_ID; idx++) 1664 if (has_spdif > 0 ||
1645 if ((ensoniq->pci->vendor == es1371_spdif_present[idx].vid && 1665 (!has_spdif && es1371_quirk_lookup(ensoniq, es1371_spdif_present))) {
1646 ensoniq->pci->device == es1371_spdif_present[idx].did && 1666 struct snd_kcontrol *kctl;
1647 ensoniq->rev == es1371_spdif_present[idx].rev) || has_spdif > 0) { 1667 int i, index = 0;
1648 struct snd_kcontrol *kctl; 1668
1649 int i, index = 0; 1669 ensoniq->spdif_default = ensoniq->spdif_stream =
1650 1670 SNDRV_PCM_DEFAULT_CON_SPDIF;
1651 if (has_spdif < 0) 1671 outl(ensoniq->spdif_default, ES_REG(ensoniq, CHANNEL_STATUS));
1652 break; 1672
1653 1673 if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SPDIF)
1654 ensoniq->spdif_default = ensoniq->spdif_stream = 1674 index++;
1655 SNDRV_PCM_DEFAULT_CON_SPDIF; 1675
1656 outl(ensoniq->spdif_default, ES_REG(ensoniq, CHANNEL_STATUS)); 1676 for (i = 0; i < ARRAY_SIZE(snd_es1371_mixer_spdif); i++) {
1657 1677 kctl = snd_ctl_new1(&snd_es1371_mixer_spdif[i], ensoniq);
1658 if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SPDIF) 1678 if (!kctl)
1659 index++; 1679 return -ENOMEM;
1660 1680 kctl->id.index = index;
1661 for (i = 0; i < (int)ARRAY_SIZE(snd_es1371_mixer_spdif); i++) { 1681 err = snd_ctl_add(card, kctl);
1662 kctl = snd_ctl_new1(&snd_es1371_mixer_spdif[i], ensoniq); 1682 if (err < 0)
1663 if (! kctl) 1683 return err;
1664 return -ENOMEM;
1665 kctl->id.index = index;
1666 if ((err = snd_ctl_add(card, kctl)) < 0)
1667 return err;
1668 }
1669 break;
1670 } 1684 }
1685 }
1671 if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SDAC) { 1686 if (ensoniq->u.es1371.ac97->ext_id & AC97_EI_SDAC) {
1672 /* mirror rear to front speakers */ 1687 /* mirror rear to front speakers */
1673 ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT24); 1688 ensoniq->cssr &= ~(ES_1373_REAR_BIT27|ES_1373_REAR_BIT24);
@@ -1676,12 +1691,10 @@ static int snd_ensoniq_1371_mixer(struct ensoniq * ensoniq, int has_spdif, int h
1676 if (err < 0) 1691 if (err < 0)
1677 return err; 1692 return err;
1678 } 1693 }
1679 if (((ensoniq->subsystem_vendor_id == 0x1274) && 1694 if (has_line > 0 ||
1680 (ensoniq->subsystem_device_id == 0x2000)) || /* GA-7DXR */ 1695 snd_pci_quirk_lookup(ensoniq->pci, ens1373_line_quirk)) {
1681 ((ensoniq->subsystem_vendor_id == 0x1458) && 1696 err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_line,
1682 (ensoniq->subsystem_device_id == 0xa000)) || /* GA-8IEXP */ 1697 ensoniq));
1683 has_line > 0) {
1684 err = snd_ctl_add(card, snd_ctl_new1(&snd_ens1373_line, ensoniq));
1685 if (err < 0) 1698 if (err < 0)
1686 return err; 1699 return err;
1687 } 1700 }
@@ -1956,21 +1969,15 @@ static int snd_ensoniq_dev_free(struct snd_device *device)
1956} 1969}
1957 1970
1958#ifdef CHIP1371 1971#ifdef CHIP1371
1959static struct { 1972static struct snd_pci_quirk es1371_amplifier_hack[] __devinitdata = {
1960 unsigned short svid; /* subsystem vendor ID */ 1973 SND_PCI_QUIRK_ID(0x107b, 0x2150), /* Gateway Solo 2150 */
1961 unsigned short sdid; /* subsystem device ID */ 1974 SND_PCI_QUIRK_ID(0x13bd, 0x100c), /* EV1938 on Mebius PC-MJ100V */
1962} es1371_amplifier_hack[] = { 1975 SND_PCI_QUIRK_ID(0x1102, 0x5938), /* Targa Xtender300 */
1963 { .svid = 0x107b, .sdid = 0x2150 }, /* Gateway Solo 2150 */ 1976 SND_PCI_QUIRK_ID(0x1102, 0x8938), /* IPC Topnote G notebook */
1964 { .svid = 0x13bd, .sdid = 0x100c }, /* EV1938 on Mebius PC-MJ100V */ 1977 { } /* end */
1965 { .svid = 0x1102, .sdid = 0x5938 }, /* Targa Xtender300 */
1966 { .svid = 0x1102, .sdid = 0x8938 }, /* IPC Topnote G notebook */
1967 { .svid = PCI_ANY_ID, .sdid = PCI_ANY_ID }
1968}; 1978};
1969static struct { 1979
1970 unsigned short vid; /* vendor ID */ 1980static struct es1371_quirk es1371_ac97_reset_hack[] = {
1971 unsigned short did; /* device ID */
1972 unsigned char rev; /* revision */
1973} es1371_ac97_reset_hack[] = {
1974 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C }, 1981 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_C },
1975 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D }, 1982 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_D },
1976 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E }, 1983 { .vid = PCI_VENDOR_ID_ENSONIQ, .did = PCI_DEVICE_ID_ENSONIQ_CT5880, .rev = CT5880REV_CT5880_E },
@@ -1984,7 +1991,6 @@ static void snd_ensoniq_chip_init(struct ensoniq *ensoniq)
1984{ 1991{
1985#ifdef CHIP1371 1992#ifdef CHIP1371
1986 int idx; 1993 int idx;
1987 struct pci_dev *pci = ensoniq->pci;
1988#endif 1994#endif
1989 /* this code was part of snd_ensoniq_create before intruduction 1995 /* this code was part of snd_ensoniq_create before intruduction
1990 * of suspend/resume 1996 * of suspend/resume
@@ -1999,16 +2005,12 @@ static void snd_ensoniq_chip_init(struct ensoniq *ensoniq)
1999 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL)); 2005 outl(ensoniq->ctrl, ES_REG(ensoniq, CONTROL));
2000 outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL)); 2006 outl(ensoniq->sctrl, ES_REG(ensoniq, SERIAL));
2001 outl(0, ES_REG(ensoniq, 1371_LEGACY)); 2007 outl(0, ES_REG(ensoniq, 1371_LEGACY));
2002 for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++) 2008 if (es1371_quirk_lookup(ensoniq, es1371_ac97_reset_hack)) {
2003 if (pci->vendor == es1371_ac97_reset_hack[idx].vid && 2009 outl(ensoniq->cssr, ES_REG(ensoniq, STATUS));
2004 pci->device == es1371_ac97_reset_hack[idx].did && 2010 /* need to delay around 20ms(bleech) to give
2005 ensoniq->rev == es1371_ac97_reset_hack[idx].rev) { 2011 some CODECs enough time to wakeup */
2006 outl(ensoniq->cssr, ES_REG(ensoniq, STATUS)); 2012 msleep(20);
2007 /* need to delay around 20ms(bleech) to give 2013 }
2008 some CODECs enough time to wakeup */
2009 msleep(20);
2010 break;
2011 }
2012 /* AC'97 warm reset to start the bitclk */ 2014 /* AC'97 warm reset to start the bitclk */
2013 outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL)); 2015 outl(ensoniq->ctrl | ES_1371_SYNC_RES, ES_REG(ensoniq, CONTROL));
2014 inl(ES_REG(ensoniq, CONTROL)); 2016 inl(ES_REG(ensoniq, CONTROL));
@@ -2112,11 +2114,7 @@ static int __devinit snd_ensoniq_create(struct snd_card *card,
2112 struct ensoniq ** rensoniq) 2114 struct ensoniq ** rensoniq)
2113{ 2115{
2114 struct ensoniq *ensoniq; 2116 struct ensoniq *ensoniq;
2115 unsigned short cmdw;
2116 unsigned char cmdb; 2117 unsigned char cmdb;
2117#ifdef CHIP1371
2118 int idx;
2119#endif
2120 int err; 2118 int err;
2121 static struct snd_device_ops ops = { 2119 static struct snd_device_ops ops = {
2122 .dev_free = snd_ensoniq_dev_free, 2120 .dev_free = snd_ensoniq_dev_free,
@@ -2159,10 +2157,6 @@ static int __devinit snd_ensoniq_create(struct snd_card *card,
2159 pci_set_master(pci); 2157 pci_set_master(pci);
2160 pci_read_config_byte(pci, PCI_REVISION_ID, &cmdb); 2158 pci_read_config_byte(pci, PCI_REVISION_ID, &cmdb);
2161 ensoniq->rev = cmdb; 2159 ensoniq->rev = cmdb;
2162 pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &cmdw);
2163 ensoniq->subsystem_vendor_id = cmdw;
2164 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &cmdw);
2165 ensoniq->subsystem_device_id = cmdw;
2166#ifdef CHIP1370 2160#ifdef CHIP1370
2167#if 0 2161#if 0
2168 ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE | 2162 ensoniq->ctrl = ES_1370_CDC_EN | ES_1370_SERR_DISABLE |
@@ -2175,19 +2169,11 @@ static int __devinit snd_ensoniq_create(struct snd_card *card,
2175 ensoniq->ctrl = 0; 2169 ensoniq->ctrl = 0;
2176 ensoniq->sctrl = 0; 2170 ensoniq->sctrl = 0;
2177 ensoniq->cssr = 0; 2171 ensoniq->cssr = 0;
2178 for (idx = 0; es1371_amplifier_hack[idx].svid != (unsigned short)PCI_ANY_ID; idx++) 2172 if (snd_pci_quirk_lookup(pci, es1371_amplifier_hack))
2179 if (ensoniq->subsystem_vendor_id == es1371_amplifier_hack[idx].svid && 2173 ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */
2180 ensoniq->subsystem_device_id == es1371_amplifier_hack[idx].sdid) { 2174
2181 ensoniq->ctrl |= ES_1371_GPIO_OUT(1); /* turn amplifier on */ 2175 if (es1371_quirk_lookup(ensoniq, es1371_ac97_reset_hack))
2182 break; 2176 ensoniq->cssr |= ES_1371_ST_AC97_RST;
2183 }
2184 for (idx = 0; es1371_ac97_reset_hack[idx].vid != (unsigned short)PCI_ANY_ID; idx++)
2185 if (pci->vendor == es1371_ac97_reset_hack[idx].vid &&
2186 pci->device == es1371_ac97_reset_hack[idx].did &&
2187 ensoniq->rev == es1371_ac97_reset_hack[idx].rev) {
2188 ensoniq->cssr |= ES_1371_ST_AC97_RST;
2189 break;
2190 }
2191#endif 2177#endif
2192 2178
2193 snd_ensoniq_chip_init(ensoniq); 2179 snd_ensoniq_chip_init(ensoniq);
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 66ac26c5a240..fec29a108945 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1344,7 +1344,7 @@ static unsigned int db_scale_line[] = {
1344 8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0), 1344 8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0),
1345}; 1345};
1346 1346
1347static DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0); 1347static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0);
1348 1348
1349static struct snd_kcontrol_new snd_es1938_controls[] = { 1349static struct snd_kcontrol_new snd_es1938_controls[] = {
1350ES1938_DOUBLE_TLV("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0, 1350ES1938_DOUBLE_TLV("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0,
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index b7b361ce3a93..6dc578bbeec9 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1157,7 +1157,7 @@ static int snd_fm801_put_mux(struct snd_kcontrol *kcontrol,
1157 return snd_fm801_update_bits(chip, FM801_REC_SRC, 7, val); 1157 return snd_fm801_update_bits(chip, FM801_REC_SRC, 7, val);
1158} 1158}
1159 1159
1160static DECLARE_TLV_DB_SCALE(db_scale_dsp, -3450, 150, 0); 1160static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -3450, 150, 0);
1161 1161
1162#define FM801_CONTROLS ARRAY_SIZE(snd_fm801_controls) 1162#define FM801_CONTROLS ARRAY_SIZE(snd_fm801_controls)
1163 1163
diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile
index dbacba6177db..60d7b05a204a 100644
--- a/sound/pci/hda/Makefile
+++ b/sound/pci/hda/Makefile
@@ -1,5 +1,14 @@
1snd-hda-intel-objs := hda_intel.o 1snd-hda-intel-objs := hda_intel.o
2snd-hda-codec-objs := hda_codec.o hda_generic.o patch_realtek.o patch_cmedia.o patch_analog.o patch_sigmatel.o patch_si3054.o patch_atihdmi.o 2snd-hda-codec-objs := hda_codec.o \
3 hda_generic.o \
4 patch_realtek.o \
5 patch_cmedia.o \
6 patch_analog.o \
7 patch_sigmatel.o \
8 patch_si3054.o \
9 patch_atihdmi.o \
10 patch_conexant.o \
11 patch_via.o
3ifdef CONFIG_PROC_FS 12ifdef CONFIG_PROC_FS
4snd-hda-codec-objs += hda_proc.o 13snd-hda-codec-objs += hda_proc.o
5endif 14endif
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 18bbc87e376f..8f34fb447983 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -52,6 +52,7 @@ struct hda_vendor_id {
52static struct hda_vendor_id hda_vendor_ids[] = { 52static struct hda_vendor_id hda_vendor_ids[] = {
53 { 0x10ec, "Realtek" }, 53 { 0x10ec, "Realtek" },
54 { 0x1057, "Motorola" }, 54 { 0x1057, "Motorola" },
55 { 0x1106, "VIA" },
55 { 0x11d4, "Analog Devices" }, 56 { 0x11d4, "Analog Devices" },
56 { 0x13f6, "C-Media" }, 57 { 0x13f6, "C-Media" },
57 { 0x14f1, "Conexant" }, 58 { 0x14f1, "Conexant" },
@@ -262,7 +263,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
262 unsol->queue[wp] = res; 263 unsol->queue[wp] = res;
263 unsol->queue[wp + 1] = res_ex; 264 unsol->queue[wp + 1] = res_ex;
264 265
265 queue_work(unsol->workq, &unsol->work); 266 schedule_work(&unsol->work);
266 267
267 return 0; 268 return 0;
268} 269}
@@ -309,12 +310,6 @@ static int init_unsol_queue(struct hda_bus *bus)
309 snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n"); 310 snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n");
310 return -ENOMEM; 311 return -ENOMEM;
311 } 312 }
312 unsol->workq = create_singlethread_workqueue("hda_codec");
313 if (! unsol->workq) {
314 snd_printk(KERN_ERR "hda_codec: can't create workqueue\n");
315 kfree(unsol);
316 return -ENOMEM;
317 }
318 INIT_WORK(&unsol->work, process_unsol_events); 313 INIT_WORK(&unsol->work, process_unsol_events);
319 unsol->bus = bus; 314 unsol->bus = bus;
320 bus->unsol = unsol; 315 bus->unsol = unsol;
@@ -333,7 +328,7 @@ static int snd_hda_bus_free(struct hda_bus *bus)
333 if (! bus) 328 if (! bus)
334 return 0; 329 return 0;
335 if (bus->unsol) { 330 if (bus->unsol) {
336 destroy_workqueue(bus->unsol->workq); 331 flush_scheduled_work();
337 kfree(bus->unsol); 332 kfree(bus->unsol);
338 } 333 }
339 list_for_each_safe(p, n, &bus->codec_list) { 334 list_for_each_safe(p, n, &bus->codec_list) {
@@ -1714,6 +1709,8 @@ EXPORT_SYMBOL(snd_hda_build_pcms);
1714/** 1709/**
1715 * snd_hda_check_board_config - compare the current codec with the config table 1710 * snd_hda_check_board_config - compare the current codec with the config table
1716 * @codec: the HDA codec 1711 * @codec: the HDA codec
1712 * @num_configs: number of config enums
1713 * @models: array of model name strings
1717 * @tbl: configuration table, terminated by null entries 1714 * @tbl: configuration table, terminated by null entries
1718 * 1715 *
1719 * Compares the modelname or PCI subsystem id of the current codec with the 1716 * Compares the modelname or PCI subsystem id of the current codec with the
@@ -1722,33 +1719,44 @@ EXPORT_SYMBOL(snd_hda_build_pcms);
1722 * 1719 *
1723 * If no entries are matching, the function returns a negative value. 1720 * If no entries are matching, the function returns a negative value.
1724 */ 1721 */
1725int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl) 1722int snd_hda_check_board_config(struct hda_codec *codec,
1726{ 1723 int num_configs, const char **models,
1727 const struct hda_board_config *c; 1724 const struct snd_pci_quirk *tbl)
1728 1725{
1729 if (codec->bus->modelname) { 1726 if (codec->bus->modelname && models) {
1730 for (c = tbl; c->modelname || c->pci_subvendor; c++) { 1727 int i;
1731 if (c->modelname && 1728 for (i = 0; i < num_configs; i++) {
1732 ! strcmp(codec->bus->modelname, c->modelname)) { 1729 if (models[i] &&
1733 snd_printd(KERN_INFO "hda_codec: model '%s' is selected\n", c->modelname); 1730 !strcmp(codec->bus->modelname, models[i])) {
1734 return c->config; 1731 snd_printd(KERN_INFO "hda_codec: model '%s' is "
1732 "selected\n", models[i]);
1733 return i;
1735 } 1734 }
1736 } 1735 }
1737 } 1736 }
1738 1737
1739 if (codec->bus->pci) { 1738 if (!codec->bus->pci || !tbl)
1740 u16 subsystem_vendor, subsystem_device; 1739 return -1;
1741 pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); 1740
1742 pci_read_config_word(codec->bus->pci, PCI_SUBSYSTEM_ID, &subsystem_device); 1741 tbl = snd_pci_quirk_lookup(codec->bus->pci, tbl);
1743 for (c = tbl; c->modelname || c->pci_subvendor; c++) { 1742 if (!tbl)
1744 if (c->pci_subvendor == subsystem_vendor && 1743 return -1;
1745 (! c->pci_subdevice /* all match */|| 1744 if (tbl->value >= 0 && tbl->value < num_configs) {
1746 (c->pci_subdevice == subsystem_device))) { 1745#ifdef CONFIG_SND_DEBUG_DETECT
1747 snd_printdd(KERN_INFO "hda_codec: PCI %x:%x, codec config %d is selected\n", 1746 char tmp[10];
1748 subsystem_vendor, subsystem_device, c->config); 1747 const char *model = NULL;
1749 return c->config; 1748 if (models)
1750 } 1749 model = models[tbl->value];
1750 if (!model) {
1751 sprintf(tmp, "#%d", tbl->value);
1752 model = tmp;
1751 } 1753 }
1754 snd_printdd(KERN_INFO "hda_codec: model '%s' is selected "
1755 "for config %x:%x (%s)\n",
1756 model, tbl->subvendor, tbl->subdevice,
1757 (tbl->name ? tbl->name : "Unknown device"));
1758#endif
1759 return tbl->value;
1752 } 1760 }
1753 return -1; 1761 return -1;
1754} 1762}
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 1a7e82104bb9..b9a8e238b0a8 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -199,7 +199,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 };
199 199
200/* STATESTS int mask: SD2,SD1,SD0 */ 200/* STATESTS int mask: SD2,SD1,SD0 */
201#define STATESTS_INT_MASK 0x07 201#define STATESTS_INT_MASK 0x07
202#define AZX_MAX_CODECS 4 202#define AZX_MAX_CODECS 3
203 203
204/* SD_CTL bits */ 204/* SD_CTL bits */
205#define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */ 205#define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */
@@ -1285,7 +1285,7 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec,
1285 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops); 1285 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops);
1286 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, 1286 snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
1287 snd_dma_pci_data(chip->pci), 1287 snd_dma_pci_data(chip->pci),
1288 1024 * 64, 1024 * 128); 1288 1024 * 64, 1024 * 1024);
1289 chip->pcm[pcm_dev] = pcm; 1289 chip->pcm[pcm_dev] = pcm;
1290 if (chip->pcm_devs < pcm_dev + 1) 1290 if (chip->pcm_devs < pcm_dev + 1)
1291 chip->pcm_devs = pcm_dev + 1; 1291 chip->pcm_devs = pcm_dev + 1;
@@ -1391,6 +1391,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
1391 return -1; 1391 return -1;
1392 } 1392 }
1393 chip->irq = chip->pci->irq; 1393 chip->irq = chip->pci->irq;
1394 pci_intx(chip->pci, !chip->msi);
1394 return 0; 1395 return 0;
1395} 1396}
1396 1397
@@ -1502,6 +1503,31 @@ static int azx_dev_free(struct snd_device *device)
1502} 1503}
1503 1504
1504/* 1505/*
1506 * white/black-listing for position_fix
1507 */
1508static const struct snd_pci_quirk position_fix_list[] __devinitdata = {
1509 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE),
1510 {}
1511};
1512
1513static int __devinit check_position_fix(struct azx *chip, int fix)
1514{
1515 const struct snd_pci_quirk *q;
1516
1517 if (fix == POS_FIX_AUTO) {
1518 q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
1519 if (q) {
1520 snd_printdd(KERN_INFO
1521 "hda_intel: position_fix set to %d "
1522 "for device %04x:%04x\n",
1523 q->value, q->subvendor, q->subdevice);
1524 return q->value;
1525 }
1526 }
1527 return fix;
1528}
1529
1530/*
1505 * constructor 1531 * constructor
1506 */ 1532 */
1507static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, 1533static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
@@ -1535,7 +1561,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
1535 chip->driver_type = driver_type; 1561 chip->driver_type = driver_type;
1536 chip->msi = enable_msi; 1562 chip->msi = enable_msi;
1537 1563
1538 chip->position_fix = position_fix; 1564 chip->position_fix = check_position_fix(chip, position_fix);
1565
1539 chip->single_cmd = single_cmd; 1566 chip->single_cmd = single_cmd;
1540 1567
1541#if BITS_PER_LONG != 64 1568#if BITS_PER_LONG != 64
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 9ca1baf860bd..39718d6cdadd 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -173,14 +173,9 @@ static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
173/* 173/*
174 * Misc 174 * Misc
175 */ 175 */
176struct hda_board_config { 176int snd_hda_check_board_config(struct hda_codec *codec, int num_configs,
177 const char *modelname; 177 const char **modelnames,
178 int config; 178 const struct snd_pci_quirk *pci_list);
179 unsigned short pci_subvendor;
180 unsigned short pci_subdevice;
181};
182
183int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl);
184int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); 179int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew);
185 180
186/* 181/*
@@ -204,7 +199,6 @@ struct hda_bus_unsolicited {
204 unsigned int rp, wp; 199 unsigned int rp, wp;
205 200
206 /* workqueue */ 201 /* workqueue */
207 struct workqueue_struct *workq;
208 struct work_struct work; 202 struct work_struct work;
209 struct hda_bus *bus; 203 struct hda_bus *bus;
210}; 204};
diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h
index 0b668793face..9f9e9ae44a9d 100644
--- a/sound/pci/hda/hda_patch.h
+++ b/sound/pci/hda/hda_patch.h
@@ -14,6 +14,10 @@ extern struct hda_codec_preset snd_hda_preset_sigmatel[];
14extern struct hda_codec_preset snd_hda_preset_si3054[]; 14extern struct hda_codec_preset snd_hda_preset_si3054[];
15/* ATI HDMI codecs */ 15/* ATI HDMI codecs */
16extern struct hda_codec_preset snd_hda_preset_atihdmi[]; 16extern struct hda_codec_preset snd_hda_preset_atihdmi[];
17/* Conexant audio codec */
18extern struct hda_codec_preset snd_hda_preset_conexant[];
19/* VIA codecs */
20extern struct hda_codec_preset snd_hda_preset_via[];
17 21
18static const struct hda_codec_preset *hda_preset_tables[] = { 22static const struct hda_codec_preset *hda_preset_tables[] = {
19 snd_hda_preset_realtek, 23 snd_hda_preset_realtek,
@@ -22,5 +26,7 @@ static const struct hda_codec_preset *hda_preset_tables[] = {
22 snd_hda_preset_sigmatel, 26 snd_hda_preset_sigmatel,
23 snd_hda_preset_si3054, 27 snd_hda_preset_si3054,
24 snd_hda_preset_atihdmi, 28 snd_hda_preset_atihdmi,
29 snd_hda_preset_conexant,
30 snd_hda_preset_via,
25 NULL 31 NULL
26}; 32};
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 076365bc10e9..38977bce70e2 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -782,54 +782,63 @@ static struct hda_channel_mode ad1986a_modes[3] = {
782 782
783/* eapd initialization */ 783/* eapd initialization */
784static struct hda_verb ad1986a_eapd_init_verbs[] = { 784static struct hda_verb ad1986a_eapd_init_verbs[] = {
785 {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, 785 {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
786 {} 786 {}
787}; 787};
788 788
789/* Ultra initialization */
790static struct hda_verb ad1986a_ultra_init[] = {
791 /* eapd initialization */
792 { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
793 /* CLFE -> Mic in */
794 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 },
795 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
796 { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
797 { } /* end */
798};
799
789/* models */ 800/* models */
790enum { AD1986A_6STACK, AD1986A_3STACK, AD1986A_LAPTOP, AD1986A_LAPTOP_EAPD }; 801enum {
791 802 AD1986A_6STACK,
792static struct hda_board_config ad1986a_cfg_tbl[] = { 803 AD1986A_3STACK,
793 { .modelname = "6stack", .config = AD1986A_6STACK }, 804 AD1986A_LAPTOP,
794 { .modelname = "3stack", .config = AD1986A_3STACK }, 805 AD1986A_LAPTOP_EAPD,
795 { .pci_subvendor = 0x10de, .pci_subdevice = 0xcb84, 806 AD1986A_ULTRA,
796 .config = AD1986A_3STACK }, /* ASUS A8N-VM CSM */ 807 AD1986A_MODELS
797 { .pci_subvendor = 0x1043, .pci_subdevice = 0x817f, 808};
798 .config = AD1986A_3STACK }, /* ASUS P5P-L2 */ 809
799 { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b3, 810static const char *ad1986a_models[AD1986A_MODELS] = {
800 .config = AD1986A_3STACK }, /* ASUS P5RD2-VM / P5GPL-X SE */ 811 [AD1986A_6STACK] = "6stack",
801 { .pci_subvendor = 0x1043, .pci_subdevice = 0x81cb, 812 [AD1986A_3STACK] = "3stack",
802 .config = AD1986A_3STACK }, /* ASUS M2NPV-VM */ 813 [AD1986A_LAPTOP] = "laptop",
803 { .modelname = "laptop", .config = AD1986A_LAPTOP }, 814 [AD1986A_LAPTOP_EAPD] = "laptop-eapd",
804 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc01e, 815 [AD1986A_ULTRA] = "ultra",
805 .config = AD1986A_LAPTOP }, /* FSC V2060 */ 816};
806 { .pci_subvendor = 0x17c0, .pci_subdevice = 0x2017, 817
807 .config = AD1986A_LAPTOP }, /* Samsung M50 */ 818static struct snd_pci_quirk ad1986a_cfg_tbl[] = {
808 { .pci_subvendor = 0x1043, .pci_subdevice = 0x818f, 819 SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
809 .config = AD1986A_LAPTOP }, /* ASUS P5GV-MX */ 820 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
810 { .modelname = "laptop-eapd", .config = AD1986A_LAPTOP_EAPD }, 821 SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
811 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc023, 822 SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD),
812 .config = AD1986A_LAPTOP_EAPD }, /* Samsung X60 Chane */ 823 SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
813 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc024, 824 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD),
814 .config = AD1986A_LAPTOP_EAPD }, /* Samsung R65-T2300 Charis */ 825 SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
815 { .pci_subvendor = 0x144d, .pci_subdevice = 0xc026, 826 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
816 .config = AD1986A_LAPTOP_EAPD }, /* Samsung X11-T2300 Culesa */ 827 SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
817 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1153, 828 SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
818 .config = AD1986A_LAPTOP_EAPD }, /* ASUS M9 */ 829 SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
819 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1213, 830 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
820 .config = AD1986A_LAPTOP_EAPD }, /* ASUS A6J */ 831 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
821 { .pci_subvendor = 0x1043, .pci_subdevice = 0x11f7, 832 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
822 .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5A */ 833 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
823 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1263, 834 SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_LAPTOP_EAPD),
824 .config = AD1986A_LAPTOP_EAPD }, /* ASUS U5F */ 835 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_LAPTOP_EAPD),
825 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1297, 836 SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_LAPTOP_EAPD),
826 .config = AD1986A_LAPTOP_EAPD }, /* ASUS Z62F */ 837 SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
827 { .pci_subvendor = 0x1043, .pci_subdevice = 0x12b3, 838 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
828 .config = AD1986A_LAPTOP_EAPD }, /* ASUS V1j */ 839 SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
829 { .pci_subvendor = 0x103c, .pci_subdevice = 0x30af, 840 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_EAPD),
830 .config = AD1986A_LAPTOP_EAPD }, /* HP Compaq Presario B2800 */ 841 SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
831 { .pci_subvendor = 0x17aa, .pci_subdevice = 0x2066,
832 .config = AD1986A_LAPTOP_EAPD }, /* Lenovo 3000 N100-07684JU */
833 {} 842 {}
834}; 843};
835 844
@@ -861,7 +870,9 @@ static int patch_ad1986a(struct hda_codec *codec)
861 codec->patch_ops = ad198x_patch_ops; 870 codec->patch_ops = ad198x_patch_ops;
862 871
863 /* override some parameters */ 872 /* override some parameters */
864 board_config = snd_hda_check_board_config(codec, ad1986a_cfg_tbl); 873 board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
874 ad1986a_models,
875 ad1986a_cfg_tbl);
865 switch (board_config) { 876 switch (board_config) {
866 case AD1986A_3STACK: 877 case AD1986A_3STACK:
867 spec->num_mixers = 2; 878 spec->num_mixers = 2;
@@ -891,6 +902,15 @@ static int patch_ad1986a(struct hda_codec *codec)
891 spec->multiout.dig_out_nid = 0; 902 spec->multiout.dig_out_nid = 0;
892 spec->input_mux = &ad1986a_laptop_eapd_capture_source; 903 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
893 break; 904 break;
905 case AD1986A_ULTRA:
906 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
907 spec->num_init_verbs = 2;
908 spec->init_verbs[1] = ad1986a_ultra_init;
909 spec->multiout.max_channels = 2;
910 spec->multiout.num_dacs = 1;
911 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
912 spec->multiout.dig_out_nid = 0;
913 break;
894 } 914 }
895 915
896 return 0; 916 return 0;
@@ -1391,20 +1411,27 @@ static struct hda_input_mux ad1981_thinkpad_capture_source = {
1391}; 1411};
1392 1412
1393/* models */ 1413/* models */
1394enum { AD1981_BASIC, AD1981_HP, AD1981_THINKPAD }; 1414enum {
1415 AD1981_BASIC,
1416 AD1981_HP,
1417 AD1981_THINKPAD,
1418 AD1981_MODELS
1419};
1420
1421static const char *ad1981_models[AD1981_MODELS] = {
1422 [AD1981_HP] = "hp",
1423 [AD1981_THINKPAD] = "thinkpad",
1424 [AD1981_BASIC] = "basic",
1425};
1395 1426
1396static struct hda_board_config ad1981_cfg_tbl[] = { 1427static struct snd_pci_quirk ad1981_cfg_tbl[] = {
1397 { .modelname = "hp", .config = AD1981_HP },
1398 /* All HP models */ 1428 /* All HP models */
1399 { .pci_subvendor = 0x103c, .config = AD1981_HP }, 1429 SND_PCI_QUIRK(0x103c, 0, "HP nx", AD1981_HP),
1400 { .pci_subvendor = 0x30b0, .pci_subdevice = 0x103c, 1430 /* HP nx6320 (reversed SSID, H/W bug) */
1401 .config = AD1981_HP }, /* HP nx6320 (reversed SSID, H/W bug) */ 1431 SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
1402 { .modelname = "thinkpad", .config = AD1981_THINKPAD },
1403 /* Lenovo Thinkpad T60/X60/Z6xx */ 1432 /* Lenovo Thinkpad T60/X60/Z6xx */
1404 { .pci_subvendor = 0x17aa, .config = AD1981_THINKPAD }, 1433 SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1981_THINKPAD),
1405 { .pci_subvendor = 0x1014, .pci_subdevice = 0x0597, 1434 SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
1406 .config = AD1981_THINKPAD }, /* Z60m/t */
1407 { .modelname = "basic", .config = AD1981_BASIC },
1408 {} 1435 {}
1409}; 1436};
1410 1437
@@ -1437,7 +1464,9 @@ static int patch_ad1981(struct hda_codec *codec)
1437 codec->patch_ops = ad198x_patch_ops; 1464 codec->patch_ops = ad198x_patch_ops;
1438 1465
1439 /* override some parameters */ 1466 /* override some parameters */
1440 board_config = snd_hda_check_board_config(codec, ad1981_cfg_tbl); 1467 board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
1468 ad1981_models,
1469 ad1981_cfg_tbl);
1441 switch (board_config) { 1470 switch (board_config) {
1442 case AD1981_HP: 1471 case AD1981_HP:
1443 spec->mixers[0] = ad1981_hp_mixers; 1472 spec->mixers[0] = ad1981_hp_mixers;
@@ -2565,15 +2594,14 @@ static int ad1988_auto_init(struct hda_codec *codec)
2565/* 2594/*
2566 */ 2595 */
2567 2596
2568static struct hda_board_config ad1988_cfg_tbl[] = { 2597static const char *ad1988_models[AD1988_MODEL_LAST] = {
2569 { .modelname = "6stack", .config = AD1988_6STACK }, 2598 [AD1988_6STACK] = "6stack",
2570 { .modelname = "6stack-dig", .config = AD1988_6STACK_DIG }, 2599 [AD1988_6STACK_DIG] = "6stack-dig",
2571 { .modelname = "3stack", .config = AD1988_3STACK }, 2600 [AD1988_3STACK] = "3stack",
2572 { .modelname = "3stack-dig", .config = AD1988_3STACK_DIG }, 2601 [AD1988_3STACK_DIG] = "3stack-dig",
2573 { .modelname = "laptop", .config = AD1988_LAPTOP }, 2602 [AD1988_LAPTOP] = "laptop",
2574 { .modelname = "laptop-dig", .config = AD1988_LAPTOP_DIG }, 2603 [AD1988_LAPTOP_DIG] = "laptop-dig",
2575 { .modelname = "auto", .config = AD1988_AUTO }, 2604 [AD1988_AUTO] = "auto",
2576 {}
2577}; 2605};
2578 2606
2579static int patch_ad1988(struct hda_codec *codec) 2607static int patch_ad1988(struct hda_codec *codec)
@@ -2591,8 +2619,9 @@ static int patch_ad1988(struct hda_codec *codec)
2591 if (is_rev2(codec)) 2619 if (is_rev2(codec))
2592 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n"); 2620 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
2593 2621
2594 board_config = snd_hda_check_board_config(codec, ad1988_cfg_tbl); 2622 board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
2595 if (board_config < 0 || board_config >= AD1988_MODEL_LAST) { 2623 ad1988_models, NULL);
2624 if (board_config < 0) {
2596 printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n"); 2625 printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n");
2597 board_config = AD1988_AUTO; 2626 board_config = AD1988_AUTO;
2598 } 2627 }
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index d38ce22507ae..5b9d3a31a1ae 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -40,6 +40,7 @@ enum {
40 CMI_FULL_DIG, /* back 6-jack + front-panel 2-jack + digital I/O */ 40 CMI_FULL_DIG, /* back 6-jack + front-panel 2-jack + digital I/O */
41 CMI_ALLOUT, /* back 5-jack + front-panel 2-jack + digital out */ 41 CMI_ALLOUT, /* back 5-jack + front-panel 2-jack + digital out */
42 CMI_AUTO, /* let driver guess it */ 42 CMI_AUTO, /* let driver guess it */
43 CMI_MODELS
43}; 44};
44 45
45struct cmi_spec { 46struct cmi_spec {
@@ -603,14 +604,17 @@ static void cmi9880_free(struct hda_codec *codec)
603/* 604/*
604 */ 605 */
605 606
606static struct hda_board_config cmi9880_cfg_tbl[] = { 607static const char *cmi9880_models[CMI_MODELS] = {
607 { .modelname = "minimal", .config = CMI_MINIMAL }, 608 [CMI_MINIMAL] = "minimal",
608 { .modelname = "min_fp", .config = CMI_MIN_FP }, 609 [CMI_MIN_FP] = "min_fp",
609 { .modelname = "full", .config = CMI_FULL }, 610 [CMI_FULL] = "full",
610 { .modelname = "full_dig", .config = CMI_FULL_DIG }, 611 [CMI_FULL_DIG] = "full_dig",
611 { .pci_subvendor = 0x1043, .pci_subdevice = 0x813d, .config = CMI_FULL_DIG }, /* ASUS P5AD2 */ 612 [CMI_ALLOUT] = "allout",
612 { .modelname = "allout", .config = CMI_ALLOUT }, 613 [CMI_AUTO] = "auto",
613 { .modelname = "auto", .config = CMI_AUTO }, 614};
615
616static struct snd_pci_quirk cmi9880_cfg_tbl[] = {
617 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG),
614 {} /* terminator */ 618 {} /* terminator */
615}; 619};
616 620
@@ -633,7 +637,9 @@ static int patch_cmi9880(struct hda_codec *codec)
633 return -ENOMEM; 637 return -ENOMEM;
634 638
635 codec->spec = spec; 639 codec->spec = spec;
636 spec->board_config = snd_hda_check_board_config(codec, cmi9880_cfg_tbl); 640 spec->board_config = snd_hda_check_board_config(codec, CMI_MODELS,
641 cmi9880_models,
642 cmi9880_cfg_tbl);
637 if (spec->board_config < 0) { 643 if (spec->board_config < 0) {
638 snd_printdd(KERN_INFO "hda_codec: Unknown model for CMI9880\n"); 644 snd_printdd(KERN_INFO "hda_codec: Unknown model for CMI9880\n");
639 spec->board_config = CMI_AUTO; /* try everything */ 645 spec->board_config = CMI_AUTO; /* try everything */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
new file mode 100644
index 000000000000..73f4668238c6
--- /dev/null
+++ b/sound/pci/hda/patch_conexant.c
@@ -0,0 +1,1311 @@
1/*
2 * HD audio interface patch for Conexant HDA audio codec
3 *
4 * Copyright (c) 2006 Pototskiy Akex <alex.pototskiy@gmail.com>
5 * Takashi Iwai <tiwai@suse.de>
6 * Tobin Davis <tdavis@dsl-only.net>
7 *
8 * This driver is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This driver is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <sound/driver.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <linux/slab.h>
27#include <linux/pci.h>
28#include <sound/core.h>
29#include "hda_codec.h"
30#include "hda_local.h"
31
32#define CXT_PIN_DIR_IN 0x00
33#define CXT_PIN_DIR_OUT 0x01
34#define CXT_PIN_DIR_INOUT 0x02
35#define CXT_PIN_DIR_IN_NOMICBIAS 0x03
36#define CXT_PIN_DIR_INOUT_NOMICBIAS 0x04
37
38#define CONEXANT_HP_EVENT 0x37
39#define CONEXANT_MIC_EVENT 0x38
40
41
42
43struct conexant_spec {
44
45 struct snd_kcontrol_new *mixers[5];
46 int num_mixers;
47
48 const struct hda_verb *init_verbs[5]; /* initialization verbs
49 * don't forget NULL
50 * termination!
51 */
52 unsigned int num_init_verbs;
53
54 /* playback */
55 struct hda_multi_out multiout; /* playback set-up
56 * max_channels, dacs must be set
57 * dig_out_nid and hp_nid are optional
58 */
59 unsigned int cur_eapd;
60 unsigned int need_dac_fix;
61
62 /* capture */
63 unsigned int num_adc_nids;
64 hda_nid_t *adc_nids;
65 hda_nid_t dig_in_nid; /* digital-in NID; optional */
66
67 /* capture source */
68 const struct hda_input_mux *input_mux;
69 hda_nid_t *capsrc_nids;
70 unsigned int cur_mux[3];
71
72 /* channel model */
73 const struct hda_channel_mode *channel_mode;
74 int num_channel_mode;
75
76 /* PCM information */
77 struct hda_pcm pcm_rec[2]; /* used in build_pcms() */
78
79 struct mutex amp_mutex; /* PCM volume/mute control mutex */
80 unsigned int spdif_route;
81
82 /* dynamic controls, init_verbs and input_mux */
83 struct auto_pin_cfg autocfg;
84 unsigned int num_kctl_alloc, num_kctl_used;
85 struct snd_kcontrol_new *kctl_alloc;
86 struct hda_input_mux private_imux;
87 hda_nid_t private_dac_nids[4];
88
89};
90
91static int conexant_playback_pcm_open(struct hda_pcm_stream *hinfo,
92 struct hda_codec *codec,
93 struct snd_pcm_substream *substream)
94{
95 struct conexant_spec *spec = codec->spec;
96 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
97}
98
99static int conexant_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
100 struct hda_codec *codec,
101 unsigned int stream_tag,
102 unsigned int format,
103 struct snd_pcm_substream *substream)
104{
105 struct conexant_spec *spec = codec->spec;
106 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
107 stream_tag,
108 format, substream);
109}
110
111static int conexant_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
112 struct hda_codec *codec,
113 struct snd_pcm_substream *substream)
114{
115 struct conexant_spec *spec = codec->spec;
116 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
117}
118
119/*
120 * Digital out
121 */
122static int conexant_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
123 struct hda_codec *codec,
124 struct snd_pcm_substream *substream)
125{
126 struct conexant_spec *spec = codec->spec;
127 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
128}
129
130static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
131 struct hda_codec *codec,
132 struct snd_pcm_substream *substream)
133{
134 struct conexant_spec *spec = codec->spec;
135 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
136}
137
138/*
139 * Analog capture
140 */
141static int conexant_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
142 struct hda_codec *codec,
143 unsigned int stream_tag,
144 unsigned int format,
145 struct snd_pcm_substream *substream)
146{
147 struct conexant_spec *spec = codec->spec;
148 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
149 stream_tag, 0, format);
150 return 0;
151}
152
153static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
154 struct hda_codec *codec,
155 struct snd_pcm_substream *substream)
156{
157 struct conexant_spec *spec = codec->spec;
158 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
159 0, 0, 0);
160 return 0;
161}
162
163
164
165static struct hda_pcm_stream conexant_pcm_analog_playback = {
166 .substreams = 1,
167 .channels_min = 2,
168 .channels_max = 2,
169 .nid = 0, /* fill later */
170 .ops = {
171 .open = conexant_playback_pcm_open,
172 .prepare = conexant_playback_pcm_prepare,
173 .cleanup = conexant_playback_pcm_cleanup
174 },
175};
176
177static struct hda_pcm_stream conexant_pcm_analog_capture = {
178 .substreams = 1,
179 .channels_min = 2,
180 .channels_max = 2,
181 .nid = 0, /* fill later */
182 .ops = {
183 .prepare = conexant_capture_pcm_prepare,
184 .cleanup = conexant_capture_pcm_cleanup
185 },
186};
187
188
189static struct hda_pcm_stream conexant_pcm_digital_playback = {
190 .substreams = 1,
191 .channels_min = 2,
192 .channels_max = 2,
193 .nid = 0, /* fill later */
194 .ops = {
195 .open = conexant_dig_playback_pcm_open,
196 .close = conexant_dig_playback_pcm_close
197 },
198};
199
200static struct hda_pcm_stream conexant_pcm_digital_capture = {
201 .substreams = 1,
202 .channels_min = 2,
203 .channels_max = 2,
204 /* NID is set in alc_build_pcms */
205};
206
207static int conexant_build_pcms(struct hda_codec *codec)
208{
209 struct conexant_spec *spec = codec->spec;
210 struct hda_pcm *info = spec->pcm_rec;
211
212 codec->num_pcms = 1;
213 codec->pcm_info = info;
214
215 info->name = "CONEXANT Analog";
216 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = conexant_pcm_analog_playback;
217 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
218 spec->multiout.max_channels;
219 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
220 spec->multiout.dac_nids[0];
221 info->stream[SNDRV_PCM_STREAM_CAPTURE] = conexant_pcm_analog_capture;
222 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
223 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
224
225 if (spec->multiout.dig_out_nid) {
226 info++;
227 codec->num_pcms++;
228 info->name = "Conexant Digital";
229 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
230 conexant_pcm_digital_playback;
231 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
232 spec->multiout.dig_out_nid;
233 if (spec->dig_in_nid) {
234 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
235 conexant_pcm_digital_capture;
236 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
237 spec->dig_in_nid;
238 }
239 }
240
241 return 0;
242}
243
244static int conexant_mux_enum_info(struct snd_kcontrol *kcontrol,
245 struct snd_ctl_elem_info *uinfo)
246{
247 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
248 struct conexant_spec *spec = codec->spec;
249
250 return snd_hda_input_mux_info(spec->input_mux, uinfo);
251}
252
253static int conexant_mux_enum_get(struct snd_kcontrol *kcontrol,
254 struct snd_ctl_elem_value *ucontrol)
255{
256 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
257 struct conexant_spec *spec = codec->spec;
258 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
259
260 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
261 return 0;
262}
263
264static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol,
265 struct snd_ctl_elem_value *ucontrol)
266{
267 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
268 struct conexant_spec *spec = codec->spec;
269 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
270
271 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
272 spec->capsrc_nids[adc_idx],
273 &spec->cur_mux[adc_idx]);
274}
275
276static int conexant_init(struct hda_codec *codec)
277{
278 struct conexant_spec *spec = codec->spec;
279 int i;
280
281 for (i = 0; i < spec->num_init_verbs; i++)
282 snd_hda_sequence_write(codec, spec->init_verbs[i]);
283 return 0;
284}
285
286static void conexant_free(struct hda_codec *codec)
287{
288 struct conexant_spec *spec = codec->spec;
289 unsigned int i;
290
291 if (spec->kctl_alloc) {
292 for (i = 0; i < spec->num_kctl_used; i++)
293 kfree(spec->kctl_alloc[i].name);
294 kfree(spec->kctl_alloc);
295 }
296
297 kfree(codec->spec);
298}
299
300#ifdef CONFIG_PM
301static int conexant_resume(struct hda_codec *codec)
302{
303 struct conexant_spec *spec = codec->spec;
304 int i;
305
306 codec->patch_ops.init(codec);
307 for (i = 0; i < spec->num_mixers; i++)
308 snd_hda_resume_ctls(codec, spec->mixers[i]);
309 if (spec->multiout.dig_out_nid)
310 snd_hda_resume_spdif_out(codec);
311 if (spec->dig_in_nid)
312 snd_hda_resume_spdif_in(codec);
313 return 0;
314}
315#endif
316
317static int conexant_build_controls(struct hda_codec *codec)
318{
319 struct conexant_spec *spec = codec->spec;
320 unsigned int i;
321 int err;
322
323 for (i = 0; i < spec->num_mixers; i++) {
324 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
325 if (err < 0)
326 return err;
327 }
328 if (spec->multiout.dig_out_nid) {
329 err = snd_hda_create_spdif_out_ctls(codec,
330 spec->multiout.dig_out_nid);
331 if (err < 0)
332 return err;
333 }
334 if (spec->dig_in_nid) {
335 err = snd_hda_create_spdif_in_ctls(codec,spec->dig_in_nid);
336 if (err < 0)
337 return err;
338 }
339 return 0;
340}
341
342static struct hda_codec_ops conexant_patch_ops = {
343 .build_controls = conexant_build_controls,
344 .build_pcms = conexant_build_pcms,
345 .init = conexant_init,
346 .free = conexant_free,
347#ifdef CONFIG_PM
348 .resume = conexant_resume,
349#endif
350};
351
352/*
353 * EAPD control
354 * the private value = nid | (invert << 8)
355 */
356
357static int conexant_eapd_info(struct snd_kcontrol *kcontrol,
358 struct snd_ctl_elem_info *uinfo)
359{
360 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
361 uinfo->count = 1;
362 uinfo->value.integer.min = 0;
363 uinfo->value.integer.max = 1;
364 return 0;
365}
366
367static int conexant_eapd_get(struct snd_kcontrol *kcontrol,
368 struct snd_ctl_elem_value *ucontrol)
369{
370 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
371 struct conexant_spec *spec = codec->spec;
372 int invert = (kcontrol->private_value >> 8) & 1;
373 if (invert)
374 ucontrol->value.integer.value[0] = !spec->cur_eapd;
375 else
376 ucontrol->value.integer.value[0] = spec->cur_eapd;
377 return 0;
378}
379
380static int conexant_eapd_put(struct snd_kcontrol *kcontrol,
381 struct snd_ctl_elem_value *ucontrol)
382{
383 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
384 struct conexant_spec *spec = codec->spec;
385 int invert = (kcontrol->private_value >> 8) & 1;
386 hda_nid_t nid = kcontrol->private_value & 0xff;
387 unsigned int eapd;
388 eapd = ucontrol->value.integer.value[0];
389 if (invert)
390 eapd = !eapd;
391 if (eapd == spec->cur_eapd && !codec->in_resume)
392 return 0;
393 spec->cur_eapd = eapd;
394 snd_hda_codec_write(codec, nid,
395 0, AC_VERB_SET_EAPD_BTLENABLE,
396 eapd ? 0x02 : 0x00);
397 return 1;
398}
399
400/* controls for test mode */
401#ifdef CONFIG_SND_DEBUG
402
403static int conexant_ch_mode_info(struct snd_kcontrol *kcontrol,
404 struct snd_ctl_elem_info *uinfo)
405{
406 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
407 struct conexant_spec *spec = codec->spec;
408 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
409 spec->num_channel_mode);
410}
411
412static int conexant_ch_mode_get(struct snd_kcontrol *kcontrol,
413 struct snd_ctl_elem_value *ucontrol)
414{
415 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
416 struct conexant_spec *spec = codec->spec;
417 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
418 spec->num_channel_mode,
419 spec->multiout.max_channels);
420}
421
422static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol,
423 struct snd_ctl_elem_value *ucontrol)
424{
425 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
426 struct conexant_spec *spec = codec->spec;
427 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
428 spec->num_channel_mode,
429 &spec->multiout.max_channels);
430 if (err >= 0 && spec->need_dac_fix)
431 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
432 return err;
433}
434
435#define CXT_PIN_MODE(xname, nid, dir) \
436 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
437 .info = conexant_ch_mode_info, \
438 .get = conexant_ch_mode_get, \
439 .put = conexant_ch_mode_put, \
440 .private_value = nid | (dir<<16) }
441
442static int cxt_gpio_data_info(struct snd_kcontrol *kcontrol,
443 struct snd_ctl_elem_info *uinfo)
444{
445 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
446 uinfo->count = 1;
447 uinfo->value.integer.min = 0;
448 uinfo->value.integer.max = 1;
449 return 0;
450}
451
452static int cxt_gpio_data_get(struct snd_kcontrol *kcontrol,
453 struct snd_ctl_elem_value *ucontrol)
454{
455 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
456 hda_nid_t nid = kcontrol->private_value & 0xffff;
457 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
458 long *valp = ucontrol->value.integer.value;
459 unsigned int val = snd_hda_codec_read(codec, nid, 0,
460 AC_VERB_GET_GPIO_DATA, 0x00);
461
462 *valp = (val & mask) != 0;
463 return 0;
464}
465
466static int cxt_gpio_data_put(struct snd_kcontrol *kcontrol,
467 struct snd_ctl_elem_value *ucontrol)
468{
469 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
470 hda_nid_t nid = kcontrol->private_value & 0xffff;
471 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
472 long val = *ucontrol->value.integer.value;
473 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
474 AC_VERB_GET_GPIO_DATA,
475 0x00);
476 unsigned int old_data = gpio_data;
477
478 /* Set/unset the masked GPIO bit(s) as needed */
479 if (val == 0)
480 gpio_data &= ~mask;
481 else
482 gpio_data |= mask;
483 if (gpio_data == old_data && !codec->in_resume)
484 return 0;
485 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data);
486 return 1;
487}
488
489#define CXT_GPIO_DATA_SWITCH(xname, nid, mask) \
490 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
491 .info = cxt_gpio_data_info, \
492 .get = cxt_gpio_data_get, \
493 .put = cxt_gpio_data_put, \
494 .private_value = nid | (mask<<16) }
495
496static int cxt_spdif_ctrl_info(struct snd_kcontrol *kcontrol,
497 struct snd_ctl_elem_info *uinfo)
498{
499 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
500 uinfo->count = 1;
501 uinfo->value.integer.min = 0;
502 uinfo->value.integer.max = 1;
503 return 0;
504}
505
506static int cxt_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
507 struct snd_ctl_elem_value *ucontrol)
508{
509 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
510 hda_nid_t nid = kcontrol->private_value & 0xffff;
511 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
512 long *valp = ucontrol->value.integer.value;
513 unsigned int val = snd_hda_codec_read(codec, nid, 0,
514 AC_VERB_GET_DIGI_CONVERT, 0x00);
515
516 *valp = (val & mask) != 0;
517 return 0;
518}
519
520static int cxt_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
521 struct snd_ctl_elem_value *ucontrol)
522{
523 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
524 hda_nid_t nid = kcontrol->private_value & 0xffff;
525 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
526 long val = *ucontrol->value.integer.value;
527 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
528 AC_VERB_GET_DIGI_CONVERT,
529 0x00);
530 unsigned int old_data = ctrl_data;
531
532 /* Set/unset the masked control bit(s) as needed */
533 if (val == 0)
534 ctrl_data &= ~mask;
535 else
536 ctrl_data |= mask;
537 if (ctrl_data == old_data && !codec->in_resume)
538 return 0;
539 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
540 ctrl_data);
541 return 1;
542}
543
544#define CXT_SPDIF_CTRL_SWITCH(xname, nid, mask) \
545 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
546 .info = cxt_spdif_ctrl_info, \
547 .get = cxt_spdif_ctrl_get, \
548 .put = cxt_spdif_ctrl_put, \
549 .private_value = nid | (mask<<16) }
550
551#endif /* CONFIG_SND_DEBUG */
552
553/* Conexant 5045 specific */
554
555static hda_nid_t cxt5045_dac_nids[1] = { 0x19 };
556static hda_nid_t cxt5045_adc_nids[1] = { 0x1a };
557static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a };
558#define CXT5045_SPDIF_OUT 0x13
559
560static struct hda_channel_mode cxt5045_modes[1] = {
561 { 2, NULL },
562};
563
564static struct hda_input_mux cxt5045_capture_source = {
565 .num_items = 2,
566 .items = {
567 { "ExtMic", 0x1 },
568 { "LineIn", 0x2 },
569 }
570};
571
572/* turn on/off EAPD (+ mute HP) as a master switch */
573static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_value *ucontrol)
575{
576 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
577 struct conexant_spec *spec = codec->spec;
578
579 if (!conexant_eapd_put(kcontrol, ucontrol))
580 return 0;
581
582 /* toggle HP mute appropriately */
583 snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0,
584 0x80, spec->cur_eapd ? 0 : 0x80);
585 snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0,
586 0x80, spec->cur_eapd ? 0 : 0x80);
587 return 1;
588}
589
590/* bind volumes of both NID 0x10 and 0x11 */
591static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol,
592 struct snd_ctl_elem_value *ucontrol)
593{
594 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
595 long *valp = ucontrol->value.integer.value;
596 int change;
597
598 change = snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0,
599 0x7f, valp[0] & 0x7f);
600 change |= snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0,
601 0x7f, valp[1] & 0x7f);
602 snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0,
603 0x7f, valp[0] & 0x7f);
604 snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0,
605 0x7f, valp[1] & 0x7f);
606 return change;
607}
608
609
610/* mute internal speaker if HP is plugged */
611static void cxt5045_hp_automute(struct hda_codec *codec)
612{
613 unsigned int present;
614
615 present = snd_hda_codec_read(codec, 0x11, 0,
616 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
617 snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0,
618 0x80, present ? 0x80 : 0);
619 snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0,
620 0x80, present ? 0x80 : 0);
621}
622
623/* unsolicited event for HP jack sensing */
624static void cxt5045_hp_unsol_event(struct hda_codec *codec,
625 unsigned int res)
626{
627 res >>= 26;
628 switch (res) {
629 case CONEXANT_HP_EVENT:
630 cxt5045_hp_automute(codec);
631 break;
632 }
633}
634
635static struct snd_kcontrol_new cxt5045_mixers[] = {
636 {
637 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
638 .name = "Capture Source",
639 .info = conexant_mux_enum_info,
640 .get = conexant_mux_enum_get,
641 .put = conexant_mux_enum_put
642 },
643 HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x17, 0x02, HDA_INPUT),
644 HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x17, 0x02, HDA_INPUT),
645 HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x02, HDA_INPUT),
646 HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x02, HDA_INPUT),
647 {
648 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
649 .name = "Master Playback Volume",
650 .info = snd_hda_mixer_amp_volume_info,
651 .get = snd_hda_mixer_amp_volume_get,
652 .put = cxt5045_hp_master_vol_put,
653 .private_value = HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
654 },
655 {
656 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
657 .name = "Master Playback Switch",
658 .info = conexant_eapd_info,
659 .get = conexant_eapd_get,
660 .put = cxt5045_hp_master_sw_put,
661 .private_value = 0x11,
662 },
663
664 {}
665};
666
667static struct hda_verb cxt5045_init_verbs[] = {
668 /* Line in, Mic */
669 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
671 /* HP, Amp */
672 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
673 {0x1A, AC_VERB_SET_CONNECT_SEL,0x01},
674 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
675 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
676 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
677 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
678 /* Record selector: Front mic */
679 {0x14, AC_VERB_SET_CONNECT_SEL,0x03},
680 {0x17, AC_VERB_SET_AMP_GAIN_MUTE,
681 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
682 /* SPDIF route: PCM */
683 { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 },
684 /* pin sensing on HP and Mic jacks */
685 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
686 /* EAPD */
687 {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x0 }, /* default on */
688 { } /* end */
689};
690
691#ifdef CONFIG_SND_DEBUG
692/* Test configuration for debugging, modelled after the ALC260 test
693 * configuration.
694 */
695static struct hda_input_mux cxt5045_test_capture_source = {
696 .num_items = 5,
697 .items = {
698 { "MIXER", 0x0 },
699 { "MIC1 pin", 0x1 },
700 { "LINE1 pin", 0x2 },
701 { "HP-OUT pin", 0x3 },
702 { "CD pin", 0x4 },
703 },
704};
705
706static struct snd_kcontrol_new cxt5045_test_mixer[] = {
707
708 /* Output controls */
709 HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x19, 0x00, HDA_OUTPUT),
710 HDA_CODEC_MUTE("OutAmp-1 Switch", 0x19,0x00, HDA_OUTPUT),
711 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT),
712 HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT),
713
714 /* Modes for retasking pin widgets */
715 CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT),
716 CXT_PIN_MODE("LINE1 pin mode", 0x12, CXT_PIN_DIR_INOUT),
717
718 /* Loopback mixer controls */
719 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x17, 0x01, HDA_INPUT),
720 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x17, 0x01, HDA_INPUT),
721 HDA_CODEC_VOLUME("LINE loopback Playback Volume", 0x17, 0x02, HDA_INPUT),
722 HDA_CODEC_MUTE("LINE loopback Playback Switch", 0x17, 0x02, HDA_INPUT),
723 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x17, 0x03, HDA_INPUT),
724 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x17, 0x03, HDA_INPUT),
725 HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x04, HDA_INPUT),
726 HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x04, HDA_INPUT),
727
728 /* Controls for GPIO pins, assuming they exist and are configured as outputs */
729 CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
730#if 0 /* limit this to one GPIO pin for now */
731 CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
732 CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
733 CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
734#endif
735 CXT_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x13, 0x01),
736
737 HDA_CODEC_VOLUME("Capture Volume", 0x17, 0x0, HDA_OUTPUT),
738 HDA_CODEC_MUTE("Capture Switch", 0x17, 0x0, HDA_OUTPUT),
739 {
740 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
741 .name = "Input Source",
742 .info = conexant_mux_enum_info,
743 .get = conexant_mux_enum_get,
744 .put = conexant_mux_enum_put,
745 },
746
747 { } /* end */
748};
749
750static struct hda_verb cxt5045_test_init_verbs[] = {
751 /* Enable all GPIOs as outputs with an initial value of 0 */
752 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
753 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
754 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
755
756 /* Enable retasking pins as output, initially without power amp */
757 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
758 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
759
760 /* Disable digital (SPDIF) pins initially, but users can enable
761 * them via a mixer switch. In the case of SPDIF-out, this initverb
762 * payload also sets the generation to 0, output to be in "consumer"
763 * PCM format, copyright asserted, no pre-emphasis and no validity
764 * control.
765 */
766 {0x13, AC_VERB_SET_DIGI_CONVERT_1, 0},
767
768 /* Start with output sum widgets muted and their output gains at min */
769 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
770 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
771
772 /* Unmute retasking pin widget output buffers since the default
773 * state appears to be output. As the pin mode is changed by the
774 * user the pin mode control will take care of enabling the pin's
775 * input/output buffers as needed.
776 */
777 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
778 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
779
780 /* Mute capture amp left and right */
781 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
782
783 /* Set ADC connection select to match default mixer setting (mic1
784 * pin)
785 */
786 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
787
788 /* Mute all inputs to mixer widget (even unconnected ones) */
789 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */
790 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Mic1 pin */
791 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* Line pin */
792 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* HP pin */
793 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
794
795 { }
796};
797#endif
798
799
800/* initialize jack-sensing, too */
801static int cxt5045_init(struct hda_codec *codec)
802{
803 conexant_init(codec);
804 cxt5045_hp_automute(codec);
805 return 0;
806}
807
808
809enum {
810 CXT5045_LAPTOP, /* Laptops w/ EAPD support */
811#ifdef CONFIG_SND_DEBUG
812 CXT5045_TEST,
813#endif
814 CXT5045_MODELS
815};
816
817static const char *cxt5045_models[CXT5045_MODELS] = {
818 [CXT5045_LAPTOP] = "laptop",
819#ifdef CONFIG_SND_DEBUG
820 [CXT5045_TEST] = "test",
821#endif
822};
823
824static struct snd_pci_quirk cxt5045_cfg_tbl[] = {
825 SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP),
826 {}
827};
828
829static int patch_cxt5045(struct hda_codec *codec)
830{
831 struct conexant_spec *spec;
832 int board_config;
833
834 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
835 if (!spec)
836 return -ENOMEM;
837 mutex_init(&spec->amp_mutex);
838 codec->spec = spec;
839
840 spec->multiout.max_channels = 2;
841 spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids);
842 spec->multiout.dac_nids = cxt5045_dac_nids;
843 spec->multiout.dig_out_nid = CXT5045_SPDIF_OUT;
844 spec->num_adc_nids = 1;
845 spec->adc_nids = cxt5045_adc_nids;
846 spec->capsrc_nids = cxt5045_capsrc_nids;
847 spec->input_mux = &cxt5045_capture_source;
848 spec->num_mixers = 1;
849 spec->mixers[0] = cxt5045_mixers;
850 spec->num_init_verbs = 1;
851 spec->init_verbs[0] = cxt5045_init_verbs;
852 spec->spdif_route = 0;
853 spec->num_channel_mode = ARRAY_SIZE(cxt5045_modes),
854 spec->channel_mode = cxt5045_modes,
855
856
857 codec->patch_ops = conexant_patch_ops;
858 codec->patch_ops.unsol_event = cxt5045_hp_unsol_event;
859
860 board_config = snd_hda_check_board_config(codec, CXT5045_MODELS,
861 cxt5045_models,
862 cxt5045_cfg_tbl);
863 switch (board_config) {
864 case CXT5045_LAPTOP:
865 spec->input_mux = &cxt5045_capture_source;
866 spec->num_init_verbs = 2;
867 spec->init_verbs[1] = cxt5045_init_verbs;
868 spec->mixers[0] = cxt5045_mixers;
869 codec->patch_ops.init = cxt5045_init;
870 break;
871#ifdef CONFIG_SND_DEBUG
872 case CXT5045_TEST:
873 spec->input_mux = &cxt5045_test_capture_source;
874 spec->mixers[0] = cxt5045_test_mixer;
875 spec->init_verbs[0] = cxt5045_test_init_verbs;
876#endif
877 }
878 return 0;
879}
880
881
882/* Conexant 5047 specific */
883
884static hda_nid_t cxt5047_dac_nids[1] = { 0x10 };
885static hda_nid_t cxt5047_adc_nids[1] = { 0x12 };
886static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a };
887#define CXT5047_SPDIF_OUT 0x11
888
889static struct hda_channel_mode cxt5047_modes[1] = {
890 { 2, NULL },
891};
892
893static struct hda_input_mux cxt5047_capture_source = {
894 .num_items = 2,
895 .items = {
896 { "ExtMic", 0x1 },
897 { "IntMic", 0x2 },
898 }
899};
900
901static struct hda_input_mux cxt5047_hp_capture_source = {
902 .num_items = 1,
903 .items = {
904 { "ExtMic", 0x1 },
905 }
906};
907
908/* turn on/off EAPD (+ mute HP) as a master switch */
909static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
910 struct snd_ctl_elem_value *ucontrol)
911{
912 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
913 struct conexant_spec *spec = codec->spec;
914
915 if (!conexant_eapd_put(kcontrol, ucontrol))
916 return 0;
917
918 /* toggle HP mute appropriately */
919 snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0,
920 0x80, spec->cur_eapd ? 0 : 0x80);
921 snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0,
922 0x80, spec->cur_eapd ? 0 : 0x80);
923 return 1;
924}
925
926#if 0
927/* bind volumes of both NID 0x13 and 0x1d */
928static int cxt5047_hp_master_vol_put(struct snd_kcontrol *kcontrol,
929 struct snd_ctl_elem_value *ucontrol)
930{
931 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
932 long *valp = ucontrol->value.integer.value;
933 int change;
934
935 change = snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0,
936 0x7f, valp[0] & 0x7f);
937 change |= snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0,
938 0x7f, valp[1] & 0x7f);
939 snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0,
940 0x7f, valp[0] & 0x7f);
941 snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0,
942 0x7f, valp[1] & 0x7f);
943 return change;
944}
945#endif
946
947/* mute internal speaker if HP is plugged */
948static void cxt5047_hp_automute(struct hda_codec *codec)
949{
950 unsigned int present;
951
952 present = snd_hda_codec_read(codec, 0x13, 0,
953 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
954 snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0,
955 0x80, present ? 0x80 : 0);
956 snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0,
957 0x80, present ? 0x80 : 0);
958}
959
960/* toggle input of built-in and mic jack appropriately */
961static void cxt5047_hp_automic(struct hda_codec *codec)
962{
963 static struct hda_verb mic_jack_on[] = {
964 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
965 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
966 {}
967 };
968 static struct hda_verb mic_jack_off[] = {
969 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
970 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
971 {}
972 };
973 unsigned int present;
974
975 present = snd_hda_codec_read(codec, 0x08, 0,
976 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
977 if (present)
978 snd_hda_sequence_write(codec, mic_jack_on);
979 else
980 snd_hda_sequence_write(codec, mic_jack_off);
981}
982
983/* unsolicited event for HP jack sensing */
984static void cxt5047_hp_unsol_event(struct hda_codec *codec,
985 unsigned int res)
986{
987 res >>= 26;
988 switch (res) {
989 case CONEXANT_HP_EVENT:
990 cxt5047_hp_automute(codec);
991 break;
992 case CONEXANT_MIC_EVENT:
993 cxt5047_hp_automic(codec);
994 break;
995 }
996}
997
998static struct snd_kcontrol_new cxt5047_mixers[] = {
999 {
1000 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1001 .name = "Capture Source",
1002 .info = conexant_mux_enum_info,
1003 .get = conexant_mux_enum_get,
1004 .put = conexant_mux_enum_put
1005 },
1006 HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT),
1007 HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT),
1008 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1009 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1010 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1011 HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1012 HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1013 {
1014 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1015 .name = "Master Playback Switch",
1016 .info = conexant_eapd_info,
1017 .get = conexant_eapd_get,
1018 .put = cxt5047_hp_master_sw_put,
1019 .private_value = 0x13,
1020 },
1021
1022 {}
1023};
1024
1025static struct snd_kcontrol_new cxt5047_hp_mixers[] = {
1026 {
1027 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1028 .name = "Capture Source",
1029 .info = conexant_mux_enum_info,
1030 .get = conexant_mux_enum_get,
1031 .put = conexant_mux_enum_put
1032 },
1033 HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT),
1034 HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19,0x02,HDA_INPUT),
1035 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1036 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1037 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
1038 HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT),
1039 HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT),
1040 {
1041 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1042 .name = "Master Playback Switch",
1043 .info = conexant_eapd_info,
1044 .get = conexant_eapd_get,
1045 .put = cxt5047_hp_master_sw_put,
1046 .private_value = 0x13,
1047 },
1048 { } /* end */
1049};
1050
1051static struct hda_verb cxt5047_init_verbs[] = {
1052 /* Line in, Mic, Built-in Mic */
1053 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1054 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1055 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 },
1056 /* HP, Amp */
1057 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1058 {0x1A, AC_VERB_SET_CONNECT_SEL,0x03},
1059 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1060 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00},
1061 {0x1A, AC_VERB_SET_AMP_GAIN_MUTE,
1062 AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03},
1063 /* Record selector: Front mic */
1064 {0x12, AC_VERB_SET_CONNECT_SEL,0x03},
1065 {0x19, AC_VERB_SET_AMP_GAIN_MUTE,
1066 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
1067 /* SPDIF route: PCM */
1068 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 },
1069 { } /* end */
1070};
1071
1072/* configuration for Toshiba Laptops */
1073static struct hda_verb cxt5047_toshiba_init_verbs[] = {
1074 {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0 }, /* default on */
1075 /* pin sensing on HP and Mic jacks */
1076 {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1077 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
1078 {}
1079};
1080
1081/* configuration for HP Laptops */
1082static struct hda_verb cxt5047_hp_init_verbs[] = {
1083 /* pin sensing on HP and Mic jacks */
1084 {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT},
1085 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT},
1086 {}
1087};
1088
1089/* Test configuration for debugging, modelled after the ALC260 test
1090 * configuration.
1091 */
1092#ifdef CONFIG_SND_DEBUG
1093static struct hda_input_mux cxt5047_test_capture_source = {
1094 .num_items = 5,
1095 .items = {
1096 { "MIXER", 0x0 },
1097 { "LINE1 pin", 0x1 },
1098 { "MIC1 pin", 0x2 },
1099 { "MIC2 pin", 0x3 },
1100 { "CD pin", 0x4 },
1101 },
1102};
1103
1104static struct snd_kcontrol_new cxt5047_test_mixer[] = {
1105
1106 /* Output only controls */
1107 HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x00, HDA_OUTPUT),
1108 HDA_CODEC_MUTE("OutAmp-1 Switch", 0x10,0x00, HDA_OUTPUT),
1109 HDA_CODEC_VOLUME("OutAmp-2 Volume", 0x1c, 0x00, HDA_OUTPUT),
1110 HDA_CODEC_MUTE("OutAmp-2 Switch", 0x1c, 0x00, HDA_OUTPUT),
1111 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1112 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1113 HDA_CODEC_VOLUME("HeadPhone Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1114 HDA_CODEC_MUTE("HeadPhone Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1115
1116 /* Modes for retasking pin widgets */
1117 CXT_PIN_MODE("LINE1 pin mode", 0x14, CXT_PIN_DIR_INOUT),
1118 CXT_PIN_MODE("MIC1 pin mode", 0x15, CXT_PIN_DIR_INOUT),
1119
1120 /* Loopback mixer controls */
1121 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x19, 0x02, HDA_INPUT),
1122 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x19, 0x02, HDA_INPUT),
1123 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x19, 0x03, HDA_INPUT),
1124 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x19, 0x03, HDA_INPUT),
1125 HDA_CODEC_VOLUME("LINE Playback Volume", 0x19, 0x01, HDA_INPUT),
1126 HDA_CODEC_MUTE("LINE Playback Switch", 0x19, 0x01, HDA_INPUT),
1127 HDA_CODEC_VOLUME("CD Playback Volume", 0x19, 0x04, HDA_INPUT),
1128 HDA_CODEC_MUTE("CD Playback Switch", 0x19, 0x04, HDA_INPUT),
1129
1130#if 0
1131 /* Controls for GPIO pins, assuming they exist and are configured as outputs */
1132 CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
1133 CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
1134 CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
1135 CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
1136#endif
1137 CXT_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x18, 0x01),
1138
1139 HDA_CODEC_VOLUME("Capture Volume", 0x19, 0x0, HDA_OUTPUT),
1140 HDA_CODEC_MUTE("Capture Switch", 0x19, 0x0, HDA_OUTPUT),
1141 {
1142 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1143 .name = "Input Source",
1144 .info = conexant_mux_enum_info,
1145 .get = conexant_mux_enum_get,
1146 .put = conexant_mux_enum_put,
1147 },
1148
1149 { } /* end */
1150};
1151
1152static struct hda_verb cxt5047_test_init_verbs[] = {
1153 /* Enable all GPIOs as outputs with an initial value of 0 */
1154 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
1155 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
1156 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
1157
1158 /* Enable retasking pins as output, initially without power amp */
1159 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1160 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1161 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1162
1163 /* Disable digital (SPDIF) pins initially, but users can enable
1164 * them via a mixer switch. In the case of SPDIF-out, this initverb
1165 * payload also sets the generation to 0, output to be in "consumer"
1166 * PCM format, copyright asserted, no pre-emphasis and no validity
1167 * control.
1168 */
1169 {0x18, AC_VERB_SET_DIGI_CONVERT_1, 0},
1170
1171 /* Ensure mic1, mic2, line1 pin widgets take input from the
1172 * OUT1 sum bus when acting as an output.
1173 */
1174 {0x1a, AC_VERB_SET_CONNECT_SEL, 0},
1175 {0x1b, AC_VERB_SET_CONNECT_SEL, 0},
1176
1177 /* Start with output sum widgets muted and their output gains at min */
1178 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1179 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
1180
1181 /* Unmute retasking pin widget output buffers since the default
1182 * state appears to be output. As the pin mode is changed by the
1183 * user the pin mode control will take care of enabling the pin's
1184 * input/output buffers as needed.
1185 */
1186 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1187 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1188 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1189
1190 /* Mute capture amp left and right */
1191 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
1192
1193 /* Set ADC connection select to match default mixer setting (mic1
1194 * pin)
1195 */
1196 {0x12, AC_VERB_SET_CONNECT_SEL, 0x00},
1197
1198 /* Mute all inputs to mixer widget (even unconnected ones) */
1199 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
1200 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
1201 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
1202 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
1203 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
1204 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
1205 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
1206 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
1207
1208 { }
1209};
1210#endif
1211
1212
1213/* initialize jack-sensing, too */
1214static int cxt5047_hp_init(struct hda_codec *codec)
1215{
1216 conexant_init(codec);
1217 cxt5047_hp_automute(codec);
1218 cxt5047_hp_automic(codec);
1219 return 0;
1220}
1221
1222
1223enum {
1224 CXT5047_LAPTOP, /* Laptops w/o EAPD support */
1225 CXT5047_LAPTOP_HP, /* Some HP laptops */
1226 CXT5047_LAPTOP_EAPD, /* Laptops with EAPD support */
1227#ifdef CONFIG_SND_DEBUG
1228 CXT5047_TEST,
1229#endif
1230 CXT5047_MODELS
1231};
1232
1233static const char *cxt5047_models[CXT5047_MODELS] = {
1234 [CXT5047_LAPTOP] = "laptop",
1235 [CXT5047_LAPTOP_HP] = "laptop-hp",
1236 [CXT5047_LAPTOP_EAPD] = "laptop-eapd",
1237#ifdef CONFIG_SND_DEBUG
1238 [CXT5047_TEST] = "test",
1239#endif
1240};
1241
1242static struct snd_pci_quirk cxt5047_cfg_tbl[] = {
1243 SND_PCI_QUIRK(0x103c, 0x30a0, "HP DV1000", CXT5047_LAPTOP),
1244 SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV2000T/DV3000T", CXT5047_LAPTOP),
1245 SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP),
1246 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD),
1247 {}
1248};
1249
1250static int patch_cxt5047(struct hda_codec *codec)
1251{
1252 struct conexant_spec *spec;
1253 int board_config;
1254
1255 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1256 if (!spec)
1257 return -ENOMEM;
1258 mutex_init(&spec->amp_mutex);
1259 codec->spec = spec;
1260
1261 spec->multiout.max_channels = 2;
1262 spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids);
1263 spec->multiout.dac_nids = cxt5047_dac_nids;
1264 spec->multiout.dig_out_nid = CXT5047_SPDIF_OUT;
1265 spec->num_adc_nids = 1;
1266 spec->adc_nids = cxt5047_adc_nids;
1267 spec->capsrc_nids = cxt5047_capsrc_nids;
1268 spec->input_mux = &cxt5047_capture_source;
1269 spec->num_mixers = 1;
1270 spec->mixers[0] = cxt5047_mixers;
1271 spec->num_init_verbs = 1;
1272 spec->init_verbs[0] = cxt5047_init_verbs;
1273 spec->spdif_route = 0;
1274 spec->num_channel_mode = ARRAY_SIZE(cxt5047_modes),
1275 spec->channel_mode = cxt5047_modes,
1276
1277 codec->patch_ops = conexant_patch_ops;
1278 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event;
1279
1280 board_config = snd_hda_check_board_config(codec, CXT5047_MODELS,
1281 cxt5047_models,
1282 cxt5047_cfg_tbl);
1283 switch (board_config) {
1284 case CXT5047_LAPTOP:
1285 break;
1286 case CXT5047_LAPTOP_HP:
1287 spec->input_mux = &cxt5047_hp_capture_source;
1288 spec->num_init_verbs = 2;
1289 spec->init_verbs[1] = cxt5047_hp_init_verbs;
1290 spec->mixers[0] = cxt5047_hp_mixers;
1291 codec->patch_ops.init = cxt5047_hp_init;
1292 break;
1293 case CXT5047_LAPTOP_EAPD:
1294 spec->num_init_verbs = 2;
1295 spec->init_verbs[1] = cxt5047_toshiba_init_verbs;
1296 break;
1297#ifdef CONFIG_SND_DEBUG
1298 case CXT5047_TEST:
1299 spec->input_mux = &cxt5047_test_capture_source;
1300 spec->mixers[0] = cxt5047_test_mixer;
1301 spec->init_verbs[0] = cxt5047_test_init_verbs;
1302#endif
1303 }
1304 return 0;
1305}
1306
1307struct hda_codec_preset snd_hda_preset_conexant[] = {
1308 { .id = 0x14f15045, .name = "CXT5045", .patch = patch_cxt5045 },
1309 { .id = 0x14f15047, .name = "CXT5047", .patch = patch_cxt5047 },
1310 {} /* terminator */
1311};
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4e0c3c1b908b..145682b78071 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -32,6 +32,10 @@
32#include "hda_codec.h" 32#include "hda_codec.h"
33#include "hda_local.h" 33#include "hda_local.h"
34 34
35#define ALC880_FRONT_EVENT 0x01
36#define ALC880_DCVOL_EVENT 0x02
37#define ALC880_HP_EVENT 0x04
38#define ALC880_MIC_EVENT 0x08
35 39
36/* ALC880 board config type */ 40/* ALC880 board config type */
37enum { 41enum {
@@ -48,7 +52,10 @@ enum {
48 ALC880_ASUS_DIG, 52 ALC880_ASUS_DIG,
49 ALC880_ASUS_W1V, 53 ALC880_ASUS_W1V,
50 ALC880_ASUS_DIG2, 54 ALC880_ASUS_DIG2,
55 ALC880_FUJITSU,
51 ALC880_UNIWILL_DIG, 56 ALC880_UNIWILL_DIG,
57 ALC880_UNIWILL,
58 ALC880_UNIWILL_P53,
52 ALC880_CLEVO, 59 ALC880_CLEVO,
53 ALC880_TCL_S700, 60 ALC880_TCL_S700,
54 ALC880_LG, 61 ALC880_LG,
@@ -77,8 +84,12 @@ enum {
77/* ALC262 models */ 84/* ALC262 models */
78enum { 85enum {
79 ALC262_BASIC, 86 ALC262_BASIC,
87 ALC262_HIPPO,
88 ALC262_HIPPO_1,
80 ALC262_FUJITSU, 89 ALC262_FUJITSU,
81 ALC262_HP_BPC, 90 ALC262_HP_BPC,
91 ALC262_HP_BPC_D7000_WL,
92 ALC262_HP_BPC_D7000_WF,
82 ALC262_BENQ_ED8, 93 ALC262_BENQ_ED8,
83 ALC262_AUTO, 94 ALC262_AUTO,
84 ALC262_MODEL_LAST /* last tag */ 95 ALC262_MODEL_LAST /* last tag */
@@ -91,16 +102,30 @@ enum {
91 ALC861_3ST_DIG, 102 ALC861_3ST_DIG,
92 ALC861_6ST_DIG, 103 ALC861_6ST_DIG,
93 ALC861_UNIWILL_M31, 104 ALC861_UNIWILL_M31,
105 ALC861_TOSHIBA,
106 ALC861_ASUS,
107 ALC861_ASUS_LAPTOP,
94 ALC861_AUTO, 108 ALC861_AUTO,
95 ALC861_MODEL_LAST, 109 ALC861_MODEL_LAST,
96}; 110};
97 111
112/* ALC861-VD models */
113enum {
114 ALC660VD_3ST,
115 ALC861VD_3ST,
116 ALC861VD_3ST_DIG,
117 ALC861VD_6ST_DIG,
118 ALC861VD_AUTO,
119 ALC861VD_MODEL_LAST,
120};
121
98/* ALC882 models */ 122/* ALC882 models */
99enum { 123enum {
100 ALC882_3ST_DIG, 124 ALC882_3ST_DIG,
101 ALC882_6ST_DIG, 125 ALC882_6ST_DIG,
102 ALC882_ARIMA, 126 ALC882_ARIMA,
103 ALC882_AUTO, 127 ALC882_AUTO,
128 ALC885_MACPRO,
104 ALC882_MODEL_LAST, 129 ALC882_MODEL_LAST,
105}; 130};
106 131
@@ -110,8 +135,12 @@ enum {
110 ALC883_3ST_6ch_DIG, 135 ALC883_3ST_6ch_DIG,
111 ALC883_3ST_6ch, 136 ALC883_3ST_6ch,
112 ALC883_6ST_DIG, 137 ALC883_6ST_DIG,
138 ALC883_TARGA_DIG,
139 ALC883_TARGA_2ch_DIG,
113 ALC888_DEMO_BOARD, 140 ALC888_DEMO_BOARD,
114 ALC883_ACER, 141 ALC883_ACER,
142 ALC883_MEDION,
143 ALC883_LAPTOP_EAPD,
115 ALC883_AUTO, 144 ALC883_AUTO,
116 ALC883_MODEL_LAST, 145 ALC883_MODEL_LAST,
117}; 146};
@@ -1015,6 +1044,60 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
1015 { } /* end */ 1044 { } /* end */
1016}; 1045};
1017 1046
1047/* Uniwill */
1048static struct snd_kcontrol_new alc880_uniwill_mixer[] = {
1049 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1050 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1051 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1052 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1053 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
1054 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
1055 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
1056 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
1057 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1058 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1059 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
1060 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
1061 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1062 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1063 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1064 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1065 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
1066 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
1067 {
1068 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1069 .name = "Channel Mode",
1070 .info = alc_ch_mode_info,
1071 .get = alc_ch_mode_get,
1072 .put = alc_ch_mode_put,
1073 },
1074 { } /* end */
1075};
1076
1077static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
1078 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1079 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
1080 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1081 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
1082 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
1083 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
1084 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1085 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1086 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
1087 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
1088 { } /* end */
1089};
1090
1091static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
1092 HDA_CODEC_VOLUME("HPhone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
1093 HDA_BIND_MUTE("HPhone Playback Switch", 0x0c, 2, HDA_INPUT),
1094 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
1095 HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT),
1096 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
1097 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
1098 { } /* end */
1099};
1100
1018/* 1101/*
1019 * build control elements 1102 * build control elements
1020 */ 1103 */
@@ -1248,6 +1331,159 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = {
1248 { } 1331 { }
1249}; 1332};
1250 1333
1334/*
1335 * Uniwill pin configuration:
1336 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
1337 * line = 0x1a
1338 */
1339static struct hda_verb alc880_uniwill_init_verbs[] = {
1340 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1341
1342 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1343 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1344 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1345 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1346 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1347 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1348 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1349 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1350 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1351 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1352 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1353 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1354 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1355 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1356
1357 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1358 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1359 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1360 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1361 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1362 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1363 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
1364 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
1365 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1366
1367 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1368 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
1369
1370 { }
1371};
1372
1373/*
1374* Uniwill P53
1375* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
1376 */
1377static struct hda_verb alc880_uniwill_p53_init_verbs[] = {
1378 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
1379
1380 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1381 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1382 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1383 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1384 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
1385 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1387 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1388 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1389 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1390 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
1391 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
1392
1393 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1394 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1395 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1396 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1397 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
1398 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
1399
1400 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
1401 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
1402
1403 { }
1404};
1405
1406static struct hda_verb alc880_beep_init_verbs[] = {
1407 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
1408 { }
1409};
1410
1411/* toggle speaker-output according to the hp-jack state */
1412static void alc880_uniwill_automute(struct hda_codec *codec)
1413{
1414 unsigned int present;
1415
1416 present = snd_hda_codec_read(codec, 0x14, 0,
1417 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1418 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0,
1419 0x80, present ? 0x80 : 0);
1420 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0,
1421 0x80, present ? 0x80 : 0);
1422 snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0,
1423 0x80, present ? 0x80 : 0);
1424 snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0,
1425 0x80, present ? 0x80 : 0);
1426
1427 present = snd_hda_codec_read(codec, 0x18, 0,
1428 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1429 snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1430 0x7000 | (0x01 << 8) | (present ? 0x80 : 0));
1431}
1432
1433static void alc880_uniwill_unsol_event(struct hda_codec *codec,
1434 unsigned int res)
1435{
1436 /* Looks like the unsol event is incompatible with the standard
1437 * definition. 4bit tag is placed at 28 bit!
1438 */
1439 if ((res >> 28) == ALC880_HP_EVENT ||
1440 (res >> 28) == ALC880_MIC_EVENT)
1441 alc880_uniwill_automute(codec);
1442}
1443
1444static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec)
1445{
1446 unsigned int present;
1447
1448 present = snd_hda_codec_read(codec, 0x14, 0,
1449 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
1450
1451 snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0,
1452 0x80, present ? 0x80 : 0);
1453 snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0,
1454 0x80, present ? 0x80 : 0);
1455}
1456
1457static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
1458{
1459 unsigned int present;
1460
1461 present = snd_hda_codec_read(codec, 0x21, 0,
1462 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0) & 0x7f;
1463
1464 snd_hda_codec_amp_update(codec, 0x0c, 0, HDA_OUTPUT, 0,
1465 0x7f, present);
1466 snd_hda_codec_amp_update(codec, 0x0c, 1, HDA_OUTPUT, 0,
1467 0x7f, present);
1468
1469 snd_hda_codec_amp_update(codec, 0x0d, 0, HDA_OUTPUT, 0,
1470 0x7f, present);
1471 snd_hda_codec_amp_update(codec, 0x0d, 1, HDA_OUTPUT, 0,
1472 0x7f, present);
1473
1474}
1475static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
1476 unsigned int res)
1477{
1478 /* Looks like the unsol event is incompatible with the standard
1479 * definition. 4bit tag is placed at 28 bit!
1480 */
1481 if ((res >> 28) == ALC880_HP_EVENT)
1482 alc880_uniwill_p53_hp_automute(codec);
1483 if ((res >> 28) == ALC880_DCVOL_EVENT)
1484 alc880_uniwill_p53_dcvol_automute(codec);
1485}
1486
1251/* FIXME! */ 1487/* FIXME! */
1252/* 1488/*
1253 * F1734 pin configuration: 1489 * F1734 pin configuration:
@@ -2125,159 +2361,112 @@ static struct hda_verb alc880_test_init_verbs[] = {
2125/* 2361/*
2126 */ 2362 */
2127 2363
2128static struct hda_board_config alc880_cfg_tbl[] = { 2364static const char *alc880_models[ALC880_MODEL_LAST] = {
2129 /* Back 3 jack, front 2 jack */ 2365 [ALC880_3ST] = "3stack",
2130 { .modelname = "3stack", .config = ALC880_3ST }, 2366 [ALC880_TCL_S700] = "tcl",
2131 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe200, .config = ALC880_3ST }, 2367 [ALC880_3ST_DIG] = "3stack-digout",
2132 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe201, .config = ALC880_3ST }, 2368 [ALC880_CLEVO] = "clevo",
2133 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe202, .config = ALC880_3ST }, 2369 [ALC880_5ST] = "5stack",
2134 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe203, .config = ALC880_3ST }, 2370 [ALC880_5ST_DIG] = "5stack-digout",
2135 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe204, .config = ALC880_3ST }, 2371 [ALC880_W810] = "w810",
2136 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe205, .config = ALC880_3ST }, 2372 [ALC880_Z71V] = "z71v",
2137 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe206, .config = ALC880_3ST }, 2373 [ALC880_6ST] = "6stack",
2138 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe207, .config = ALC880_3ST }, 2374 [ALC880_6ST_DIG] = "6stack-digout",
2139 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe208, .config = ALC880_3ST }, 2375 [ALC880_ASUS] = "asus",
2140 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe209, .config = ALC880_3ST }, 2376 [ALC880_ASUS_W1V] = "asus-w1v",
2141 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20a, .config = ALC880_3ST }, 2377 [ALC880_ASUS_DIG] = "asus-dig",
2142 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20b, .config = ALC880_3ST }, 2378 [ALC880_ASUS_DIG2] = "asus-dig2",
2143 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20c, .config = ALC880_3ST }, 2379 [ALC880_UNIWILL_DIG] = "uniwill",
2144 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20d, .config = ALC880_3ST }, 2380 [ALC880_UNIWILL_P53] = "uniwill-p53",
2145 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20e, .config = ALC880_3ST }, 2381 [ALC880_FUJITSU] = "fujitsu",
2146 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe20f, .config = ALC880_3ST }, 2382 [ALC880_F1734] = "F1734",
2147 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe210, .config = ALC880_3ST }, 2383 [ALC880_LG] = "lg",
2148 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe211, .config = ALC880_3ST }, 2384 [ALC880_LG_LW] = "lg-lw",
2149 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe212, .config = ALC880_3ST },
2150 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe213, .config = ALC880_3ST },
2151 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe214, .config = ALC880_3ST },
2152 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe234, .config = ALC880_3ST },
2153 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe302, .config = ALC880_3ST },
2154 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe303, .config = ALC880_3ST },
2155 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe304, .config = ALC880_3ST },
2156 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe306, .config = ALC880_3ST },
2157 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe307, .config = ALC880_3ST },
2158 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe404, .config = ALC880_3ST },
2159 { .pci_subvendor = 0x8086, .pci_subdevice = 0xa101, .config = ALC880_3ST },
2160 { .pci_subvendor = 0x107b, .pci_subdevice = 0x3031, .config = ALC880_3ST },
2161 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4036, .config = ALC880_3ST },
2162 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4037, .config = ALC880_3ST },
2163 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4038, .config = ALC880_3ST },
2164 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4040, .config = ALC880_3ST },
2165 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4041, .config = ALC880_3ST },
2166 /* TCL S700 */
2167 { .modelname = "tcl", .config = ALC880_TCL_S700 },
2168 { .pci_subvendor = 0x19db, .pci_subdevice = 0x4188, .config = ALC880_TCL_S700 },
2169
2170 /* Back 3 jack, front 2 jack (Internal add Aux-In) */
2171 { .pci_subvendor = 0x1025, .pci_subdevice = 0xe310, .config = ALC880_3ST },
2172 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81d6, .config = ALC880_3ST },
2173 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81a0, .config = ALC880_3ST },
2174
2175 /* Back 3 jack plus 1 SPDIF out jack, front 2 jack */
2176 { .modelname = "3stack-digout", .config = ALC880_3ST_DIG },
2177 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe308, .config = ALC880_3ST_DIG },
2178 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0070, .config = ALC880_3ST_DIG },
2179
2180 /* Clevo laptops */
2181 { .modelname = "clevo", .config = ALC880_CLEVO },
2182 { .pci_subvendor = 0x1558, .pci_subdevice = 0x0520,
2183 .config = ALC880_CLEVO }, /* Clevo m520G NB */
2184 { .pci_subvendor = 0x1558, .pci_subdevice = 0x0660,
2185 .config = ALC880_CLEVO }, /* Clevo m665n */
2186
2187 /* Back 3 jack plus 1 SPDIF out jack, front 2 jack (Internal add Aux-In)*/
2188 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe305, .config = ALC880_3ST_DIG },
2189 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd402, .config = ALC880_3ST_DIG },
2190 { .pci_subvendor = 0x1025, .pci_subdevice = 0xe309, .config = ALC880_3ST_DIG },
2191
2192 /* Back 5 jack, front 2 jack */
2193 { .modelname = "5stack", .config = ALC880_5ST },
2194 { .pci_subvendor = 0x107b, .pci_subdevice = 0x3033, .config = ALC880_5ST },
2195 { .pci_subvendor = 0x107b, .pci_subdevice = 0x4039, .config = ALC880_5ST },
2196 { .pci_subvendor = 0x107b, .pci_subdevice = 0x3032, .config = ALC880_5ST },
2197 { .pci_subvendor = 0x103c, .pci_subdevice = 0x2a09, .config = ALC880_5ST },
2198 { .pci_subvendor = 0x1043, .pci_subdevice = 0x814e, .config = ALC880_5ST },
2199
2200 /* Back 5 jack plus 1 SPDIF out jack, front 2 jack */
2201 { .modelname = "5stack-digout", .config = ALC880_5ST_DIG },
2202 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe224, .config = ALC880_5ST_DIG },
2203 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe400, .config = ALC880_5ST_DIG },
2204 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe401, .config = ALC880_5ST_DIG },
2205 { .pci_subvendor = 0x8086, .pci_subdevice = 0xe402, .config = ALC880_5ST_DIG },
2206 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd400, .config = ALC880_5ST_DIG },
2207 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd401, .config = ALC880_5ST_DIG },
2208 { .pci_subvendor = 0x8086, .pci_subdevice = 0xa100, .config = ALC880_5ST_DIG },
2209 { .pci_subvendor = 0x1565, .pci_subdevice = 0x8202, .config = ALC880_5ST_DIG },
2210 { .pci_subvendor = 0x1019, .pci_subdevice = 0xa880, .config = ALC880_5ST_DIG },
2211 { .pci_subvendor = 0xa0a0, .pci_subdevice = 0x0560,
2212 .config = ALC880_5ST_DIG }, /* Aopen i915GMm-HFS */
2213 /* { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_5ST_DIG }, */ /* conflict with 6stack */
2214 { .pci_subvendor = 0x1695, .pci_subdevice = 0x400d, .config = ALC880_5ST_DIG },
2215 /* note subvendor = 0 below */
2216 /* { .pci_subvendor = 0x0000, .pci_subdevice = 0x8086, .config = ALC880_5ST_DIG }, */
2217
2218 { .modelname = "w810", .config = ALC880_W810 },
2219 { .pci_subvendor = 0x161f, .pci_subdevice = 0x203d, .config = ALC880_W810 },
2220
2221 { .modelname = "z71v", .config = ALC880_Z71V },
2222 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_Z71V },
2223
2224 { .modelname = "6stack", .config = ALC880_6ST },
2225 { .pci_subvendor = 0x1043, .pci_subdevice = 0x8196, .config = ALC880_6ST }, /* ASUS P5GD1-HVM */
2226 { .pci_subvendor = 0x1043, .pci_subdevice = 0x81b4, .config = ALC880_6ST },
2227 { .pci_subvendor = 0x1019, .pci_subdevice = 0xa884, .config = ALC880_6ST }, /* Acer APFV */
2228 { .pci_subvendor = 0x1458, .pci_subdevice = 0xa102, .config = ALC880_6ST }, /* Gigabyte K8N51 */
2229
2230 { .modelname = "6stack-digout", .config = ALC880_6ST_DIG },
2231 { .pci_subvendor = 0x2668, .pci_subdevice = 0x8086, .config = ALC880_6ST_DIG },
2232 { .pci_subvendor = 0x8086, .pci_subdevice = 0x2668, .config = ALC880_6ST_DIG },
2233 { .pci_subvendor = 0x1462, .pci_subdevice = 0x1150, .config = ALC880_6ST_DIG },
2234 { .pci_subvendor = 0xe803, .pci_subdevice = 0x1019, .config = ALC880_6ST_DIG },
2235 { .pci_subvendor = 0x1039, .pci_subdevice = 0x1234, .config = ALC880_6ST_DIG },
2236 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0077, .config = ALC880_6ST_DIG },
2237 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0078, .config = ALC880_6ST_DIG },
2238 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0087, .config = ALC880_6ST_DIG },
2239 { .pci_subvendor = 0x1297, .pci_subdevice = 0xc790, .config = ALC880_6ST_DIG }, /* Shuttle ST20G5 */
2240 { .pci_subvendor = 0x1509, .pci_subdevice = 0x925d, .config = ALC880_6ST_DIG }, /* FIC P4M-915GD1 */
2241 { .pci_subvendor = 0x1695, .pci_subdevice = 0x4012, .config = ALC880_5ST_DIG }, /* Epox EP-5LDA+ GLi */
2242
2243 { .modelname = "asus", .config = ALC880_ASUS },
2244 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1964, .config = ALC880_ASUS_DIG },
2245 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1973, .config = ALC880_ASUS_DIG },
2246 { .pci_subvendor = 0x1043, .pci_subdevice = 0x19b3, .config = ALC880_ASUS_DIG },
2247 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1113, .config = ALC880_ASUS_DIG },
2248 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1173, .config = ALC880_ASUS_DIG },
2249 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1993, .config = ALC880_ASUS },
2250 { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c2, .config = ALC880_ASUS_DIG }, /* Asus W6A */
2251 { .pci_subvendor = 0x1043, .pci_subdevice = 0x10c3, .config = ALC880_ASUS_DIG },
2252 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1133, .config = ALC880_ASUS },
2253 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1123, .config = ALC880_ASUS_DIG },
2254 { .pci_subvendor = 0x1043, .pci_subdevice = 0x1143, .config = ALC880_ASUS },
2255 { .modelname = "asus-w1v", .config = ALC880_ASUS_W1V },
2256 { .pci_subvendor = 0x1043, .pci_subdevice = 0x10b3, .config = ALC880_ASUS_W1V },
2257 { .modelname = "asus-dig", .config = ALC880_ASUS_DIG },
2258 { .pci_subvendor = 0x1043, .pci_subdevice = 0x8181, .config = ALC880_ASUS_DIG }, /* ASUS P4GPL-X */
2259 { .modelname = "asus-dig2", .config = ALC880_ASUS_DIG2 },
2260 { .pci_subvendor = 0x1558, .pci_subdevice = 0x5401, .config = ALC880_ASUS_DIG2 },
2261
2262 { .modelname = "uniwill", .config = ALC880_UNIWILL_DIG },
2263 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9050, .config = ALC880_UNIWILL_DIG },
2264
2265 { .modelname = "F1734", .config = ALC880_F1734 },
2266 { .pci_subvendor = 0x1734, .pci_subdevice = 0x107c, .config = ALC880_F1734 },
2267 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9054, .config = ALC880_F1734 },
2268
2269 { .modelname = "lg", .config = ALC880_LG },
2270 { .pci_subvendor = 0x1854, .pci_subdevice = 0x003b, .config = ALC880_LG },
2271 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0068, .config = ALC880_LG },
2272
2273 { .modelname = "lg-lw", .config = ALC880_LG_LW },
2274 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0018, .config = ALC880_LG_LW },
2275 { .pci_subvendor = 0x1854, .pci_subdevice = 0x0077, .config = ALC880_LG_LW },
2276
2277#ifdef CONFIG_SND_DEBUG 2385#ifdef CONFIG_SND_DEBUG
2278 { .modelname = "test", .config = ALC880_TEST }, 2386 [ALC880_TEST] = "test",
2279#endif 2387#endif
2280 { .modelname = "auto", .config = ALC880_AUTO }, 2388 [ALC880_AUTO] = "auto",
2389};
2390
2391static struct snd_pci_quirk alc880_cfg_tbl[] = {
2392 /* Broken BIOS configuration */
2393 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG),
2394 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
2395
2396 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
2397 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
2398 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
2399 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
2400 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
2401 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
2402 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
2403 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
2404 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
2405
2406 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
2407 SND_PCI_QUIRK(0x103c, 0x2a09, "HP", ALC880_5ST),
2408
2409 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
2410 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
2411 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
2412 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
2413 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
2414 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
2415 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
2416 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
2417 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
2418 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
2419 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS", ALC880_ASUS),
2420 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
2421 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
2422 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
2423 SND_PCI_QUIRK(0x1043, 0, "ASUS", ALC880_ASUS),
2424
2425 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
2426 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
2427 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
2428 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
2429 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
2430 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
2431 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
2432 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
2433 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
2434 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
2435 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
2436 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
2437 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
2438 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
2439 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
2440 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
2441 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
2442 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
2443
2444 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
2445 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
2446 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
2447 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwlll", ALC880_F1734),
2448
2449 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
2450 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL),
2451 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
2452 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
2453
2454 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
2455 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
2456 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
2457 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
2458
2459 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
2460 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
2461 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
2462 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
2463 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
2464 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
2465 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
2466 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
2467 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
2468 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
2469 SND_PCI_QUIRK(0x8086, 0, "Intel mobo", ALC880_3ST),
2281 2470
2282 {} 2471 {}
2283}; 2472};
@@ -2438,7 +2627,8 @@ static struct alc_config_preset alc880_presets[] = {
2438 }, 2627 },
2439 [ALC880_UNIWILL_DIG] = { 2628 [ALC880_UNIWILL_DIG] = {
2440 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer }, 2629 .mixers = { alc880_asus_mixer, alc880_pcbeep_mixer },
2441 .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs }, 2630 .init_verbs = { alc880_volume_init_verbs,
2631 alc880_pin_asus_init_verbs },
2442 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), 2632 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2443 .dac_nids = alc880_asus_dac_nids, 2633 .dac_nids = alc880_asus_dac_nids,
2444 .dig_out_nid = ALC880_DIGOUT_NID, 2634 .dig_out_nid = ALC880_DIGOUT_NID,
@@ -2447,6 +2637,46 @@ static struct alc_config_preset alc880_presets[] = {
2447 .need_dac_fix = 1, 2637 .need_dac_fix = 1,
2448 .input_mux = &alc880_capture_source, 2638 .input_mux = &alc880_capture_source,
2449 }, 2639 },
2640 [ALC880_UNIWILL] = {
2641 .mixers = { alc880_uniwill_mixer },
2642 .init_verbs = { alc880_volume_init_verbs,
2643 alc880_uniwill_init_verbs },
2644 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2645 .dac_nids = alc880_asus_dac_nids,
2646 .dig_out_nid = ALC880_DIGOUT_NID,
2647 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
2648 .channel_mode = alc880_threestack_modes,
2649 .need_dac_fix = 1,
2650 .input_mux = &alc880_capture_source,
2651 .unsol_event = alc880_uniwill_unsol_event,
2652 .init_hook = alc880_uniwill_automute,
2653 },
2654 [ALC880_UNIWILL_P53] = {
2655 .mixers = { alc880_uniwill_p53_mixer },
2656 .init_verbs = { alc880_volume_init_verbs,
2657 alc880_uniwill_p53_init_verbs },
2658 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
2659 .dac_nids = alc880_asus_dac_nids,
2660 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
2661 .channel_mode = alc880_threestack_modes,
2662 .input_mux = &alc880_capture_source,
2663 .unsol_event = alc880_uniwill_p53_unsol_event,
2664 .init_hook = alc880_uniwill_p53_hp_automute,
2665 },
2666 [ALC880_FUJITSU] = {
2667 .mixers = { alc880_fujitsu_mixer,
2668 alc880_pcbeep_mixer, },
2669 .init_verbs = { alc880_volume_init_verbs,
2670 alc880_uniwill_p53_init_verbs,
2671 alc880_beep_init_verbs },
2672 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
2673 .dac_nids = alc880_dac_nids,
2674 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
2675 .channel_mode = alc880_2_jack_modes,
2676 .input_mux = &alc880_capture_source,
2677 .unsol_event = alc880_uniwill_p53_unsol_event,
2678 .init_hook = alc880_uniwill_p53_hp_automute,
2679 },
2450 [ALC880_CLEVO] = { 2680 [ALC880_CLEVO] = {
2451 .mixers = { alc880_three_stack_mixer }, 2681 .mixers = { alc880_three_stack_mixer },
2452 .init_verbs = { alc880_volume_init_verbs, 2682 .init_verbs = { alc880_volume_init_verbs,
@@ -2841,8 +3071,10 @@ static int patch_alc880(struct hda_codec *codec)
2841 3071
2842 codec->spec = spec; 3072 codec->spec = spec;
2843 3073
2844 board_config = snd_hda_check_board_config(codec, alc880_cfg_tbl); 3074 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
2845 if (board_config < 0 || board_config >= ALC880_MODEL_LAST) { 3075 alc880_models,
3076 alc880_cfg_tbl);
3077 if (board_config < 0) {
2846 printk(KERN_INFO "hda_codec: Unknown model for ALC880, " 3078 printk(KERN_INFO "hda_codec: Unknown model for ALC880, "
2847 "trying auto-probe from BIOS...\n"); 3079 "trying auto-probe from BIOS...\n");
2848 board_config = ALC880_AUTO; 3080 board_config = ALC880_AUTO;
@@ -3090,11 +3322,20 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
3090 * and the output jack. If this turns out to be the case for all such 3322 * and the output jack. If this turns out to be the case for all such
3091 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT 3323 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
3092 * to ALC_PIN_DIR_INOUT_NOMICBIAS. 3324 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
3325 *
3326 * The C20x Tablet series have a mono internal speaker which is controlled
3327 * via the chip's Mono sum widget and pin complex, so include the necessary
3328 * controls for such models. On models without a "mono speaker" the control
3329 * won't do anything.
3093 */ 3330 */
3094static struct snd_kcontrol_new alc260_acer_mixer[] = { 3331static struct snd_kcontrol_new alc260_acer_mixer[] = {
3095 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), 3332 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
3096 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), 3333 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
3097 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), 3334 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
3335 HDA_CODEC_VOLUME_MONO("Mono Speaker Playback Volume", 0x0a, 1, 0x0,
3336 HDA_OUTPUT),
3337 HDA_BIND_MUTE_MONO("Mono Speaker Playback Switch", 0x0a, 1, 2,
3338 HDA_INPUT),
3098 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), 3339 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
3099 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), 3340 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
3100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), 3341 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
@@ -3409,11 +3650,11 @@ static struct hda_verb alc260_acer_init_verbs[] = {
3409 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, 3650 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3410 /* Line In jack is connected to Line1 pin */ 3651 /* Line In jack is connected to Line1 pin */
3411 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 3652 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3653 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
3654 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3412 /* Ensure all other unused pins are disabled and muted. */ 3655 /* Ensure all other unused pins are disabled and muted. */
3413 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3656 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3414 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3657 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3415 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3416 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3417 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3658 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
3418 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 3659 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3419 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, 3660 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
@@ -3441,6 +3682,8 @@ static struct hda_verb alc260_acer_init_verbs[] = {
3441 3682
3442 /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */ 3683 /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */
3443 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 3684 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3685 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
3686 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3444 /* Unmute Mic1 and Line1 pin widget input buffers since they start as 3687 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
3445 * inputs. If the pin mode is changed by the user the pin mode control 3688 * inputs. If the pin mode is changed by the user the pin mode control
3446 * will take care of enabling the pin's input/output buffers as needed. 3689 * will take care of enabling the pin's input/output buffers as needed.
@@ -3928,33 +4171,33 @@ static void alc260_auto_init(struct hda_codec *codec)
3928/* 4171/*
3929 * ALC260 configurations 4172 * ALC260 configurations
3930 */ 4173 */
3931static struct hda_board_config alc260_cfg_tbl[] = { 4174static const char *alc260_models[ALC260_MODEL_LAST] = {
3932 { .modelname = "basic", .config = ALC260_BASIC }, 4175 [ALC260_BASIC] = "basic",
3933 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81bb, 4176 [ALC260_HP] = "hp",
3934 .config = ALC260_BASIC }, /* Sony VAIO */ 4177 [ALC260_HP_3013] = "hp-3013",
3935 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cc, 4178 [ALC260_FUJITSU_S702X] = "fujitsu",
3936 .config = ALC260_BASIC }, /* Sony VAIO VGN-S3HP */ 4179 [ALC260_ACER] = "acer",
3937 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81cd,
3938 .config = ALC260_BASIC }, /* Sony VAIO */
3939 { .pci_subvendor = 0x152d, .pci_subdevice = 0x0729,
3940 .config = ALC260_BASIC }, /* CTL Travel Master U553W */
3941 { .modelname = "hp", .config = ALC260_HP },
3942 { .modelname = "hp-3013", .config = ALC260_HP_3013 },
3943 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3010, .config = ALC260_HP_3013 },
3944 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3011, .config = ALC260_HP },
3945 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3012, .config = ALC260_HP_3013 },
3946 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3013, .config = ALC260_HP_3013 },
3947 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, .config = ALC260_HP },
3948 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, .config = ALC260_HP },
3949 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3016, .config = ALC260_HP },
3950 { .modelname = "fujitsu", .config = ALC260_FUJITSU_S702X },
3951 { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1326, .config = ALC260_FUJITSU_S702X },
3952 { .modelname = "acer", .config = ALC260_ACER },
3953 { .pci_subvendor = 0x1025, .pci_subdevice = 0x008f, .config = ALC260_ACER },
3954#ifdef CONFIG_SND_DEBUG 4180#ifdef CONFIG_SND_DEBUG
3955 { .modelname = "test", .config = ALC260_TEST }, 4181 [ALC260_TEST] = "test",
3956#endif 4182#endif
3957 { .modelname = "auto", .config = ALC260_AUTO }, 4183 [ALC260_AUTO] = "auto",
4184};
4185
4186static struct snd_pci_quirk alc260_cfg_tbl[] = {
4187 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
4188 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
4189 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
4190 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP),
4191 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013),
4192 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
4193 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
4194 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
4195 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
4196 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
4197 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
4198 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
4199 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
4200 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
3958 {} 4201 {}
3959}; 4202};
3960 4203
@@ -4053,8 +4296,10 @@ static int patch_alc260(struct hda_codec *codec)
4053 4296
4054 codec->spec = spec; 4297 codec->spec = spec;
4055 4298
4056 board_config = snd_hda_check_board_config(codec, alc260_cfg_tbl); 4299 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
4057 if (board_config < 0 || board_config >= ALC260_MODEL_LAST) { 4300 alc260_models,
4301 alc260_cfg_tbl);
4302 if (board_config < 0) {
4058 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, " 4303 snd_printd(KERN_INFO "hda_codec: Unknown model for ALC260, "
4059 "trying auto-probe from BIOS...\n"); 4304 "trying auto-probe from BIOS...\n");
4060 board_config = ALC260_AUTO; 4305 board_config = ALC260_AUTO;
@@ -4207,8 +4452,10 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
4207 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 4452 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4208 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 4453 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4209 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 4454 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4455 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4210 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 4456 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4211 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 4457 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4458 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4212 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 4459 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4213 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 4460 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4214 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 4461 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
@@ -4313,6 +4560,100 @@ static struct hda_verb alc882_eapd_verbs[] = {
4313 { } 4560 { }
4314}; 4561};
4315 4562
4563/* Mac Pro test */
4564static struct snd_kcontrol_new alc882_macpro_mixer[] = {
4565 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4566 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4567 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
4568 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
4569 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
4570 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x02, HDA_INPUT),
4571 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x02, HDA_INPUT),
4572 { } /* end */
4573};
4574
4575static struct hda_verb alc882_macpro_init_verbs[] = {
4576 /* Front mixer: unmute input/output amp left and right (volume = 0) */
4577 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4578 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4579 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4580 /* Front Pin: output 0 (0x0c) */
4581 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4582 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4583 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
4584 /* Front Mic pin: input vref at 80% */
4585 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4586 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4587 /* Speaker: output */
4588 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4589 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4590 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
4591 /* Headphone output (output 0 - 0x0c) */
4592 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4593 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4594 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
4595
4596 /* FIXME: use matrix-type input source selection */
4597 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
4598 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
4599 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4600 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4601 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4602 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4603 /* Input mixer2 */
4604 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4605 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4606 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4607 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4608 /* Input mixer3 */
4609 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4610 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4611 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4612 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4613 /* ADC1: mute amp left and right */
4614 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4615 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4616 /* ADC2: mute amp left and right */
4617 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4618 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4619 /* ADC3: mute amp left and right */
4620 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4621 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4622
4623 { }
4624};
4625static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
4626{
4627 unsigned int gpiostate, gpiomask, gpiodir;
4628
4629 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
4630 AC_VERB_GET_GPIO_DATA, 0);
4631
4632 if (!muted)
4633 gpiostate |= (1 << pin);
4634 else
4635 gpiostate &= ~(1 << pin);
4636
4637 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
4638 AC_VERB_GET_GPIO_MASK, 0);
4639 gpiomask |= (1 << pin);
4640
4641 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
4642 AC_VERB_GET_GPIO_DIRECTION, 0);
4643 gpiodir |= (1 << pin);
4644
4645
4646 snd_hda_codec_write(codec, codec->afg, 0,
4647 AC_VERB_SET_GPIO_MASK, gpiomask);
4648 snd_hda_codec_write(codec, codec->afg, 0,
4649 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
4650
4651 msleep(1);
4652
4653 snd_hda_codec_write(codec, codec->afg, 0,
4654 AC_VERB_SET_GPIO_DATA, gpiostate);
4655}
4656
4316/* 4657/*
4317 * generic initialization of ADC, input mixers and output mixers 4658 * generic initialization of ADC, input mixers and output mixers
4318 */ 4659 */
@@ -4435,19 +4776,20 @@ static struct snd_kcontrol_new alc882_capture_mixer[] = {
4435/* 4776/*
4436 * configuration and preset 4777 * configuration and preset
4437 */ 4778 */
4438static struct hda_board_config alc882_cfg_tbl[] = { 4779static const char *alc882_models[ALC882_MODEL_LAST] = {
4439 { .modelname = "3stack-dig", .config = ALC882_3ST_DIG }, 4780 [ALC882_3ST_DIG] = "3stack-dig",
4440 { .modelname = "6stack-dig", .config = ALC882_6ST_DIG }, 4781 [ALC882_6ST_DIG] = "6stack-dig",
4441 { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, 4782 [ALC882_ARIMA] = "arima",
4442 .config = ALC882_6ST_DIG }, /* MSI */ 4783 [ALC885_MACPRO] = "macpro",
4443 { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, 4784 [ALC882_AUTO] = "auto",
4444 .config = ALC882_6ST_DIG }, /* Foxconn */ 4785};
4445 { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, 4786
4446 .config = ALC882_6ST_DIG }, /* ECS to Intel*/ 4787static struct snd_pci_quirk alc882_cfg_tbl[] = {
4447 { .modelname = "arima", .config = ALC882_ARIMA }, 4788 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
4448 { .pci_subvendor = 0x161f, .pci_subdevice = 0x2054, 4789 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
4449 .config = ALC882_ARIMA }, /* Arima W820Di1 */ 4790 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
4450 { .modelname = "auto", .config = ALC882_AUTO }, 4791 SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA),
4792 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
4451 {} 4793 {}
4452}; 4794};
4453 4795
@@ -4484,6 +4826,17 @@ static struct alc_config_preset alc882_presets[] = {
4484 .channel_mode = alc882_sixstack_modes, 4826 .channel_mode = alc882_sixstack_modes,
4485 .input_mux = &alc882_capture_source, 4827 .input_mux = &alc882_capture_source,
4486 }, 4828 },
4829 [ALC885_MACPRO] = {
4830 .mixers = { alc882_macpro_mixer },
4831 .init_verbs = { alc882_macpro_init_verbs },
4832 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
4833 .dac_nids = alc882_dac_nids,
4834 .dig_out_nid = ALC882_DIGOUT_NID,
4835 .dig_in_nid = ALC882_DIGIN_NID,
4836 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
4837 .channel_mode = alc882_ch_modes,
4838 .input_mux = &alc882_capture_source,
4839 },
4487}; 4840};
4488 4841
4489 4842
@@ -4584,7 +4937,9 @@ static int patch_alc882(struct hda_codec *codec)
4584 4937
4585 codec->spec = spec; 4938 codec->spec = spec;
4586 4939
4587 board_config = snd_hda_check_board_config(codec, alc882_cfg_tbl); 4940 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
4941 alc882_models,
4942 alc882_cfg_tbl);
4588 4943
4589 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 4944 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
4590 printk(KERN_INFO "hda_codec: Unknown model for ALC882, " 4945 printk(KERN_INFO "hda_codec: Unknown model for ALC882, "
@@ -4609,6 +4964,11 @@ static int patch_alc882(struct hda_codec *codec)
4609 if (board_config != ALC882_AUTO) 4964 if (board_config != ALC882_AUTO)
4610 setup_preset(spec, &alc882_presets[board_config]); 4965 setup_preset(spec, &alc882_presets[board_config]);
4611 4966
4967 if (board_config == ALC885_MACPRO) {
4968 alc882_gpio_mute(codec, 0, 0);
4969 alc882_gpio_mute(codec, 1, 0);
4970 }
4971
4612 spec->stream_name_analog = "ALC882 Analog"; 4972 spec->stream_name_analog = "ALC882 Analog";
4613 spec->stream_analog_playback = &alc882_pcm_analog_playback; 4973 spec->stream_analog_playback = &alc882_pcm_analog_playback;
4614 spec->stream_analog_capture = &alc882_pcm_analog_capture; 4974 spec->stream_analog_capture = &alc882_pcm_analog_capture;
@@ -4767,6 +5127,13 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = {
4767 { 8, alc883_sixstack_ch8_init }, 5127 { 8, alc883_sixstack_ch8_init },
4768}; 5128};
4769 5129
5130static struct hda_verb alc883_medion_eapd_verbs[] = {
5131 /* eanable EAPD on medion laptop */
5132 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
5133 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
5134 { }
5135};
5136
4770/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 5137/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
4771 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b 5138 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
4772 */ 5139 */
@@ -4788,8 +5155,10 @@ static struct snd_kcontrol_new alc883_base_mixer[] = {
4788 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5155 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4789 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5156 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4790 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5157 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5158 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4791 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5159 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4792 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 5160 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5161 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4793 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 5162 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4794 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5163 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4795 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5164 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
@@ -4818,8 +5187,10 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
4818 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5187 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4819 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5188 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4820 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5189 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5190 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4821 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4822 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 5192 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5193 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4823 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 5194 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4824 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5195 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4825 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5196 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
@@ -4854,8 +5225,10 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
4854 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 5225 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4855 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 5226 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 5227 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5228 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
4857 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 5229 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4858 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 5230 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5231 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
4859 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 5232 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
4860 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), 5233 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
4861 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), 5234 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
@@ -4875,6 +5248,101 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
4875 { } /* end */ 5248 { } /* end */
4876}; 5249};
4877 5250
5251static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
5252 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5253 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5254 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5255 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5256 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5257 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5258 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x16, 1, 0x0, HDA_OUTPUT),
5259 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5260 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5261 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5262 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5263 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5264 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5265 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5266 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5267 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5268 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
5269 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
5270 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
5271 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
5272 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
5273 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5274 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5275
5276 {
5277 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5278 /* .name = "Capture Source", */
5279 .name = "Input Source",
5280 .count = 1,
5281 .info = alc883_mux_enum_info,
5282 .get = alc883_mux_enum_get,
5283 .put = alc883_mux_enum_put,
5284 },
5285 { } /* end */
5286};
5287
5288static struct snd_kcontrol_new alc883_tagra_mixer[] = {
5289 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5290 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5291 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5292 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5293 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
5294 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
5295 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5296 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
5297 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
5298 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5299 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5300 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5301 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5302 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5303 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5304 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5305 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5306 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5307 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5308 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5309 {
5310 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5311 /* .name = "Capture Source", */
5312 .name = "Input Source",
5313 .count = 2,
5314 .info = alc883_mux_enum_info,
5315 .get = alc883_mux_enum_get,
5316 .put = alc883_mux_enum_put,
5317 },
5318 { } /* end */
5319};
5320
5321static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = {
5322 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5323 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5324 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5325 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5326 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5328 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
5329 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5330 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
5331 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
5332 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT),
5333 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT),
5334 {
5335 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
5336 /* .name = "Capture Source", */
5337 .name = "Input Source",
5338 .count = 2,
5339 .info = alc883_mux_enum_info,
5340 .get = alc883_mux_enum_get,
5341 .put = alc883_mux_enum_put,
5342 },
5343 { } /* end */
5344};
5345
4878static struct snd_kcontrol_new alc883_chmode_mixer[] = { 5346static struct snd_kcontrol_new alc883_chmode_mixer[] = {
4879 { 5347 {
4880 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 5348 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -4963,6 +5431,45 @@ static struct hda_verb alc883_init_verbs[] = {
4963 { } 5431 { }
4964}; 5432};
4965 5433
5434static struct hda_verb alc883_tagra_verbs[] = {
5435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5436 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5437
5438 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5439 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5440
5441 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
5442 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
5443 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
5444
5445 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
5446 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
5447 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
5448 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
5449
5450 { } /* end */
5451};
5452
5453/* toggle speaker-output according to the hp-jack state */
5454static void alc883_tagra_automute(struct hda_codec *codec)
5455{
5456 unsigned int present;
5457
5458 present = snd_hda_codec_read(codec, 0x14, 0,
5459 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
5460 snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0,
5461 0x80, present ? 0x80 : 0);
5462 snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0,
5463 0x80, present ? 0x80 : 0);
5464 snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3);
5465}
5466
5467static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res)
5468{
5469 if ((res >> 26) == ALC880_HP_EVENT)
5470 alc883_tagra_automute(codec);
5471}
5472
4966/* 5473/*
4967 * generic initialization of ADC, input mixers and output mixers 5474 * generic initialization of ADC, input mixers and output mixers
4968 */ 5475 */
@@ -5057,32 +5564,42 @@ static struct snd_kcontrol_new alc883_capture_mixer[] = {
5057/* 5564/*
5058 * configuration and preset 5565 * configuration and preset
5059 */ 5566 */
5060static struct hda_board_config alc883_cfg_tbl[] = { 5567static const char *alc883_models[ALC883_MODEL_LAST] = {
5061 { .modelname = "3stack-dig", .config = ALC883_3ST_2ch_DIG }, 5568 [ALC883_3ST_2ch_DIG] = "3stack-dig",
5062 { .modelname = "3stack-6ch-dig", .config = ALC883_3ST_6ch_DIG }, 5569 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
5063 { .pci_subvendor = 0x1019, .pci_subdevice = 0x6668, 5570 [ALC883_3ST_6ch] = "3stack-6ch",
5064 .config = ALC883_3ST_6ch_DIG }, /* ECS to Intel*/ 5571 [ALC883_6ST_DIG] = "6stack-dig",
5065 { .modelname = "3stack-6ch", .config = ALC883_3ST_6ch }, 5572 [ALC883_TARGA_DIG] = "targa-dig",
5066 { .pci_subvendor = 0x108e, .pci_subdevice = 0x534d, 5573 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
5067 .config = ALC883_3ST_6ch }, 5574 [ALC888_DEMO_BOARD] = "6stack-dig-demo",
5068 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd601, 5575 [ALC883_ACER] = "acer",
5069 .config = ALC883_3ST_6ch }, /* D102GGC */ 5576 [ALC883_MEDION] = "medion",
5070 { .modelname = "6stack-dig", .config = ALC883_6ST_DIG }, 5577 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
5071 { .pci_subvendor = 0x1462, .pci_subdevice = 0x6668, 5578 [ALC883_AUTO] = "auto",
5072 .config = ALC883_6ST_DIG }, /* MSI */ 5579};
5073 { .pci_subvendor = 0x1462, .pci_subdevice = 0x7280, 5580
5074 .config = ALC883_6ST_DIG }, /* MSI K9A Platinum (MS-7280) */ 5581static struct snd_pci_quirk alc883_cfg_tbl[] = {
5075 { .pci_subvendor = 0x105b, .pci_subdevice = 0x6668, 5582 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG),
5076 .config = ALC883_6ST_DIG }, /* Foxconn */ 5583 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
5077 { .modelname = "6stack-dig-demo", .config = ALC888_DEMO_BOARD }, 5584 SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD),
5078 { .modelname = "acer", .config = ALC883_ACER }, 5585 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG),
5079 { .pci_subvendor = 0x1025, .pci_subdevice = 0/*0x0102*/, 5586 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
5080 .config = ALC883_ACER }, 5587 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
5081 { .pci_subvendor = 0x1025, .pci_subdevice = 0x0102, 5588 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
5082 .config = ALC883_ACER }, 5589 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
5083 { .pci_subvendor = 0x1025, .pci_subdevice = 0x009f, 5590 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
5084 .config = ALC883_ACER }, 5591 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
5085 { .modelname = "auto", .config = ALC883_AUTO }, 5592 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
5593 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
5594 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
5595 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
5596 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
5597 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
5598 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
5599 SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER),
5600 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
5601 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
5602 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
5086 {} 5603 {}
5087}; 5604};
5088 5605
@@ -5139,6 +5656,35 @@ static struct alc_config_preset alc883_presets[] = {
5139 .channel_mode = alc883_sixstack_modes, 5656 .channel_mode = alc883_sixstack_modes,
5140 .input_mux = &alc883_capture_source, 5657 .input_mux = &alc883_capture_source,
5141 }, 5658 },
5659 [ALC883_TARGA_DIG] = {
5660 .mixers = { alc883_tagra_mixer, alc883_chmode_mixer },
5661 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
5662 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5663 .dac_nids = alc883_dac_nids,
5664 .dig_out_nid = ALC883_DIGOUT_NID,
5665 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5666 .adc_nids = alc883_adc_nids,
5667 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
5668 .channel_mode = alc883_3ST_6ch_modes,
5669 .need_dac_fix = 1,
5670 .input_mux = &alc883_capture_source,
5671 .unsol_event = alc883_tagra_unsol_event,
5672 .init_hook = alc883_tagra_automute,
5673 },
5674 [ALC883_TARGA_2ch_DIG] = {
5675 .mixers = { alc883_tagra_2ch_mixer},
5676 .init_verbs = { alc883_init_verbs, alc883_tagra_verbs},
5677 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5678 .dac_nids = alc883_dac_nids,
5679 .dig_out_nid = ALC883_DIGOUT_NID,
5680 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5681 .adc_nids = alc883_adc_nids,
5682 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5683 .channel_mode = alc883_3ST_2ch_modes,
5684 .input_mux = &alc883_capture_source,
5685 .unsol_event = alc883_tagra_unsol_event,
5686 .init_hook = alc883_tagra_automute,
5687 },
5142 [ALC888_DEMO_BOARD] = { 5688 [ALC888_DEMO_BOARD] = {
5143 .mixers = { alc883_base_mixer, alc883_chmode_mixer }, 5689 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
5144 .init_verbs = { alc883_init_verbs }, 5690 .init_verbs = { alc883_init_verbs },
@@ -5169,6 +5715,31 @@ static struct alc_config_preset alc883_presets[] = {
5169 .channel_mode = alc883_3ST_2ch_modes, 5715 .channel_mode = alc883_3ST_2ch_modes,
5170 .input_mux = &alc883_capture_source, 5716 .input_mux = &alc883_capture_source,
5171 }, 5717 },
5718 [ALC883_MEDION] = {
5719 .mixers = { alc883_fivestack_mixer,
5720 alc883_chmode_mixer },
5721 .init_verbs = { alc883_init_verbs,
5722 alc883_medion_eapd_verbs },
5723 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5724 .dac_nids = alc883_dac_nids,
5725 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5726 .adc_nids = alc883_adc_nids,
5727 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
5728 .channel_mode = alc883_sixstack_modes,
5729 .input_mux = &alc883_capture_source,
5730 },
5731 [ALC883_LAPTOP_EAPD] = {
5732 .mixers = { alc883_base_mixer,
5733 alc883_chmode_mixer },
5734 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
5735 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
5736 .dac_nids = alc883_dac_nids,
5737 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
5738 .adc_nids = alc883_adc_nids,
5739 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
5740 .channel_mode = alc883_3ST_2ch_modes,
5741 .input_mux = &alc883_capture_source,
5742 },
5172}; 5743};
5173 5744
5174 5745
@@ -5277,8 +5848,10 @@ static int patch_alc883(struct hda_codec *codec)
5277 5848
5278 codec->spec = spec; 5849 codec->spec = spec;
5279 5850
5280 board_config = snd_hda_check_board_config(codec, alc883_cfg_tbl); 5851 board_config = snd_hda_check_board_config(codec, ALC883_MODEL_LAST,
5281 if (board_config < 0 || board_config >= ALC883_MODEL_LAST) { 5852 alc883_models,
5853 alc883_cfg_tbl);
5854 if (board_config < 0) {
5282 printk(KERN_INFO "hda_codec: Unknown model for ALC883, " 5855 printk(KERN_INFO "hda_codec: Unknown model for ALC883, "
5283 "trying auto-probe from BIOS...\n"); 5856 "trying auto-probe from BIOS...\n");
5284 board_config = ALC883_AUTO; 5857 board_config = ALC883_AUTO;
@@ -5355,6 +5928,24 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
5355 { } /* end */ 5928 { } /* end */
5356}; 5929};
5357 5930
5931static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
5932 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5933 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
5934 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5935 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5936 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
5937 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
5938 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5939 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5940 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
5941 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
5942 /* HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
5943 HDA_CODEC_MUTE("PC Beelp Playback Switch", 0x0b, 0x05, HDA_INPUT), */
5944 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/
5945 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5946 { } /* end */
5947};
5948
5358static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { 5949static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
5359 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), 5950 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5360 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), 5951 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -5377,6 +5968,30 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
5377 { } /* end */ 5968 { } /* end */
5378}; 5969};
5379 5970
5971static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
5972 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
5973 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
5974 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
5975 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
5976 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
5977 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
5978 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
5979 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
5980 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
5981 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
5982 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
5983 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
5984 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x0b, 0x05, HDA_INPUT),
5985 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x0b, 0x05, HDA_INPUT),
5986 { } /* end */
5987};
5988
5989static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
5990 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
5991 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
5992 { } /* end */
5993};
5994
5380#define alc262_capture_mixer alc882_capture_mixer 5995#define alc262_capture_mixer alc882_capture_mixer
5381#define alc262_capture_alt_mixer alc882_capture_alt_mixer 5996#define alc262_capture_alt_mixer alc882_capture_alt_mixer
5382 5997
@@ -5459,6 +6074,103 @@ static struct hda_verb alc262_init_verbs[] = {
5459 { } 6074 { }
5460}; 6075};
5461 6076
6077static struct hda_verb alc262_hippo_unsol_verbs[] = {
6078 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6079 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6080 {}
6081};
6082
6083static struct hda_verb alc262_hippo1_unsol_verbs[] = {
6084 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6085 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6086 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6087
6088 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6089 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6090 {}
6091};
6092
6093/* mute/unmute internal speaker according to the hp jack and mute state */
6094static void alc262_hippo_automute(struct hda_codec *codec, int force)
6095{
6096 struct alc_spec *spec = codec->spec;
6097 unsigned int mute;
6098
6099 if (force || ! spec->sense_updated) {
6100 unsigned int present;
6101 /* need to execute and sync at first */
6102 snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0);
6103 present = snd_hda_codec_read(codec, 0x15, 0,
6104 AC_VERB_GET_PIN_SENSE, 0);
6105 spec->jack_present = (present & 0x80000000) != 0;
6106 spec->sense_updated = 1;
6107 }
6108 if (spec->jack_present) {
6109 /* mute internal speaker */
6110 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6111 0x80, 0x80);
6112 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6113 0x80, 0x80);
6114 } else {
6115 /* unmute internal speaker if necessary */
6116 mute = snd_hda_codec_amp_read(codec, 0x15, 0, HDA_OUTPUT, 0);
6117 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6118 0x80, mute & 0x80);
6119 mute = snd_hda_codec_amp_read(codec, 0x15, 1, HDA_OUTPUT, 0);
6120 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6121 0x80, mute & 0x80);
6122 }
6123}
6124
6125/* unsolicited event for HP jack sensing */
6126static void alc262_hippo_unsol_event(struct hda_codec *codec,
6127 unsigned int res)
6128{
6129 if ((res >> 26) != ALC880_HP_EVENT)
6130 return;
6131 alc262_hippo_automute(codec, 1);
6132}
6133
6134static void alc262_hippo1_automute(struct hda_codec *codec, int force)
6135{
6136 struct alc_spec *spec = codec->spec;
6137 unsigned int mute;
6138
6139 if (force || ! spec->sense_updated) {
6140 unsigned int present;
6141 /* need to execute and sync at first */
6142 snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0);
6143 present = snd_hda_codec_read(codec, 0x1b, 0,
6144 AC_VERB_GET_PIN_SENSE, 0);
6145 spec->jack_present = (present & 0x80000000) != 0;
6146 spec->sense_updated = 1;
6147 }
6148 if (spec->jack_present) {
6149 /* mute internal speaker */
6150 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6151 0x80, 0x80);
6152 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6153 0x80, 0x80);
6154 } else {
6155 /* unmute internal speaker if necessary */
6156 mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0);
6157 snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0,
6158 0x80, mute & 0x80);
6159 mute = snd_hda_codec_amp_read(codec, 0x1b, 1, HDA_OUTPUT, 0);
6160 snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0,
6161 0x80, mute & 0x80);
6162 }
6163}
6164
6165/* unsolicited event for HP jack sensing */
6166static void alc262_hippo1_unsol_event(struct hda_codec *codec,
6167 unsigned int res)
6168{
6169 if ((res >> 26) != ALC880_HP_EVENT)
6170 return;
6171 alc262_hippo1_automute(codec, 1);
6172}
6173
5462/* 6174/*
5463 * fujitsu model 6175 * fujitsu model
5464 * 0x14 = headphone/spdif-out, 0x15 = internal speaker 6176 * 0x14 = headphone/spdif-out, 0x15 = internal speaker
@@ -5809,6 +6521,100 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = {
5809 { } 6521 { }
5810}; 6522};
5811 6523
6524static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
6525 /*
6526 * Unmute ADC0-2 and set the default input to mic-in
6527 */
6528 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6530 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
6531 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6532 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
6533 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6534
6535 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
6536 * mixer widget
6537 * Note: PASD motherboards uses the Line In 2 as the input for front
6538 * panel mic (mic 2)
6539 */
6540 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
6541 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6542 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6543 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
6544 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
6545 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
6546 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
6547 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
6548 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(7)},
6549 /*
6550 * Set up output mixers (0x0c - 0x0e)
6551 */
6552 /* set vol=0 to output mixers */
6553 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6554 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6555 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6556
6557 /* set up input amps for analog loopback */
6558 /* Amp Indices: DAC = 0, mixer = 1 */
6559 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6560 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6561 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6562 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6563 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6564 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
6565
6566
6567 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
6568 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
6569 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
6570 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
6571 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
6572 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
6573 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
6574
6575 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6576 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
6577
6578 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
6579 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6580
6581 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
6582 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6583 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6584 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
6585 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6586 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
6587
6588 /* FIXME: use matrix-type input source selection */
6589 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
6590 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
6591 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
6592 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
6593 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
6594 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
6595 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
6596 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
6597 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
6598 /* Input mixer2 */
6599 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6600 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6601 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
6602 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
6603 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
6604 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
6605 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
6606 /* Input mixer3 */
6607 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6608 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6609 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
6610 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
6611 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
6612 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
6613 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
6614
6615 { }
6616};
6617
5812/* pcm configuration: identiacal with ALC880 */ 6618/* pcm configuration: identiacal with ALC880 */
5813#define alc262_pcm_analog_playback alc880_pcm_analog_playback 6619#define alc262_pcm_analog_playback alc880_pcm_analog_playback
5814#define alc262_pcm_analog_capture alc880_pcm_analog_capture 6620#define alc262_pcm_analog_capture alc880_pcm_analog_capture
@@ -5866,26 +6672,35 @@ static void alc262_auto_init(struct hda_codec *codec)
5866/* 6672/*
5867 * configuration and preset 6673 * configuration and preset
5868 */ 6674 */
5869static struct hda_board_config alc262_cfg_tbl[] = { 6675static const char *alc262_models[ALC262_MODEL_LAST] = {
5870 { .modelname = "basic", .config = ALC262_BASIC }, 6676 [ALC262_BASIC] = "basic",
5871 { .modelname = "fujitsu", .config = ALC262_FUJITSU }, 6677 [ALC262_HIPPO] = "hippo",
5872 { .pci_subvendor = 0x10cf, .pci_subdevice = 0x1397, 6678 [ALC262_HIPPO_1] = "hippo_1",
5873 .config = ALC262_FUJITSU }, 6679 [ALC262_FUJITSU] = "fujitsu",
5874 { .modelname = "hp-bpc", .config = ALC262_HP_BPC }, 6680 [ALC262_HP_BPC] = "hp-bpc",
5875 { .pci_subvendor = 0x103c, .pci_subdevice = 0x280c, 6681 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
5876 .config = ALC262_HP_BPC }, /* xw4400 */ 6682 [ALC262_BENQ_ED8] = "benq",
5877 { .pci_subvendor = 0x103c, .pci_subdevice = 0x2801, 6683 [ALC262_AUTO] = "auto",
5878 .config = ALC262_HP_BPC }, /* q965 */ 6684};
5879 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3014, 6685
5880 .config = ALC262_HP_BPC }, /* xw6400 */ 6686static struct snd_pci_quirk alc262_cfg_tbl[] = {
5881 { .pci_subvendor = 0x103c, .pci_subdevice = 0x3015, 6687 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
5882 .config = ALC262_HP_BPC }, /* xw8400 */ 6688 SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC),
5883 { .pci_subvendor = 0x103c, .pci_subdevice = 0x12fe, 6689 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
5884 .config = ALC262_HP_BPC }, /* xw9400 */ 6690 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
5885 { .modelname = "benq", .config = ALC262_BENQ_ED8 }, 6691 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
5886 { .pci_subvendor = 0x17ff, .pci_subdevice = 0x0560, 6692 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
5887 .config = ALC262_BENQ_ED8 }, 6693 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
5888 { .modelname = "auto", .config = ALC262_AUTO }, 6694 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
6695 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
6696 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
6697 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
6698 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
6699 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
6700 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
6701 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
6702 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
6703 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
5889 {} 6704 {}
5890}; 6705};
5891 6706
@@ -5900,6 +6715,30 @@ static struct alc_config_preset alc262_presets[] = {
5900 .channel_mode = alc262_modes, 6715 .channel_mode = alc262_modes,
5901 .input_mux = &alc262_capture_source, 6716 .input_mux = &alc262_capture_source,
5902 }, 6717 },
6718 [ALC262_HIPPO] = {
6719 .mixers = { alc262_base_mixer },
6720 .init_verbs = { alc262_init_verbs, alc262_hippo_unsol_verbs},
6721 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
6722 .dac_nids = alc262_dac_nids,
6723 .hp_nid = 0x03,
6724 .dig_out_nid = ALC262_DIGOUT_NID,
6725 .num_channel_mode = ARRAY_SIZE(alc262_modes),
6726 .channel_mode = alc262_modes,
6727 .input_mux = &alc262_capture_source,
6728 .unsol_event = alc262_hippo_unsol_event,
6729 },
6730 [ALC262_HIPPO_1] = {
6731 .mixers = { alc262_hippo1_mixer },
6732 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
6733 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
6734 .dac_nids = alc262_dac_nids,
6735 .hp_nid = 0x02,
6736 .dig_out_nid = ALC262_DIGOUT_NID,
6737 .num_channel_mode = ARRAY_SIZE(alc262_modes),
6738 .channel_mode = alc262_modes,
6739 .input_mux = &alc262_capture_source,
6740 .unsol_event = alc262_hippo1_unsol_event,
6741 },
5903 [ALC262_FUJITSU] = { 6742 [ALC262_FUJITSU] = {
5904 .mixers = { alc262_fujitsu_mixer }, 6743 .mixers = { alc262_fujitsu_mixer },
5905 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs }, 6744 .init_verbs = { alc262_init_verbs, alc262_fujitsu_unsol_verbs },
@@ -5922,6 +6761,27 @@ static struct alc_config_preset alc262_presets[] = {
5922 .channel_mode = alc262_modes, 6761 .channel_mode = alc262_modes,
5923 .input_mux = &alc262_HP_capture_source, 6762 .input_mux = &alc262_HP_capture_source,
5924 }, 6763 },
6764 [ALC262_HP_BPC_D7000_WF] = {
6765 .mixers = { alc262_HP_BPC_WildWest_mixer },
6766 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
6767 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
6768 .dac_nids = alc262_dac_nids,
6769 .hp_nid = 0x03,
6770 .num_channel_mode = ARRAY_SIZE(alc262_modes),
6771 .channel_mode = alc262_modes,
6772 .input_mux = &alc262_HP_capture_source,
6773 },
6774 [ALC262_HP_BPC_D7000_WL] = {
6775 .mixers = { alc262_HP_BPC_WildWest_mixer,
6776 alc262_HP_BPC_WildWest_option_mixer },
6777 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
6778 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
6779 .dac_nids = alc262_dac_nids,
6780 .hp_nid = 0x03,
6781 .num_channel_mode = ARRAY_SIZE(alc262_modes),
6782 .channel_mode = alc262_modes,
6783 .input_mux = &alc262_HP_capture_source,
6784 },
5925 [ALC262_BENQ_ED8] = { 6785 [ALC262_BENQ_ED8] = {
5926 .mixers = { alc262_base_mixer }, 6786 .mixers = { alc262_base_mixer },
5927 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, 6787 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
@@ -5940,7 +6800,7 @@ static int patch_alc262(struct hda_codec *codec)
5940 int board_config; 6800 int board_config;
5941 int err; 6801 int err;
5942 6802
5943 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 6803 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5944 if (spec == NULL) 6804 if (spec == NULL)
5945 return -ENOMEM; 6805 return -ENOMEM;
5946 6806
@@ -5956,9 +6816,11 @@ static int patch_alc262(struct hda_codec *codec)
5956 } 6816 }
5957#endif 6817#endif
5958 6818
5959 board_config = snd_hda_check_board_config(codec, alc262_cfg_tbl); 6819 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
5960 6820 alc262_models,
5961 if (board_config < 0 || board_config >= ALC262_MODEL_LAST) { 6821 alc262_cfg_tbl);
6822
6823 if (board_config < 0) {
5962 printk(KERN_INFO "hda_codec: Unknown model for ALC262, " 6824 printk(KERN_INFO "hda_codec: Unknown model for ALC262, "
5963 "trying auto-probe from BIOS...\n"); 6825 "trying auto-probe from BIOS...\n");
5964 board_config = ALC262_AUTO; 6826 board_config = ALC262_AUTO;
@@ -6078,6 +6940,44 @@ static struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
6078 { 4, alc861_uniwill_m31_ch4_init }, 6940 { 4, alc861_uniwill_m31_ch4_init },
6079}; 6941};
6080 6942
6943/* Set mic1 and line-in as input and unmute the mixer */
6944static struct hda_verb alc861_asus_ch2_init[] = {
6945 /* set pin widget 1Ah (line in) for input */
6946 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
6947 /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */
6948 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6949
6950 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
6951#if 0
6952 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
6953 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
6954#endif
6955 { } /* end */
6956};
6957/* Set mic1 nad line-in as output and mute mixer */
6958static struct hda_verb alc861_asus_ch6_init[] = {
6959 /* set pin widget 1Ah (line in) for output (Back Surround)*/
6960 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6961 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
6962 /* set pin widget 18h (mic1) for output (CLFE)*/
6963 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
6964 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
6965 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
6966 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
6967
6968 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
6969#if 0
6970 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
6971 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
6972#endif
6973 { } /* end */
6974};
6975
6976static struct hda_channel_mode alc861_asus_modes[2] = {
6977 { 2, alc861_asus_ch2_init },
6978 { 6, alc861_asus_ch6_init },
6979};
6980
6081/* patch-ALC861 */ 6981/* patch-ALC861 */
6082 6982
6083static struct snd_kcontrol_new alc861_base_mixer[] = { 6983static struct snd_kcontrol_new alc861_base_mixer[] = {
@@ -6154,7 +7054,29 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = {
6154 .private_value = ARRAY_SIZE(alc861_threestack_modes), 7054 .private_value = ARRAY_SIZE(alc861_threestack_modes),
6155 }, 7055 },
6156 { } /* end */ 7056 { } /* end */
6157}; 7057};
7058
7059static struct snd_kcontrol_new alc861_toshiba_mixer[] = {
7060 /* output mixer control */
7061 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
7062 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
7063 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
7064
7065 /*Capture mixer control */
7066 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7067 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7068 {
7069 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7070 .name = "Capture Source",
7071 .count = 1,
7072 .info = alc_mux_enum_info,
7073 .get = alc_mux_enum_get,
7074 .put = alc_mux_enum_put,
7075 },
7076
7077 { } /* end */
7078};
7079
6158static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { 7080static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
6159 /* output mixer control */ 7081 /* output mixer control */
6160 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), 7082 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
@@ -6196,7 +7118,58 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
6196 }, 7118 },
6197 { } /* end */ 7119 { } /* end */
6198}; 7120};
6199 7121
7122static struct snd_kcontrol_new alc861_asus_mixer[] = {
7123 /* output mixer control */
7124 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
7125 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
7126 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
7127 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
7128 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
7129
7130 /* Input mixer control */
7131 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
7132 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
7133 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
7134 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
7135 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
7136 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
7137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
7138 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
7139 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
7140 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */
7141
7142 /* Capture mixer control */
7143 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
7144 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
7145 {
7146 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7147 .name = "Capture Source",
7148 .count = 1,
7149 .info = alc_mux_enum_info,
7150 .get = alc_mux_enum_get,
7151 .put = alc_mux_enum_put,
7152 },
7153 {
7154 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
7155 .name = "Channel Mode",
7156 .info = alc_ch_mode_info,
7157 .get = alc_ch_mode_get,
7158 .put = alc_ch_mode_put,
7159 .private_value = ARRAY_SIZE(alc861_asus_modes),
7160 },
7161 { }
7162};
7163
7164/* additional mixer */
7165static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
7166 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
7167 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
7168 HDA_CODEC_VOLUME("PC Beep Playback Volume", 0x23, 0x0, HDA_OUTPUT),
7169 HDA_CODEC_MUTE("PC Beep Playback Switch", 0x23, 0x0, HDA_OUTPUT),
7170 { }
7171};
7172
6200/* 7173/*
6201 * generic initialization of ADC, input mixers and output mixers 7174 * generic initialization of ADC, input mixers and output mixers
6202 */ 7175 */
@@ -6217,7 +7190,7 @@ static struct hda_verb alc861_base_init_verbs[] = {
6217 /* port-E for HP out (front panel) */ 7190 /* port-E for HP out (front panel) */
6218 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 7191 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
6219 /* route front PCM to HP */ 7192 /* route front PCM to HP */
6220 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7193 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
6221 /* port-F for mic-in (front panel) with vref */ 7194 /* port-F for mic-in (front panel) with vref */
6222 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 7195 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6223 /* port-G for CLFE (rear panel) */ 7196 /* port-G for CLFE (rear panel) */
@@ -6281,7 +7254,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = {
6281 /* port-E for HP out (front panel) */ 7254 /* port-E for HP out (front panel) */
6282 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 7255 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
6283 /* route front PCM to HP */ 7256 /* route front PCM to HP */
6284 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7257 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
6285 /* port-F for mic-in (front panel) with vref */ 7258 /* port-F for mic-in (front panel) with vref */
6286 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 7259 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6287 /* port-G for CLFE (rear panel) */ 7260 /* port-G for CLFE (rear panel) */
@@ -6341,7 +7314,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
6341 /* port-E for HP out (front panel) */ 7314 /* port-E for HP out (front panel) */
6342 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80 7315 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80
6343 /* route front PCM to HP */ 7316 /* route front PCM to HP */
6344 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01 }, 7317 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
6345 /* port-F for mic-in (front panel) with vref */ 7318 /* port-F for mic-in (front panel) with vref */
6346 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 7319 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
6347 /* port-G for CLFE (rear panel) */ 7320 /* port-G for CLFE (rear panel) */
@@ -6385,6 +7358,74 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = {
6385 { } 7358 { }
6386}; 7359};
6387 7360
7361static struct hda_verb alc861_asus_init_verbs[] = {
7362 /*
7363 * Unmute ADC0 and set the default input to mic-in
7364 */
7365 /* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/
7366 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
7367 /* route front PCM to HP */
7368 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
7369 /* port-B for mic-in (rear panel) with vref */
7370 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7371 /* port-C for line-in (rear panel) */
7372 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7373 /* port-D for Front */
7374 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7375 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
7376 /* port-E for HP out (front panel) */
7377 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */
7378 /* route front PCM to HP */
7379 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
7380 /* port-F for mic-in (front panel) with vref */
7381 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
7382 /* port-G for CLFE (rear panel) */
7383 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7384 /* port-H for side (rear panel) */
7385 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
7386 /* CD-in */
7387 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
7388 /* route front mic to ADC1*/
7389 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
7390 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7391 /* Unmute DAC0~3 & spdif out*/
7392 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7393 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7394 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7395 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7396 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7397 /* Unmute Mixer 14 (mic) 1c (Line in)*/
7398 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7399 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7400 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7401 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7402
7403 /* Unmute Stereo Mixer 15 */
7404 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7405 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7406 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7407 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, /* Output 0~12 step */
7408
7409 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7410 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7411 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7412 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7413 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7414 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7415 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7416 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7417 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */
7418 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
7419 { }
7420};
7421
7422/* additional init verbs for ASUS laptops */
7423static struct hda_verb alc861_asus_laptop_init_verbs[] = {
7424 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
7425 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
7426 { }
7427};
7428
6388/* 7429/*
6389 * generic initialization of ADC, input mixers and output mixers 7430 * generic initialization of ADC, input mixers and output mixers
6390 */ 7431 */
@@ -6437,6 +7478,39 @@ static struct hda_verb alc861_auto_init_verbs[] = {
6437 { } 7478 { }
6438}; 7479};
6439 7480
7481static struct hda_verb alc861_toshiba_init_verbs[] = {
7482 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
7483
7484 { }
7485};
7486
7487/* toggle speaker-output according to the hp-jack state */
7488static void alc861_toshiba_automute(struct hda_codec *codec)
7489{
7490 unsigned int present;
7491
7492 present = snd_hda_codec_read(codec, 0x0f, 0,
7493 AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
7494 snd_hda_codec_amp_update(codec, 0x16, 0, HDA_INPUT, 0,
7495 0x80, present ? 0x80 : 0);
7496 snd_hda_codec_amp_update(codec, 0x16, 1, HDA_INPUT, 0,
7497 0x80, present ? 0x80 : 0);
7498 snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_INPUT, 3,
7499 0x80, present ? 0 : 0x80);
7500 snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_INPUT, 3,
7501 0x80, present ? 0 : 0x80);
7502}
7503
7504static void alc861_toshiba_unsol_event(struct hda_codec *codec,
7505 unsigned int res)
7506{
7507 /* Looks like the unsol event is incompatible with the standard
7508 * definition. 6bit tag is placed at 26 bit!
7509 */
7510 if ((res >> 26) == ALC880_HP_EVENT)
7511 alc861_toshiba_automute(codec);
7512}
7513
6440/* pcm configuration: identiacal with ALC880 */ 7514/* pcm configuration: identiacal with ALC880 */
6441#define alc861_pcm_analog_playback alc880_pcm_analog_playback 7515#define alc861_pcm_analog_playback alc880_pcm_analog_playback
6442#define alc861_pcm_analog_capture alc880_pcm_analog_capture 7516#define alc861_pcm_analog_capture alc880_pcm_analog_capture
@@ -6710,19 +7784,29 @@ static void alc861_auto_init(struct hda_codec *codec)
6710/* 7784/*
6711 * configuration and preset 7785 * configuration and preset
6712 */ 7786 */
6713static struct hda_board_config alc861_cfg_tbl[] = { 7787static const char *alc861_models[ALC861_MODEL_LAST] = {
6714 { .modelname = "3stack", .config = ALC861_3ST }, 7788 [ALC861_3ST] = "3stack",
6715 { .pci_subvendor = 0x8086, .pci_subdevice = 0xd600, 7789 [ALC660_3ST] = "3stack-660",
6716 .config = ALC861_3ST }, 7790 [ALC861_3ST_DIG] = "3stack-dig",
6717 { .modelname = "3stack-660", .config = ALC660_3ST }, 7791 [ALC861_6ST_DIG] = "6stack-dig",
6718 { .pci_subvendor = 0x1043, .pci_subdevice = 0x81e7, 7792 [ALC861_UNIWILL_M31] = "uniwill-m31",
6719 .config = ALC660_3ST }, 7793 [ALC861_TOSHIBA] = "toshiba",
6720 { .modelname = "3stack-dig", .config = ALC861_3ST_DIG }, 7794 [ALC861_ASUS] = "asus",
6721 { .modelname = "6stack-dig", .config = ALC861_6ST_DIG }, 7795 [ALC861_ASUS_LAPTOP] = "asus-laptop",
6722 { .modelname = "uniwill-m31", .config = ALC861_UNIWILL_M31}, 7796 [ALC861_AUTO] = "auto",
6723 { .pci_subvendor = 0x1584, .pci_subdevice = 0x9072, 7797};
6724 .config = ALC861_UNIWILL_M31 }, 7798
6725 { .modelname = "auto", .config = ALC861_AUTO }, 7799static struct snd_pci_quirk alc861_cfg_tbl[] = {
7800 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
7801 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
7802 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
7803 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
7804 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST),
7805 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
7806 SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA),
7807 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
7808 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
7809 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
6726 {} 7810 {}
6727}; 7811};
6728 7812
@@ -6789,8 +7873,48 @@ static struct alc_config_preset alc861_presets[] = {
6789 .adc_nids = alc861_adc_nids, 7873 .adc_nids = alc861_adc_nids,
6790 .input_mux = &alc861_capture_source, 7874 .input_mux = &alc861_capture_source,
6791 }, 7875 },
6792 7876 [ALC861_TOSHIBA] = {
6793}; 7877 .mixers = { alc861_toshiba_mixer },
7878 .init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs },
7879 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
7880 .dac_nids = alc861_dac_nids,
7881 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7882 .channel_mode = alc883_3ST_2ch_modes,
7883 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7884 .adc_nids = alc861_adc_nids,
7885 .input_mux = &alc861_capture_source,
7886 .unsol_event = alc861_toshiba_unsol_event,
7887 .init_hook = alc861_toshiba_automute,
7888 },
7889 [ALC861_ASUS] = {
7890 .mixers = { alc861_asus_mixer },
7891 .init_verbs = { alc861_asus_init_verbs },
7892 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
7893 .dac_nids = alc861_dac_nids,
7894 .dig_out_nid = ALC861_DIGOUT_NID,
7895 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
7896 .channel_mode = alc861_asus_modes,
7897 .need_dac_fix = 1,
7898 .hp_nid = 0x06,
7899 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7900 .adc_nids = alc861_adc_nids,
7901 .input_mux = &alc861_capture_source,
7902 },
7903 [ALC861_ASUS_LAPTOP] = {
7904 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
7905 .init_verbs = { alc861_asus_init_verbs,
7906 alc861_asus_laptop_init_verbs },
7907 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
7908 .dac_nids = alc861_dac_nids,
7909 .dig_out_nid = ALC861_DIGOUT_NID,
7910 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
7911 .channel_mode = alc883_3ST_2ch_modes,
7912 .need_dac_fix = 1,
7913 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
7914 .adc_nids = alc861_adc_nids,
7915 .input_mux = &alc861_capture_source,
7916 },
7917};
6794 7918
6795 7919
6796static int patch_alc861(struct hda_codec *codec) 7920static int patch_alc861(struct hda_codec *codec)
@@ -6799,15 +7923,17 @@ static int patch_alc861(struct hda_codec *codec)
6799 int board_config; 7923 int board_config;
6800 int err; 7924 int err;
6801 7925
6802 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); 7926 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
6803 if (spec == NULL) 7927 if (spec == NULL)
6804 return -ENOMEM; 7928 return -ENOMEM;
6805 7929
6806 codec->spec = spec; 7930 codec->spec = spec;
6807 7931
6808 board_config = snd_hda_check_board_config(codec, alc861_cfg_tbl); 7932 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
7933 alc861_models,
7934 alc861_cfg_tbl);
6809 7935
6810 if (board_config < 0 || board_config >= ALC861_MODEL_LAST) { 7936 if (board_config < 0) {
6811 printk(KERN_INFO "hda_codec: Unknown model for ALC861, " 7937 printk(KERN_INFO "hda_codec: Unknown model for ALC861, "
6812 "trying auto-probe from BIOS...\n"); 7938 "trying auto-probe from BIOS...\n");
6813 board_config = ALC861_AUTO; 7939 board_config = ALC861_AUTO;
@@ -6846,19 +7972,706 @@ static int patch_alc861(struct hda_codec *codec)
6846} 7972}
6847 7973
6848/* 7974/*
7975 * ALC861-VD support
7976 *
7977 * Based on ALC882
7978 *
7979 * In addition, an independent DAC
7980 */
7981#define ALC861VD_DIGOUT_NID 0x06
7982
7983static hda_nid_t alc861vd_dac_nids[4] = {
7984 /* front, surr, clfe, side surr */
7985 0x02, 0x03, 0x04, 0x05
7986};
7987
7988/* dac_nids for ALC660vd are in a different order - according to
7989 * Realtek's driver.
7990 * This should probably tesult in a different mixer for 6stack models
7991 * of ALC660vd codecs, but for now there is only 3stack mixer
7992 * - and it is the same as in 861vd.
7993 * adc_nids in ALC660vd are (is) the same as in 861vd
7994 */
7995static hda_nid_t alc660vd_dac_nids[3] = {
7996 /* front, rear, clfe, rear_surr */
7997 0x02, 0x04, 0x03
7998};
7999
8000static hda_nid_t alc861vd_adc_nids[1] = {
8001 /* ADC0 */
8002 0x09,
8003};
8004
8005/* input MUX */
8006/* FIXME: should be a matrix-type input source selection */
8007static struct hda_input_mux alc861vd_capture_source = {
8008 .num_items = 4,
8009 .items = {
8010 { "Mic", 0x0 },
8011 { "Front Mic", 0x1 },
8012 { "Line", 0x2 },
8013 { "CD", 0x4 },
8014 },
8015};
8016
8017#define alc861vd_mux_enum_info alc_mux_enum_info
8018#define alc861vd_mux_enum_get alc_mux_enum_get
8019
8020static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol,
8021 struct snd_ctl_elem_value *ucontrol)
8022{
8023 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
8024 struct alc_spec *spec = codec->spec;
8025 const struct hda_input_mux *imux = spec->input_mux;
8026 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
8027 static hda_nid_t capture_mixers[1] = { 0x22 };
8028 hda_nid_t nid = capture_mixers[adc_idx];
8029 unsigned int *cur_val = &spec->cur_mux[adc_idx];
8030 unsigned int i, idx;
8031
8032 idx = ucontrol->value.enumerated.item[0];
8033 if (idx >= imux->num_items)
8034 idx = imux->num_items - 1;
8035 if (*cur_val == idx && ! codec->in_resume)
8036 return 0;
8037 for (i = 0; i < imux->num_items; i++) {
8038 unsigned int v = (i == idx) ? 0x7000 : 0x7080;
8039 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
8040 v | (imux->items[i].index << 8));
8041 }
8042 *cur_val = idx;
8043 return 1;
8044}
8045
8046/*
8047 * 2ch mode
8048 */
8049static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
8050 { 2, NULL }
8051};
8052
8053/*
8054 * 6ch mode
8055 */
8056static struct hda_verb alc861vd_6stack_ch6_init[] = {
8057 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8058 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8059 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8060 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8061 { } /* end */
8062};
8063
8064/*
8065 * 8ch mode
8066 */
8067static struct hda_verb alc861vd_6stack_ch8_init[] = {
8068 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8069 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8070 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8071 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8072 { } /* end */
8073};
8074
8075static struct hda_channel_mode alc861vd_6stack_modes[2] = {
8076 { 6, alc861vd_6stack_ch6_init },
8077 { 8, alc861vd_6stack_ch8_init },
8078};
8079
8080static struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
8081 {
8082 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8083 .name = "Channel Mode",
8084 .info = alc_ch_mode_info,
8085 .get = alc_ch_mode_get,
8086 .put = alc_ch_mode_put,
8087 },
8088 { } /* end */
8089};
8090
8091static struct snd_kcontrol_new alc861vd_capture_mixer[] = {
8092 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
8093 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
8094
8095 {
8096 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8097 /* The multiple "Capture Source" controls confuse alsamixer
8098 * So call somewhat different..
8099 *FIXME: the controls appear in the "playback" view!
8100 */
8101 /* .name = "Capture Source", */
8102 .name = "Input Source",
8103 .count = 1,
8104 .info = alc861vd_mux_enum_info,
8105 .get = alc861vd_mux_enum_get,
8106 .put = alc861vd_mux_enum_put,
8107 },
8108 { } /* end */
8109};
8110
8111/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8112 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8113 */
8114static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
8115 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8116 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8117
8118 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
8119 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8120
8121 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
8122 HDA_OUTPUT),
8123 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
8124 HDA_OUTPUT),
8125 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8126 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8127
8128 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
8129 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8130
8131 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8132
8133 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8134 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8135 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8136
8137 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8138 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8139 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8140
8141 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8142 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8143
8144 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8145 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8146
8147 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
8148 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
8149
8150 { } /* end */
8151};
8152
8153static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
8154 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
8155 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8156
8157 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8158
8159 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT),
8160 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8161 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8162
8163 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT),
8164 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8165 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8166
8167 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8168 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8169
8170 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8171 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8172
8173 HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT),
8174 HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT),
8175
8176 { } /* end */
8177};
8178
8179/*
8180 * generic initialization of ADC, input mixers and output mixers
8181 */
8182static struct hda_verb alc861vd_volume_init_verbs[] = {
8183 /*
8184 * Unmute ADC0 and set the default input to mic-in
8185 */
8186 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8187 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8188
8189 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
8190 * the analog-loopback mixer widget
8191 */
8192 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
8193 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8194 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8195 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8196 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8197 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8198
8199 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
8200 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
8201 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
8202 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)},
8203 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(8)},
8204
8205 /*
8206 * Set up output mixers (0x02 - 0x05)
8207 */
8208 /* set vol=0 to output mixers */
8209 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8210 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8211 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8212 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8213
8214 /* set up input amps for analog loopback */
8215 /* Amp Indices: DAC = 0, mixer = 1 */
8216 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8218 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8219 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8220 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8221 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8222 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8223 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8224
8225 { }
8226};
8227
8228/*
8229 * 3-stack pin configuration:
8230 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
8231 */
8232static struct hda_verb alc861vd_3stack_init_verbs[] = {
8233 /*
8234 * Set pin mode and muting
8235 */
8236 /* set front pin widgets 0x14 for output */
8237 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8238 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8239 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8240
8241 /* Mic (rear) pin: input vref at 80% */
8242 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8243 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8244 /* Front Mic pin: input vref at 80% */
8245 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8246 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8247 /* Line In pin: input */
8248 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8249 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8250 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8251 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8252 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8253 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8254 /* CD pin widget for input */
8255 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8256
8257 { }
8258};
8259
8260/*
8261 * 6-stack pin configuration:
8262 */
8263static struct hda_verb alc861vd_6stack_init_verbs[] = {
8264 /*
8265 * Set pin mode and muting
8266 */
8267 /* set front pin widgets 0x14 for output */
8268 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8270 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8271
8272 /* Rear Pin: output 1 (0x0d) */
8273 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8274 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8275 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8276 /* CLFE Pin: output 2 (0x0e) */
8277 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8278 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8279 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8280 /* Side Pin: output 3 (0x0f) */
8281 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8282 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8283 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8284
8285 /* Mic (rear) pin: input vref at 80% */
8286 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8287 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8288 /* Front Mic pin: input vref at 80% */
8289 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8290 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8291 /* Line In pin: input */
8292 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8293 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8294 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8295 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8296 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8297 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8298 /* CD pin widget for input */
8299 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8300
8301 { }
8302};
8303
8304/* pcm configuration: identiacal with ALC880 */
8305#define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
8306#define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
8307#define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
8308#define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
8309
8310/*
8311 * configuration and preset
8312 */
8313static const char *alc861vd_models[ALC861VD_MODEL_LAST] = {
8314 [ALC660VD_3ST] = "3stack-660",
8315 [ALC861VD_3ST] = "3stack",
8316 [ALC861VD_3ST_DIG] = "3stack-digout",
8317 [ALC861VD_6ST_DIG] = "6stack-digout",
8318 [ALC861VD_AUTO] = "auto",
8319};
8320
8321static struct snd_pci_quirk alc861vd_cfg_tbl[] = {
8322 SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),
8323 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
8324 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
8325
8326 SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_3ST),
8327 {}
8328};
8329
8330static struct alc_config_preset alc861vd_presets[] = {
8331 [ALC660VD_3ST] = {
8332 .mixers = { alc861vd_3st_mixer },
8333 .init_verbs = { alc861vd_volume_init_verbs,
8334 alc861vd_3stack_init_verbs },
8335 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
8336 .dac_nids = alc660vd_dac_nids,
8337 .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids),
8338 .adc_nids = alc861vd_adc_nids,
8339 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
8340 .channel_mode = alc861vd_3stack_2ch_modes,
8341 .input_mux = &alc861vd_capture_source,
8342 },
8343 [ALC861VD_3ST] = {
8344 .mixers = { alc861vd_3st_mixer },
8345 .init_verbs = { alc861vd_volume_init_verbs,
8346 alc861vd_3stack_init_verbs },
8347 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
8348 .dac_nids = alc861vd_dac_nids,
8349 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
8350 .channel_mode = alc861vd_3stack_2ch_modes,
8351 .input_mux = &alc861vd_capture_source,
8352 },
8353 [ALC861VD_3ST_DIG] = {
8354 .mixers = { alc861vd_3st_mixer },
8355 .init_verbs = { alc861vd_volume_init_verbs,
8356 alc861vd_3stack_init_verbs },
8357 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
8358 .dac_nids = alc861vd_dac_nids,
8359 .dig_out_nid = ALC861VD_DIGOUT_NID,
8360 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
8361 .channel_mode = alc861vd_3stack_2ch_modes,
8362 .input_mux = &alc861vd_capture_source,
8363 },
8364 [ALC861VD_6ST_DIG] = {
8365 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
8366 .init_verbs = { alc861vd_volume_init_verbs,
8367 alc861vd_6stack_init_verbs },
8368 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
8369 .dac_nids = alc861vd_dac_nids,
8370 .dig_out_nid = ALC861VD_DIGOUT_NID,
8371 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
8372 .channel_mode = alc861vd_6stack_modes,
8373 .input_mux = &alc861vd_capture_source,
8374 },
8375};
8376
8377/*
8378 * BIOS auto configuration
8379 */
8380static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
8381 hda_nid_t nid, int pin_type, int dac_idx)
8382{
8383 /* set as output */
8384 snd_hda_codec_write(codec, nid, 0,
8385 AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type);
8386 snd_hda_codec_write(codec, nid, 0,
8387 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE);
8388}
8389
8390static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
8391{
8392 struct alc_spec *spec = codec->spec;
8393 int i;
8394
8395 for (i = 0; i <= HDA_SIDE; i++) {
8396 hda_nid_t nid = spec->autocfg.line_out_pins[i];
8397 if (nid)
8398 alc861vd_auto_set_output_and_unmute(codec, nid,
8399 PIN_OUT, i);
8400 }
8401}
8402
8403
8404static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
8405{
8406 struct alc_spec *spec = codec->spec;
8407 hda_nid_t pin;
8408
8409 pin = spec->autocfg.hp_pins[0];
8410 if (pin) /* connect to front and use dac 0 */
8411 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
8412}
8413
8414#define alc861vd_is_input_pin(nid) alc880_is_input_pin(nid)
8415#define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
8416
8417static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
8418{
8419 struct alc_spec *spec = codec->spec;
8420 int i;
8421
8422 for (i = 0; i < AUTO_PIN_LAST; i++) {
8423 hda_nid_t nid = spec->autocfg.input_pins[i];
8424 if (alc861vd_is_input_pin(nid)) {
8425 snd_hda_codec_write(codec, nid, 0,
8426 AC_VERB_SET_PIN_WIDGET_CONTROL,
8427 i <= AUTO_PIN_FRONT_MIC ?
8428 PIN_VREF80 : PIN_IN);
8429 if (nid != ALC861VD_PIN_CD_NID)
8430 snd_hda_codec_write(codec, nid, 0,
8431 AC_VERB_SET_AMP_GAIN_MUTE,
8432 AMP_OUT_MUTE);
8433 }
8434 }
8435}
8436
8437#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
8438#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
8439
8440/* add playback controls from the parsed DAC table */
8441/* Based on ALC880 version. But ALC861VD has separate,
8442 * different NIDs for mute/unmute switch and volume control */
8443static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
8444 const struct auto_pin_cfg *cfg)
8445{
8446 char name[32];
8447 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"};
8448 hda_nid_t nid_v, nid_s;
8449 int i, err;
8450
8451 for (i = 0; i < cfg->line_outs; i++) {
8452 if (! spec->multiout.dac_nids[i])
8453 continue;
8454 nid_v = alc861vd_idx_to_mixer_vol(
8455 alc880_dac_to_idx(
8456 spec->multiout.dac_nids[i]));
8457 nid_s = alc861vd_idx_to_mixer_switch(
8458 alc880_dac_to_idx(
8459 spec->multiout.dac_nids[i]));
8460
8461 if (i == 2) {
8462 /* Center/LFE */
8463 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL,
8464 "Center Playback Volume",
8465 HDA_COMPOSE_AMP_VAL(nid_v, 1,
8466 0, HDA_OUTPUT))) < 0)
8467 return err;
8468 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL,
8469 "LFE Playback Volume",
8470 HDA_COMPOSE_AMP_VAL(nid_v, 2,
8471 0, HDA_OUTPUT))) < 0)
8472 return err;
8473 if ((err = add_control(spec, ALC_CTL_BIND_MUTE,
8474 "Center Playback Switch",
8475 HDA_COMPOSE_AMP_VAL(nid_s, 1,
8476 2, HDA_INPUT))) < 0)
8477 return err;
8478 if ((err = add_control(spec, ALC_CTL_BIND_MUTE,
8479 "LFE Playback Switch",
8480 HDA_COMPOSE_AMP_VAL(nid_s, 2,
8481 2, HDA_INPUT))) < 0)
8482 return err;
8483 } else {
8484 sprintf(name, "%s Playback Volume", chname[i]);
8485 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8486 HDA_COMPOSE_AMP_VAL(nid_v, 3,
8487 0, HDA_OUTPUT))) < 0)
8488 return err;
8489 sprintf(name, "%s Playback Switch", chname[i]);
8490 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
8491 HDA_COMPOSE_AMP_VAL(nid_v, 3,
8492 2, HDA_INPUT))) < 0)
8493 return err;
8494 }
8495 }
8496 return 0;
8497}
8498
8499/* add playback controls for speaker and HP outputs */
8500/* Based on ALC880 version. But ALC861VD has separate,
8501 * different NIDs for mute/unmute switch and volume control */
8502static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
8503 hda_nid_t pin, const char *pfx)
8504{
8505 hda_nid_t nid_v, nid_s;
8506 int err;
8507 char name[32];
8508
8509 if (! pin)
8510 return 0;
8511
8512 if (alc880_is_fixed_pin(pin)) {
8513 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
8514 /* specify the DAC as the extra output */
8515 if (! spec->multiout.hp_nid)
8516 spec->multiout.hp_nid = nid_v;
8517 else
8518 spec->multiout.extra_out_nid[0] = nid_v;
8519 /* control HP volume/switch on the output mixer amp */
8520 nid_v = alc861vd_idx_to_mixer_vol(
8521 alc880_fixed_pin_idx(pin));
8522 nid_s = alc861vd_idx_to_mixer_switch(
8523 alc880_fixed_pin_idx(pin));
8524
8525 sprintf(name, "%s Playback Volume", pfx);
8526 if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name,
8527 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
8528 HDA_OUTPUT))) < 0)
8529 return err;
8530 sprintf(name, "%s Playback Switch", pfx);
8531 if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name,
8532 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
8533 HDA_INPUT))) < 0)
8534 return err;
8535 } else if (alc880_is_multi_pin(pin)) {
8536 /* set manual connection */
8537 /* we have only a switch on HP-out PIN */
8538 sprintf(name, "%s Playback Switch", pfx);
8539 if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name,
8540 HDA_COMPOSE_AMP_VAL(pin, 3, 0,
8541 HDA_OUTPUT))) < 0)
8542 return err;
8543 }
8544 return 0;
8545}
8546
8547/* parse the BIOS configuration and set up the alc_spec
8548 * return 1 if successful, 0 if the proper config is not found,
8549 * or a negative error code
8550 * Based on ALC880 version - had to change it to override
8551 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
8552static int alc861vd_parse_auto_config(struct hda_codec *codec)
8553{
8554 struct alc_spec *spec = codec->spec;
8555 int err;
8556 static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
8557
8558 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
8559 alc861vd_ignore)) < 0)
8560 return err;
8561 if (! spec->autocfg.line_outs)
8562 return 0; /* can't find valid BIOS pin config */
8563
8564 if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 ||
8565 (err = alc861vd_auto_create_multi_out_ctls(spec,
8566 &spec->autocfg)) < 0 ||
8567 (err = alc861vd_auto_create_extra_out(spec,
8568 spec->autocfg.speaker_pins[0], "Speaker")) < 0 ||
8569 (err = alc861vd_auto_create_extra_out(spec,
8570 spec->autocfg.hp_pins[0], "Headphone")) < 0 ||
8571 (err = alc880_auto_create_analog_input_ctls(spec,
8572 &spec->autocfg)) < 0)
8573 return err;
8574
8575 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
8576
8577 if (spec->autocfg.dig_out_pin)
8578 spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
8579
8580 if (spec->kctl_alloc)
8581 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
8582
8583 spec->init_verbs[spec->num_init_verbs++]
8584 = alc861vd_volume_init_verbs;
8585
8586 spec->num_mux_defs = 1;
8587 spec->input_mux = &spec->private_imux;
8588
8589 return 1;
8590}
8591
8592/* additional initialization for auto-configuration model */
8593static void alc861vd_auto_init(struct hda_codec *codec)
8594{
8595 alc861vd_auto_init_multi_out(codec);
8596 alc861vd_auto_init_hp_out(codec);
8597 alc861vd_auto_init_analog_input(codec);
8598}
8599
8600static int patch_alc861vd(struct hda_codec *codec)
8601{
8602 struct alc_spec *spec;
8603 int err, board_config;
8604
8605 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
8606 if (spec == NULL)
8607 return -ENOMEM;
8608
8609 codec->spec = spec;
8610
8611 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
8612 alc861vd_models,
8613 alc861vd_cfg_tbl);
8614
8615 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
8616 printk(KERN_INFO "hda_codec: Unknown model for ALC660VD/"
8617 "ALC861VD, trying auto-probe from BIOS...\n");
8618 board_config = ALC861VD_AUTO;
8619 }
8620
8621 if (board_config == ALC861VD_AUTO) {
8622 /* automatic parse from the BIOS config */
8623 err = alc861vd_parse_auto_config(codec);
8624 if (err < 0) {
8625 alc_free(codec);
8626 return err;
8627 } else if (! err) {
8628 printk(KERN_INFO
8629 "hda_codec: Cannot set up configuration "
8630 "from BIOS. Using base mode...\n");
8631 board_config = ALC861VD_3ST;
8632 }
8633 }
8634
8635 if (board_config != ALC861VD_AUTO)
8636 setup_preset(spec, &alc861vd_presets[board_config]);
8637
8638 spec->stream_name_analog = "ALC861VD Analog";
8639 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
8640 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
8641
8642 spec->stream_name_digital = "ALC861VD Digital";
8643 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
8644 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
8645
8646 spec->adc_nids = alc861vd_adc_nids;
8647 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
8648
8649 spec->mixers[spec->num_mixers] = alc861vd_capture_mixer;
8650 spec->num_mixers++;
8651
8652 codec->patch_ops = alc_patch_ops;
8653
8654 if (board_config == ALC861VD_AUTO)
8655 spec->init_hook = alc861vd_auto_init;
8656
8657 return 0;
8658}
8659
8660/*
6849 * patch entries 8661 * patch entries
6850 */ 8662 */
6851struct hda_codec_preset snd_hda_preset_realtek[] = { 8663struct hda_codec_preset snd_hda_preset_realtek[] = {
6852 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, 8664 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
6853 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, 8665 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
6854 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, 8666 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
8667 .patch = patch_alc861 },
8668 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
8669 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
8670 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
8671 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
6855 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, 8672 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
6856 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, 8673 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 },
6857 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, 8674 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
6858 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 }, 8675 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc883 },
6859 { .id = 0x10ec0861, .rev = 0x100300, .name = "ALC861",
6860 .patch = patch_alc861 },
6861 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
6862 .patch = patch_alc861 },
6863 {} /* terminator */ 8676 {} /* terminator */
6864}; 8677};
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index fe51ef3e49d2..6f4a39273b98 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -37,14 +37,37 @@
37#define NUM_CONTROL_ALLOC 32 37#define NUM_CONTROL_ALLOC 32
38#define STAC_HP_EVENT 0x37 38#define STAC_HP_EVENT 0x37
39 39
40#define STAC_REF 0 40enum {
41#define STAC_D945GTP3 1 41 STAC_REF,
42#define STAC_D945GTP5 2 42 STAC_9200_MODELS
43#define STAC_MACMINI 3 43};
44#define STAC_922X_MODELS 4 /* number of 922x models */ 44
45#define STAC_D965_3ST 4 45enum {
46#define STAC_D965_5ST 5 46 STAC_9205_REF,
47#define STAC_927X_MODELS 6 /* number of 922x models */ 47 STAC_9205_MODELS
48};
49
50enum {
51 STAC_925x_REF,
52 STAC_M2_2,
53 STAC_MA6,
54 STAC_925x_MODELS
55};
56
57enum {
58 STAC_D945_REF,
59 STAC_D945GTP3,
60 STAC_D945GTP5,
61 STAC_MACMINI,
62 STAC_922X_MODELS
63};
64
65enum {
66 STAC_D965_REF,
67 STAC_D965_3ST,
68 STAC_D965_5ST,
69 STAC_927X_MODELS
70};
48 71
49struct sigmatel_spec { 72struct sigmatel_spec {
50 struct snd_kcontrol_new *mixers[4]; 73 struct snd_kcontrol_new *mixers[4];
@@ -67,6 +90,9 @@ struct sigmatel_spec {
67 unsigned int num_adcs; 90 unsigned int num_adcs;
68 hda_nid_t *mux_nids; 91 hda_nid_t *mux_nids;
69 unsigned int num_muxes; 92 unsigned int num_muxes;
93 hda_nid_t *dmic_nids;
94 unsigned int num_dmics;
95 hda_nid_t dmux_nid;
70 hda_nid_t dig_in_nid; 96 hda_nid_t dig_in_nid;
71 97
72 /* pin widgets */ 98 /* pin widgets */
@@ -80,6 +106,8 @@ struct sigmatel_spec {
80 struct snd_kcontrol_new *mixer; 106 struct snd_kcontrol_new *mixer;
81 107
82 /* capture source */ 108 /* capture source */
109 struct hda_input_mux *dinput_mux;
110 unsigned int cur_dmux;
83 struct hda_input_mux *input_mux; 111 struct hda_input_mux *input_mux;
84 unsigned int cur_mux[3]; 112 unsigned int cur_mux[3];
85 113
@@ -92,6 +120,7 @@ struct sigmatel_spec {
92 struct auto_pin_cfg autocfg; 120 struct auto_pin_cfg autocfg;
93 unsigned int num_kctl_alloc, num_kctl_used; 121 unsigned int num_kctl_alloc, num_kctl_used;
94 struct snd_kcontrol_new *kctl_alloc; 122 struct snd_kcontrol_new *kctl_alloc;
123 struct hda_input_mux private_dimux;
95 struct hda_input_mux private_imux; 124 struct hda_input_mux private_imux;
96}; 125};
97 126
@@ -107,6 +136,18 @@ static hda_nid_t stac9200_dac_nids[1] = {
107 0x02, 136 0x02,
108}; 137};
109 138
139static hda_nid_t stac925x_adc_nids[1] = {
140 0x03,
141};
142
143static hda_nid_t stac925x_mux_nids[1] = {
144 0x0f,
145};
146
147static hda_nid_t stac925x_dac_nids[1] = {
148 0x02,
149};
150
110static hda_nid_t stac922x_adc_nids[2] = { 151static hda_nid_t stac922x_adc_nids[2] = {
111 0x06, 0x07, 152 0x06, 0x07,
112}; 153};
@@ -131,11 +172,20 @@ static hda_nid_t stac9205_mux_nids[2] = {
131 0x19, 0x1a 172 0x19, 0x1a
132}; 173};
133 174
175static hda_nid_t stac9205_dmic_nids[3] = {
176 0x17, 0x18, 0
177};
178
134static hda_nid_t stac9200_pin_nids[8] = { 179static hda_nid_t stac9200_pin_nids[8] = {
135 0x08, 0x09, 0x0d, 0x0e, 180 0x08, 0x09, 0x0d, 0x0e,
136 0x0f, 0x10, 0x11, 0x12, 181 0x0f, 0x10, 0x11, 0x12,
137}; 182};
138 183
184static hda_nid_t stac925x_pin_nids[8] = {
185 0x07, 0x08, 0x0a, 0x0b,
186 0x0c, 0x0d, 0x10, 0x11,
187};
188
139static hda_nid_t stac922x_pin_nids[10] = { 189static hda_nid_t stac922x_pin_nids[10] = {
140 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 190 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
141 0x0f, 0x10, 0x11, 0x15, 0x1b, 191 0x0f, 0x10, 0x11, 0x15, 0x1b,
@@ -154,6 +204,34 @@ static hda_nid_t stac9205_pin_nids[12] = {
154 204
155}; 205};
156 206
207static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol,
208 struct snd_ctl_elem_info *uinfo)
209{
210 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
211 struct sigmatel_spec *spec = codec->spec;
212 return snd_hda_input_mux_info(spec->dinput_mux, uinfo);
213}
214
215static int stac92xx_dmux_enum_get(struct snd_kcontrol *kcontrol,
216 struct snd_ctl_elem_value *ucontrol)
217{
218 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
219 struct sigmatel_spec *spec = codec->spec;
220
221 ucontrol->value.enumerated.item[0] = spec->cur_dmux;
222 return 0;
223}
224
225static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol,
226 struct snd_ctl_elem_value *ucontrol)
227{
228 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
229 struct sigmatel_spec *spec = codec->spec;
230
231 return snd_hda_input_mux_put(codec, spec->dinput_mux, ucontrol,
232 spec->dmux_nid, &spec->cur_dmux);
233}
234
157static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 235static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
158{ 236{
159 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 237 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
@@ -187,6 +265,12 @@ static struct hda_verb stac9200_core_init[] = {
187 {} 265 {}
188}; 266};
189 267
268static struct hda_verb stac925x_core_init[] = {
269 /* set dac0mux for dac converter */
270 { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00},
271 {}
272};
273
190static struct hda_verb stac922x_core_init[] = { 274static struct hda_verb stac922x_core_init[] = {
191 /* set master volume and direct control */ 275 /* set master volume and direct control */
192 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, 276 { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff},
@@ -232,6 +316,23 @@ static struct snd_kcontrol_new stac9200_mixer[] = {
232 { } /* end */ 316 { } /* end */
233}; 317};
234 318
319static struct snd_kcontrol_new stac925x_mixer[] = {
320 HDA_CODEC_VOLUME("Master Playback Volume", 0xe, 0, HDA_OUTPUT),
321 HDA_CODEC_MUTE("Master Playback Switch", 0xe, 0, HDA_OUTPUT),
322 {
323 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
324 .name = "Input Source",
325 .count = 1,
326 .info = stac92xx_mux_enum_info,
327 .get = stac92xx_mux_enum_get,
328 .put = stac92xx_mux_enum_put,
329 },
330 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT),
331 HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_OUTPUT),
332 HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT),
333 { } /* end */
334};
335
235/* This needs to be generated dynamically based on sequence */ 336/* This needs to be generated dynamically based on sequence */
236static struct snd_kcontrol_new stac922x_mixer[] = { 337static struct snd_kcontrol_new stac922x_mixer[] = {
237 { 338 {
@@ -263,7 +364,7 @@ static struct snd_kcontrol_new stac9227_mixer[] = {
263 { } /* end */ 364 { } /* end */
264}; 365};
265 366
266static snd_kcontrol_new_t stac927x_mixer[] = { 367static struct snd_kcontrol_new stac927x_mixer[] = {
267 { 368 {
268 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 369 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
269 .name = "Input Source", 370 .name = "Input Source",
@@ -278,7 +379,15 @@ static snd_kcontrol_new_t stac927x_mixer[] = {
278 { } /* end */ 379 { } /* end */
279}; 380};
280 381
281static snd_kcontrol_new_t stac9205_mixer[] = { 382static struct snd_kcontrol_new stac9205_mixer[] = {
383 {
384 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
385 .name = "Digital Input Source",
386 .count = 1,
387 .info = stac92xx_dmux_enum_info,
388 .get = stac92xx_dmux_enum_get,
389 .put = stac92xx_dmux_enum_put,
390 },
282 { 391 {
283 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 392 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
284 .name = "Input Source", 393 .name = "Input Source",
@@ -327,22 +436,64 @@ static unsigned int ref9200_pin_configs[8] = {
327 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, 436 0x02a19020, 0x01a19021, 0x90100140, 0x01813122,
328}; 437};
329 438
330static unsigned int *stac9200_brd_tbl[] = { 439static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
331 ref9200_pin_configs, 440 [STAC_REF] = ref9200_pin_configs,
441};
442
443static const char *stac9200_models[STAC_9200_MODELS] = {
444 [STAC_REF] = "ref",
332}; 445};
333 446
334static struct hda_board_config stac9200_cfg_tbl[] = { 447static struct snd_pci_quirk stac9200_cfg_tbl[] = {
335 { .modelname = "ref", 448 /* SigmaTel reference board */
336 .pci_subvendor = PCI_VENDOR_ID_INTEL, 449 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
337 .pci_subdevice = 0x2668, /* DFI LanParty */ 450 "DFI LanParty", STAC_REF),
338 .config = STAC_REF },
339 /* Dell laptops have BIOS problem */ 451 /* Dell laptops have BIOS problem */
340 { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01b5, 452 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01b5,
341 .config = STAC_REF }, /* Dell Inspiron 630m */ 453 "Dell Inspiron 630m", STAC_REF),
342 { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01c2, 454 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01c2,
343 .config = STAC_REF }, /* Dell Latitude D620 */ 455 "Dell Latitude D620", STAC_REF),
344 { .pci_subvendor = PCI_VENDOR_ID_DELL, .pci_subdevice = 0x01cb, 456 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cb,
345 .config = STAC_REF }, /* Dell Latitude 120L */ 457 "Dell Latitude 120L", STAC_REF),
458 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01cc,
459 "Dell Latitude D820", STAC_REF),
460 {} /* terminator */
461};
462
463static unsigned int ref925x_pin_configs[8] = {
464 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
465 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e,
466};
467
468static unsigned int stac925x_MA6_pin_configs[8] = {
469 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021,
470 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e,
471};
472
473static unsigned int stac925xM2_2_pin_configs[8] = {
474 0x40c003f3, 0x424503f2, 0x041800f4, 0x02a19020,
475 0x50a103F0, 0x90100210, 0x400003f1, 0x9033032e,
476};
477
478static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
479 [STAC_REF] = ref925x_pin_configs,
480 [STAC_M2_2] = stac925xM2_2_pin_configs,
481 [STAC_MA6] = stac925x_MA6_pin_configs,
482};
483
484static const char *stac925x_models[STAC_925x_MODELS] = {
485 [STAC_REF] = "ref",
486 [STAC_M2_2] = "m2-2",
487 [STAC_MA6] = "m6",
488};
489
490static struct snd_pci_quirk stac925x_cfg_tbl[] = {
491 /* SigmaTel reference board */
492 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF),
493 SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF),
494 SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF),
495 SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6),
496 SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2),
346 {} /* terminator */ 497 {} /* terminator */
347}; 498};
348 499
@@ -365,100 +516,80 @@ static unsigned int d945gtp5_pin_configs[10] = {
365}; 516};
366 517
367static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { 518static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
368 [STAC_REF] = ref922x_pin_configs, 519 [STAC_D945_REF] = ref922x_pin_configs,
369 [STAC_D945GTP3] = d945gtp3_pin_configs, 520 [STAC_D945GTP3] = d945gtp3_pin_configs,
370 [STAC_D945GTP5] = d945gtp5_pin_configs, 521 [STAC_D945GTP5] = d945gtp5_pin_configs,
371 [STAC_MACMINI] = d945gtp5_pin_configs, 522 [STAC_MACMINI] = d945gtp5_pin_configs,
372}; 523};
373 524
374static struct hda_board_config stac922x_cfg_tbl[] = { 525static const char *stac922x_models[STAC_922X_MODELS] = {
375 { .modelname = "5stack", .config = STAC_D945GTP5 }, 526 [STAC_D945_REF] = "ref",
376 { .modelname = "3stack", .config = STAC_D945GTP3 }, 527 [STAC_D945GTP5] = "5stack",
377 { .modelname = "ref", 528 [STAC_D945GTP3] = "3stack",
378 .pci_subvendor = PCI_VENDOR_ID_INTEL, 529 [STAC_MACMINI] = "macmini",
379 .pci_subdevice = 0x2668, /* DFI LanParty */ 530};
380 .config = STAC_REF }, /* SigmaTel reference board */ 531
381 /* Intel 945G based systems */ 532static struct snd_pci_quirk stac922x_cfg_tbl[] = {
382 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 533 /* SigmaTel reference board */
383 .pci_subdevice = 0x0101, 534 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
384 .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ 535 "DFI LanParty", STAC_D945_REF),
385 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 536 /* Intel 945G based systems */
386 .pci_subdevice = 0x0202, 537 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101,
387 .config = STAC_D945GTP3 }, /* Intel D945GNT - 3 Stack */ 538 "Intel D945G", STAC_D945GTP3),
388 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 539 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0202,
389 .pci_subdevice = 0x0606, 540 "Intel D945G", STAC_D945GTP3),
390 .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ 541 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0606,
391 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 542 "Intel D945G", STAC_D945GTP3),
392 .pci_subdevice = 0x0601, 543 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0601,
393 .config = STAC_D945GTP3 }, /* Intel D945GTP - 3 Stack */ 544 "Intel D945G", STAC_D945GTP3),
394 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 545 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0111,
395 .pci_subdevice = 0x0111, 546 "Intel D945G", STAC_D945GTP3),
396 .config = STAC_D945GTP3 }, /* Intel D945GZP - 3 Stack */ 547 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1115,
397 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 548 "Intel D945G", STAC_D945GTP3),
398 .pci_subdevice = 0x1115, 549 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1116,
399 .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ 550 "Intel D945G", STAC_D945GTP3),
400 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 551 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1117,
401 .pci_subdevice = 0x1116, 552 "Intel D945G", STAC_D945GTP3),
402 .config = STAC_D945GTP3 }, /* Intel D945GBO - 3 Stack */ 553 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1118,
403 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 554 "Intel D945G", STAC_D945GTP3),
404 .pci_subdevice = 0x1117, 555 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x1119,
405 .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ 556 "Intel D945G", STAC_D945GTP3),
406 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 557 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x8826,
407 .pci_subdevice = 0x1118, 558 "Intel D945G", STAC_D945GTP3),
408 .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ 559 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5049,
409 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 560 "Intel D945G", STAC_D945GTP3),
410 .pci_subdevice = 0x1119, 561 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5055,
411 .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ 562 "Intel D945G", STAC_D945GTP3),
412 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 563 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x5048,
413 .pci_subdevice = 0x8826, 564 "Intel D945G", STAC_D945GTP3),
414 .config = STAC_D945GTP3 }, /* Intel D945GPM - 3 Stack */ 565 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0110,
415 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 566 "Intel D945G", STAC_D945GTP3),
416 .pci_subdevice = 0x5049, 567 /* Intel D945G 5-stack systems */
417 .config = STAC_D945GTP3 }, /* Intel D945GCZ - 3 Stack */ 568 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0404,
418 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 569 "Intel D945G", STAC_D945GTP5),
419 .pci_subdevice = 0x5055, 570 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0303,
420 .config = STAC_D945GTP3 }, /* Intel D945GCZ - 3 Stack */ 571 "Intel D945G", STAC_D945GTP5),
421 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 572 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0013,
422 .pci_subdevice = 0x5048, 573 "Intel D945G", STAC_D945GTP5),
423 .config = STAC_D945GTP3 }, /* Intel D945GPB - 3 Stack */ 574 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0417,
424 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 575 "Intel D945G", STAC_D945GTP5),
425 .pci_subdevice = 0x0110, 576 /* Intel 945P based systems */
426 .config = STAC_D945GTP3 }, /* Intel D945GLR - 3 Stack */ 577 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0b0b,
427 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 578 "Intel D945P", STAC_D945GTP3),
428 .pci_subdevice = 0x0404, 579 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0112,
429 .config = STAC_D945GTP5 }, /* Intel D945GTP - 5 Stack */ 580 "Intel D945P", STAC_D945GTP3),
430 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 581 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0d0d,
431 .pci_subdevice = 0x0303, 582 "Intel D945P", STAC_D945GTP3),
432 .config = STAC_D945GTP5 }, /* Intel D945GNT - 5 Stack */ 583 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0909,
433 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 584 "Intel D945P", STAC_D945GTP3),
434 .pci_subdevice = 0x0013, 585 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0505,
435 .config = STAC_D945GTP5 }, /* Intel D955XBK - 5 Stack */ 586 "Intel D945P", STAC_D945GTP3),
436 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 587 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707,
437 .pci_subdevice = 0x0417, 588 "Intel D945P", STAC_D945GTP5),
438 .config = STAC_D945GTP5 }, /* Intel D975XBK - 5 Stack */ 589 /* other systems */
439 /* Intel 945P based systems */ 590 /* Apple Mac Mini (early 2006) */
440 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 591 SND_PCI_QUIRK(0x8384, 0x7680,
441 .pci_subdevice = 0x0b0b, 592 "Mac Mini", STAC_MACMINI),
442 .config = STAC_D945GTP3 }, /* Intel D945PSN - 3 Stack */
443 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
444 .pci_subdevice = 0x0112,
445 .config = STAC_D945GTP3 }, /* Intel D945PLN - 3 Stack */
446 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
447 .pci_subdevice = 0x0d0d,
448 .config = STAC_D945GTP3 }, /* Intel D945PLM - 3 Stack */
449 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
450 .pci_subdevice = 0x0909,
451 .config = STAC_D945GTP3 }, /* Intel D945PAW - 3 Stack */
452 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
453 .pci_subdevice = 0x0505,
454 .config = STAC_D945GTP3 }, /* Intel D945PLM - 3 Stack */
455 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
456 .pci_subdevice = 0x0707,
457 .config = STAC_D945GTP5 }, /* Intel D945PSV - 5 Stack */
458 /* other systems */
459 { .pci_subvendor = 0x8384,
460 .pci_subdevice = 0x7680,
461 .config = STAC_MACMINI }, /* Apple Mac Mini (early 2006) */
462 {} /* terminator */ 593 {} /* terminator */
463}; 594};
464 595
@@ -484,120 +615,72 @@ static unsigned int d965_5st_pin_configs[14] = {
484}; 615};
485 616
486static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { 617static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
487 [STAC_REF] = ref927x_pin_configs, 618 [STAC_D965_REF] = ref927x_pin_configs,
488 [STAC_D965_3ST] = d965_3st_pin_configs, 619 [STAC_D965_3ST] = d965_3st_pin_configs,
489 [STAC_D965_5ST] = d965_5st_pin_configs, 620 [STAC_D965_5ST] = d965_5st_pin_configs,
490}; 621};
491 622
492static struct hda_board_config stac927x_cfg_tbl[] = { 623static const char *stac927x_models[STAC_927X_MODELS] = {
493 { .modelname = "5stack", .config = STAC_D965_5ST }, 624 [STAC_D965_REF] = "ref",
494 { .modelname = "3stack", .config = STAC_D965_3ST }, 625 [STAC_D965_3ST] = "3stack",
495 { .modelname = "ref", 626 [STAC_D965_5ST] = "5stack",
496 .pci_subvendor = PCI_VENDOR_ID_INTEL, 627};
497 .pci_subdevice = 0x2668, /* DFI LanParty */ 628
498 .config = STAC_REF }, /* SigmaTel reference board */ 629static struct snd_pci_quirk stac927x_cfg_tbl[] = {
630 /* SigmaTel reference board */
631 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
632 "DFI LanParty", STAC_D965_REF),
499 /* Intel 946 based systems */ 633 /* Intel 946 based systems */
500 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 634 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST),
501 .pci_subdevice = 0x3d01, 635 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST),
502 .config = STAC_D965_3ST }, /* D946 configuration */
503 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
504 .pci_subdevice = 0xa301,
505 .config = STAC_D965_3ST }, /* Intel D946GZT - 3 stack */
506 /* 965 based 3 stack systems */ 636 /* 965 based 3 stack systems */
507 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 637 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST),
508 .pci_subdevice = 0x2116, 638 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST),
509 .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ 639 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST),
510 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 640 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST),
511 .pci_subdevice = 0x2115, 641 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST),
512 .config = STAC_D965_3ST }, /* Intel DQ965WC - 3 Stack */ 642 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST),
513 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 643 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST),
514 .pci_subdevice = 0x2114, 644 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST),
515 .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ 645 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST),
516 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 646 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST),
517 .pci_subdevice = 0x2113, 647 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST),
518 .config = STAC_D965_3ST }, /* Intel D965 3Stack config */ 648 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST),
519 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 649 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST),
520 .pci_subdevice = 0x2112, 650 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST),
521 .config = STAC_D965_3ST }, /* Intel DG965MS - 3 Stack */ 651 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST),
522 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 652 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST),
523 .pci_subdevice = 0x2111,
524 .config = STAC_D965_3ST }, /* Intel D965 3Stack config */
525 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
526 .pci_subdevice = 0x2110,
527 .config = STAC_D965_3ST }, /* Intel D965 3Stack config */
528 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
529 .pci_subdevice = 0x2009,
530 .config = STAC_D965_3ST }, /* Intel D965 3Stack config */
531 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
532 .pci_subdevice = 0x2008,
533 .config = STAC_D965_3ST }, /* Intel DQ965GF - 3 Stack */
534 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
535 .pci_subdevice = 0x2007,
536 .config = STAC_D965_3ST }, /* Intel D965 3Stack config */
537 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
538 .pci_subdevice = 0x2006,
539 .config = STAC_D965_3ST }, /* Intel D965 3Stack config */
540 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
541 .pci_subdevice = 0x2005,
542 .config = STAC_D965_3ST }, /* Intel D965 3Stack config */
543 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
544 .pci_subdevice = 0x2004,
545 .config = STAC_D965_3ST }, /* Intel D965 3Stack config */
546 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
547 .pci_subdevice = 0x2003,
548 .config = STAC_D965_3ST }, /* Intel D965 3Stack config */
549 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
550 .pci_subdevice = 0x2002,
551 .config = STAC_D965_3ST }, /* Intel D965 3Stack config */
552 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
553 .pci_subdevice = 0x2001,
554 .config = STAC_D965_3ST }, /* Intel DQ965GF - 3 Stack */
555 /* 965 based 5 stack systems */ 653 /* 965 based 5 stack systems */
556 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 654 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST),
557 .pci_subdevice = 0x2301, 655 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST),
558 .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ 656 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST),
559 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 657 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST),
560 .pci_subdevice = 0x2302, 658 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST),
561 .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ 659 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST),
562 { .pci_subvendor = PCI_VENDOR_ID_INTEL, 660 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST),
563 .pci_subdevice = 0x2303, 661 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST),
564 .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */ 662 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST),
565 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
566 .pci_subdevice = 0x2304,
567 .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */
568 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
569 .pci_subdevice = 0x2305,
570 .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */
571 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
572 .pci_subdevice = 0x2501,
573 .config = STAC_D965_5ST }, /* Intel DG965MQ - 5 Stack */
574 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
575 .pci_subdevice = 0x2502,
576 .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */
577 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
578 .pci_subdevice = 0x2503,
579 .config = STAC_D965_5ST }, /* Intel DG965 - 5 Stack */
580 { .pci_subvendor = PCI_VENDOR_ID_INTEL,
581 .pci_subdevice = 0x2504,
582 .config = STAC_D965_5ST }, /* Intel DQ965GF - 5 Stack */
583 {} /* terminator */ 663 {} /* terminator */
584}; 664};
585 665
586static unsigned int ref9205_pin_configs[12] = { 666static unsigned int ref9205_pin_configs[12] = {
587 0x40000100, 0x40000100, 0x01016011, 0x01014010, 667 0x40000100, 0x40000100, 0x01016011, 0x01014010,
588 0x01813122, 0x01a19021, 0x40000100, 0x40000100, 668 0x01813122, 0x01a19021, 0x40000100, 0x40000100,
589 0x40000100, 0x40000100, 0x01441030, 0x01c41030 669 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030
590}; 670};
591 671
592static unsigned int *stac9205_brd_tbl[] = { 672static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
593 ref9205_pin_configs, 673 ref9205_pin_configs,
594}; 674};
595 675
596static struct hda_board_config stac9205_cfg_tbl[] = { 676static const char *stac9205_models[STAC_9205_MODELS] = {
597 { .modelname = "ref", 677 [STAC_9205_REF] = "ref",
598 .pci_subvendor = PCI_VENDOR_ID_INTEL, 678};
599 .pci_subdevice = 0x2668, /* DFI LanParty */ 679
600 .config = STAC_REF }, /* SigmaTel reference board */ 680static struct snd_pci_quirk stac9205_cfg_tbl[] = {
681 /* SigmaTel reference board */
682 SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668,
683 "DFI LanParty", STAC_9205_REF),
601 {} /* terminator */ 684 {} /* terminator */
602}; 685};
603 686
@@ -1154,6 +1237,58 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
1154 return 0; 1237 return 0;
1155} 1238}
1156 1239
1240/* labels for dmic mux inputs */
1241static const char *stac92xx_dmic_labels[5] = {
1242 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
1243 "Digital Mic 3", "Digital Mic 4"
1244};
1245
1246/* create playback/capture controls for input pins on dmic capable codecs */
1247static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
1248 const struct auto_pin_cfg *cfg)
1249{
1250 struct sigmatel_spec *spec = codec->spec;
1251 struct hda_input_mux *dimux = &spec->private_dimux;
1252 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
1253 int i, j;
1254
1255 dimux->items[dimux->num_items].label = stac92xx_dmic_labels[0];
1256 dimux->items[dimux->num_items].index = 0;
1257 dimux->num_items++;
1258
1259 for (i = 0; i < spec->num_dmics; i++) {
1260 int index;
1261 int num_cons;
1262 unsigned int def_conf;
1263
1264 def_conf = snd_hda_codec_read(codec,
1265 spec->dmic_nids[i],
1266 0,
1267 AC_VERB_GET_CONFIG_DEFAULT,
1268 0);
1269 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
1270 continue;
1271
1272 num_cons = snd_hda_get_connections(codec,
1273 spec->dmux_nid,
1274 con_lst,
1275 HDA_MAX_NUM_INPUTS);
1276 for (j = 0; j < num_cons; j++)
1277 if (con_lst[j] == spec->dmic_nids[i]) {
1278 index = j;
1279 goto found;
1280 }
1281 continue;
1282found:
1283 dimux->items[dimux->num_items].label =
1284 stac92xx_dmic_labels[dimux->num_items];
1285 dimux->items[dimux->num_items].index = index;
1286 dimux->num_items++;
1287 }
1288
1289 return 0;
1290}
1291
1157/* create playback/capture controls for input pins */ 1292/* create playback/capture controls for input pins */
1158static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) 1293static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg)
1159{ 1294{
@@ -1238,7 +1373,9 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
1238 struct sigmatel_spec *spec = codec->spec; 1373 struct sigmatel_spec *spec = codec->spec;
1239 int err; 1374 int err;
1240 1375
1241 if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL)) < 0) 1376 if ((err = snd_hda_parse_pin_def_config(codec,
1377 &spec->autocfg,
1378 spec->dmic_nids)) < 0)
1242 return err; 1379 return err;
1243 if (! spec->autocfg.line_outs) 1380 if (! spec->autocfg.line_outs)
1244 return 0; /* can't find valid pin config */ 1381 return 0; /* can't find valid pin config */
@@ -1254,6 +1391,11 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
1254 (err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0) 1391 (err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg)) < 0)
1255 return err; 1392 return err;
1256 1393
1394 if (spec->num_dmics > 0)
1395 if ((err = stac92xx_auto_create_dmic_input_ctls(codec,
1396 &spec->autocfg)) < 0)
1397 return err;
1398
1257 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 1399 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1258 if (spec->multiout.max_channels > 2) 1400 if (spec->multiout.max_channels > 2)
1259 spec->surr_switch = 1; 1401 spec->surr_switch = 1;
@@ -1267,6 +1409,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
1267 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1409 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1268 1410
1269 spec->input_mux = &spec->private_imux; 1411 spec->input_mux = &spec->private_imux;
1412 spec->dinput_mux = &spec->private_dimux;
1270 1413
1271 return 1; 1414 return 1;
1272} 1415}
@@ -1366,6 +1509,7 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
1366 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1509 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1367 1510
1368 spec->input_mux = &spec->private_imux; 1511 spec->input_mux = &spec->private_imux;
1512 spec->dinput_mux = &spec->private_dimux;
1369 1513
1370 return 1; 1514 return 1;
1371} 1515}
@@ -1448,6 +1592,11 @@ static int stac92xx_init(struct hda_codec *codec)
1448 stac92xx_auto_set_pinctl(codec, nid, pinctl); 1592 stac92xx_auto_set_pinctl(codec, nid, pinctl);
1449 } 1593 }
1450 } 1594 }
1595 if (spec->num_dmics > 0)
1596 for (i = 0; i < spec->num_dmics; i++)
1597 stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i],
1598 AC_PINCTL_IN_EN);
1599
1451 if (cfg->dig_out_pin) 1600 if (cfg->dig_out_pin)
1452 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, 1601 stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin,
1453 AC_PINCTL_OUT_EN); 1602 AC_PINCTL_OUT_EN);
@@ -1598,7 +1747,9 @@ static int patch_stac9200(struct hda_codec *codec)
1598 codec->spec = spec; 1747 codec->spec = spec;
1599 spec->num_pins = 8; 1748 spec->num_pins = 8;
1600 spec->pin_nids = stac9200_pin_nids; 1749 spec->pin_nids = stac9200_pin_nids;
1601 spec->board_config = snd_hda_check_board_config(codec, stac9200_cfg_tbl); 1750 spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS,
1751 stac9200_models,
1752 stac9200_cfg_tbl);
1602 if (spec->board_config < 0) { 1753 if (spec->board_config < 0) {
1603 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); 1754 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n");
1604 err = stac92xx_save_bios_config_regs(codec); 1755 err = stac92xx_save_bios_config_regs(codec);
@@ -1618,6 +1769,7 @@ static int patch_stac9200(struct hda_codec *codec)
1618 spec->adc_nids = stac9200_adc_nids; 1769 spec->adc_nids = stac9200_adc_nids;
1619 spec->mux_nids = stac9200_mux_nids; 1770 spec->mux_nids = stac9200_mux_nids;
1620 spec->num_muxes = 1; 1771 spec->num_muxes = 1;
1772 spec->num_dmics = 0;
1621 1773
1622 spec->init = stac9200_core_init; 1774 spec->init = stac9200_core_init;
1623 spec->mixer = stac9200_mixer; 1775 spec->mixer = stac9200_mixer;
@@ -1633,6 +1785,56 @@ static int patch_stac9200(struct hda_codec *codec)
1633 return 0; 1785 return 0;
1634} 1786}
1635 1787
1788static int patch_stac925x(struct hda_codec *codec)
1789{
1790 struct sigmatel_spec *spec;
1791 int err;
1792
1793 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1794 if (spec == NULL)
1795 return -ENOMEM;
1796
1797 codec->spec = spec;
1798 spec->num_pins = 8;
1799 spec->pin_nids = stac925x_pin_nids;
1800 spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS,
1801 stac925x_models,
1802 stac925x_cfg_tbl);
1803 if (spec->board_config < 0) {
1804 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x, using BIOS defaults\n");
1805 err = stac92xx_save_bios_config_regs(codec);
1806 if (err < 0) {
1807 stac92xx_free(codec);
1808 return err;
1809 }
1810 spec->pin_configs = spec->bios_pin_configs;
1811 } else if (stac925x_brd_tbl[spec->board_config] != NULL){
1812 spec->pin_configs = stac925x_brd_tbl[spec->board_config];
1813 stac92xx_set_config_regs(codec);
1814 }
1815
1816 spec->multiout.max_channels = 2;
1817 spec->multiout.num_dacs = 1;
1818 spec->multiout.dac_nids = stac925x_dac_nids;
1819 spec->adc_nids = stac925x_adc_nids;
1820 spec->mux_nids = stac925x_mux_nids;
1821 spec->num_muxes = 1;
1822 spec->num_dmics = 0;
1823
1824 spec->init = stac925x_core_init;
1825 spec->mixer = stac925x_mixer;
1826
1827 err = stac92xx_parse_auto_config(codec, 0x8, 0x7);
1828 if (err < 0) {
1829 stac92xx_free(codec);
1830 return err;
1831 }
1832
1833 codec->patch_ops = stac92xx_patch_ops;
1834
1835 return 0;
1836}
1837
1636static int patch_stac922x(struct hda_codec *codec) 1838static int patch_stac922x(struct hda_codec *codec)
1637{ 1839{
1638 struct sigmatel_spec *spec; 1840 struct sigmatel_spec *spec;
@@ -1645,7 +1847,9 @@ static int patch_stac922x(struct hda_codec *codec)
1645 codec->spec = spec; 1847 codec->spec = spec;
1646 spec->num_pins = 10; 1848 spec->num_pins = 10;
1647 spec->pin_nids = stac922x_pin_nids; 1849 spec->pin_nids = stac922x_pin_nids;
1648 spec->board_config = snd_hda_check_board_config(codec, stac922x_cfg_tbl); 1850 spec->board_config = snd_hda_check_board_config(codec, STAC_922X_MODELS,
1851 stac922x_models,
1852 stac922x_cfg_tbl);
1649 if (spec->board_config < 0) { 1853 if (spec->board_config < 0) {
1650 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " 1854 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, "
1651 "using BIOS defaults\n"); 1855 "using BIOS defaults\n");
@@ -1663,6 +1867,7 @@ static int patch_stac922x(struct hda_codec *codec)
1663 spec->adc_nids = stac922x_adc_nids; 1867 spec->adc_nids = stac922x_adc_nids;
1664 spec->mux_nids = stac922x_mux_nids; 1868 spec->mux_nids = stac922x_mux_nids;
1665 spec->num_muxes = 2; 1869 spec->num_muxes = 2;
1870 spec->num_dmics = 0;
1666 1871
1667 spec->init = stac922x_core_init; 1872 spec->init = stac922x_core_init;
1668 spec->mixer = stac922x_mixer; 1873 spec->mixer = stac922x_mixer;
@@ -1695,7 +1900,9 @@ static int patch_stac927x(struct hda_codec *codec)
1695 codec->spec = spec; 1900 codec->spec = spec;
1696 spec->num_pins = 14; 1901 spec->num_pins = 14;
1697 spec->pin_nids = stac927x_pin_nids; 1902 spec->pin_nids = stac927x_pin_nids;
1698 spec->board_config = snd_hda_check_board_config(codec, stac927x_cfg_tbl); 1903 spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS,
1904 stac927x_models,
1905 stac927x_cfg_tbl);
1699 if (spec->board_config < 0) { 1906 if (spec->board_config < 0) {
1700 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n"); 1907 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC927x, using BIOS defaults\n");
1701 err = stac92xx_save_bios_config_regs(codec); 1908 err = stac92xx_save_bios_config_regs(codec);
@@ -1714,6 +1921,7 @@ static int patch_stac927x(struct hda_codec *codec)
1714 spec->adc_nids = stac927x_adc_nids; 1921 spec->adc_nids = stac927x_adc_nids;
1715 spec->mux_nids = stac927x_mux_nids; 1922 spec->mux_nids = stac927x_mux_nids;
1716 spec->num_muxes = 3; 1923 spec->num_muxes = 3;
1924 spec->num_dmics = 0;
1717 spec->init = d965_core_init; 1925 spec->init = d965_core_init;
1718 spec->mixer = stac9227_mixer; 1926 spec->mixer = stac9227_mixer;
1719 break; 1927 break;
@@ -1721,6 +1929,7 @@ static int patch_stac927x(struct hda_codec *codec)
1721 spec->adc_nids = stac927x_adc_nids; 1929 spec->adc_nids = stac927x_adc_nids;
1722 spec->mux_nids = stac927x_mux_nids; 1930 spec->mux_nids = stac927x_mux_nids;
1723 spec->num_muxes = 3; 1931 spec->num_muxes = 3;
1932 spec->num_dmics = 0;
1724 spec->init = d965_core_init; 1933 spec->init = d965_core_init;
1725 spec->mixer = stac9227_mixer; 1934 spec->mixer = stac9227_mixer;
1726 break; 1935 break;
@@ -1728,6 +1937,7 @@ static int patch_stac927x(struct hda_codec *codec)
1728 spec->adc_nids = stac927x_adc_nids; 1937 spec->adc_nids = stac927x_adc_nids;
1729 spec->mux_nids = stac927x_mux_nids; 1938 spec->mux_nids = stac927x_mux_nids;
1730 spec->num_muxes = 3; 1939 spec->num_muxes = 3;
1940 spec->num_dmics = 0;
1731 spec->init = stac927x_core_init; 1941 spec->init = stac927x_core_init;
1732 spec->mixer = stac927x_mixer; 1942 spec->mixer = stac927x_mixer;
1733 } 1943 }
@@ -1757,7 +1967,9 @@ static int patch_stac9205(struct hda_codec *codec)
1757 codec->spec = spec; 1967 codec->spec = spec;
1758 spec->num_pins = 14; 1968 spec->num_pins = 14;
1759 spec->pin_nids = stac9205_pin_nids; 1969 spec->pin_nids = stac9205_pin_nids;
1760 spec->board_config = snd_hda_check_board_config(codec, stac9205_cfg_tbl); 1970 spec->board_config = snd_hda_check_board_config(codec, STAC_9205_MODELS,
1971 stac9205_models,
1972 stac9205_cfg_tbl);
1761 if (spec->board_config < 0) { 1973 if (spec->board_config < 0) {
1762 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); 1974 snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n");
1763 err = stac92xx_save_bios_config_regs(codec); 1975 err = stac92xx_save_bios_config_regs(codec);
@@ -1773,13 +1985,28 @@ static int patch_stac9205(struct hda_codec *codec)
1773 1985
1774 spec->adc_nids = stac9205_adc_nids; 1986 spec->adc_nids = stac9205_adc_nids;
1775 spec->mux_nids = stac9205_mux_nids; 1987 spec->mux_nids = stac9205_mux_nids;
1776 spec->num_muxes = 3; 1988 spec->num_muxes = 2;
1989 spec->dmic_nids = stac9205_dmic_nids;
1990 spec->num_dmics = 2;
1991 spec->dmux_nid = 0x1d;
1777 1992
1778 spec->init = stac9205_core_init; 1993 spec->init = stac9205_core_init;
1779 spec->mixer = stac9205_mixer; 1994 spec->mixer = stac9205_mixer;
1780 1995
1781 spec->multiout.dac_nids = spec->dac_nids; 1996 spec->multiout.dac_nids = spec->dac_nids;
1782 1997
1998 /* Configure GPIO0 as EAPD output */
1999 snd_hda_codec_write(codec, codec->afg, 0,
2000 AC_VERB_SET_GPIO_DIRECTION, 0x00000001);
2001 /* Configure GPIO0 as CMOS */
2002 snd_hda_codec_write(codec, codec->afg, 0, 0x7e7, 0x00000000);
2003 /* Assert GPIO0 high */
2004 snd_hda_codec_write(codec, codec->afg, 0,
2005 AC_VERB_SET_GPIO_DATA, 0x00000001);
2006 /* Enable GPIO0 */
2007 snd_hda_codec_write(codec, codec->afg, 0,
2008 AC_VERB_SET_GPIO_MASK, 0x00000001);
2009
1783 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20); 2010 err = stac92xx_parse_auto_config(codec, 0x1f, 0x20);
1784 if (err < 0) { 2011 if (err < 0) {
1785 stac92xx_free(codec); 2012 stac92xx_free(codec);
@@ -1963,18 +2190,19 @@ enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */
1963 /* Unknown. id=0x83847661 and subsys=0x104D1200. */ 2190 /* Unknown. id=0x83847661 and subsys=0x104D1200. */
1964 STAC9872K_VAIO, 2191 STAC9872K_VAIO,
1965 /* AR Series. id=0x83847664 and subsys=104D1300 */ 2192 /* AR Series. id=0x83847664 and subsys=104D1300 */
1966 CXD9872AKD_VAIO 2193 CXD9872AKD_VAIO,
1967 }; 2194 STAC_9872_MODELS,
1968 2195};
1969static struct hda_board_config stac9872_cfg_tbl[] = { 2196
1970 { .modelname = "vaio", .config = CXD9872RD_VAIO }, 2197static const char *stac9872_models[STAC_9872_MODELS] = {
1971 { .modelname = "vaio-ar", .config = CXD9872AKD_VAIO }, 2198 [CXD9872RD_VAIO] = "vaio",
1972 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81e6, 2199 [CXD9872AKD_VAIO] = "vaio-ar",
1973 .config = CXD9872RD_VAIO }, 2200};
1974 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81ef, 2201
1975 .config = CXD9872RD_VAIO }, 2202static struct snd_pci_quirk stac9872_cfg_tbl[] = {
1976 { .pci_subvendor = 0x104d, .pci_subdevice = 0x81fd, 2203 SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO),
1977 .config = CXD9872AKD_VAIO }, 2204 SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO),
2205 SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO),
1978 {} 2206 {}
1979}; 2207};
1980 2208
@@ -1983,7 +2211,9 @@ static int patch_stac9872(struct hda_codec *codec)
1983 struct sigmatel_spec *spec; 2211 struct sigmatel_spec *spec;
1984 int board_config; 2212 int board_config;
1985 2213
1986 board_config = snd_hda_check_board_config(codec, stac9872_cfg_tbl); 2214 board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS,
2215 stac9872_models,
2216 stac9872_cfg_tbl);
1987 if (board_config < 0) 2217 if (board_config < 0)
1988 /* unknown config, let generic-parser do its job... */ 2218 /* unknown config, let generic-parser do its job... */
1989 return snd_hda_parse_generic_codec(codec); 2219 return snd_hda_parse_generic_codec(codec);
@@ -2055,6 +2285,12 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = {
2055 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x }, 2285 { .id = 0x83847627, .name = "STAC9271D", .patch = patch_stac927x },
2056 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x }, 2286 { .id = 0x83847628, .name = "STAC9274X5NH", .patch = patch_stac927x },
2057 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x }, 2287 { .id = 0x83847629, .name = "STAC9274D5NH", .patch = patch_stac927x },
2288 { .id = 0x83847632, .name = "STAC9202", .patch = patch_stac925x },
2289 { .id = 0x83847633, .name = "STAC9202D", .patch = patch_stac925x },
2290 { .id = 0x83847634, .name = "STAC9250", .patch = patch_stac925x },
2291 { .id = 0x83847635, .name = "STAC9250D", .patch = patch_stac925x },
2292 { .id = 0x83847636, .name = "STAC9251", .patch = patch_stac925x },
2293 { .id = 0x83847637, .name = "STAC9250D", .patch = patch_stac925x },
2058 /* The following does not take into account .id=0x83847661 when subsys = 2294 /* The following does not take into account .id=0x83847661 when subsys =
2059 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are 2295 * 104D0C00 which is STAC9225s. Because of this, some SZ Notebooks are
2060 * currently not fully supported. 2296 * currently not fully supported.
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
new file mode 100644
index 000000000000..4c839b031729
--- /dev/null
+++ b/sound/pci/hda/patch_via.c
@@ -0,0 +1,1396 @@
1/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for VIA VT1708 codec
5 *
6 * Copyright (c) 2006 Lydia Wang <lydiawang@viatech.com>
7 * Takashi Iwai <tiwai@suse.de>
8 *
9 * This driver 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 driver 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/* * * * * * * * * * * * * * Release History * * * * * * * * * * * * * * * * */
25/* */
26/* 2006-03-03 Lydia Wang Create the basic patch to support VT1708 codec */
27/* 2006-03-14 Lydia Wang Modify hard code for some pin widget nid */
28/* 2006-08-02 Lydia Wang Add support to VT1709 codec */
29/* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */
30/* */
31/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
32
33
34#include <sound/driver.h>
35#include <linux/init.h>
36#include <linux/delay.h>
37#include <linux/slab.h>
38#include <linux/pci.h>
39#include <sound/core.h>
40#include "hda_codec.h"
41#include "hda_local.h"
42
43
44/* amp values */
45#define AMP_VAL_IDX_SHIFT 19
46#define AMP_VAL_IDX_MASK (0x0f<<19)
47
48#define NUM_CONTROL_ALLOC 32
49#define NUM_VERB_ALLOC 32
50
51/* Pin Widget NID */
52#define VT1708_HP_NID 0x13
53#define VT1708_DIGOUT_NID 0x14
54#define VT1708_DIGIN_NID 0x16
55
56#define VT1709_HP_DAC_NID 0x28
57#define VT1709_DIGOUT_NID 0x13
58#define VT1709_DIGIN_NID 0x17
59
60#define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b)
61#define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713)
62#define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717)
63
64
65enum {
66 VIA_CTL_WIDGET_VOL,
67 VIA_CTL_WIDGET_MUTE,
68};
69
70enum {
71 AUTO_SEQ_FRONT,
72 AUTO_SEQ_SURROUND,
73 AUTO_SEQ_CENLFE,
74 AUTO_SEQ_SIDE
75};
76
77static struct snd_kcontrol_new vt1708_control_templates[] = {
78 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
79 HDA_CODEC_MUTE(NULL, 0, 0, 0),
80};
81
82
83struct via_spec {
84 /* codec parameterization */
85 struct snd_kcontrol_new *mixers[3];
86 unsigned int num_mixers;
87
88 struct hda_verb *init_verbs;
89
90 char *stream_name_analog;
91 struct hda_pcm_stream *stream_analog_playback;
92 struct hda_pcm_stream *stream_analog_capture;
93
94 char *stream_name_digital;
95 struct hda_pcm_stream *stream_digital_playback;
96 struct hda_pcm_stream *stream_digital_capture;
97
98 /* playback */
99 struct hda_multi_out multiout;
100
101 /* capture */
102 unsigned int num_adc_nids;
103 hda_nid_t *adc_nids;
104 hda_nid_t dig_in_nid;
105
106 /* capture source */
107 const struct hda_input_mux *input_mux;
108 unsigned int cur_mux[3];
109
110 /* PCM information */
111 struct hda_pcm pcm_rec[2];
112
113 /* dynamic controls, init_verbs and input_mux */
114 struct auto_pin_cfg autocfg;
115 unsigned int num_kctl_alloc, num_kctl_used;
116 struct snd_kcontrol_new *kctl_alloc;
117 struct hda_input_mux private_imux;
118 hda_nid_t private_dac_nids[4];
119};
120
121static hda_nid_t vt1708_adc_nids[2] = {
122 /* ADC1-2 */
123 0x15, 0x27
124};
125
126static hda_nid_t vt1709_adc_nids[3] = {
127 /* ADC1-2 */
128 0x14, 0x15, 0x16
129};
130
131/* add dynamic controls */
132static int via_add_control(struct via_spec *spec, int type, const char *name,
133 unsigned long val)
134{
135 struct snd_kcontrol_new *knew;
136
137 if (spec->num_kctl_used >= spec->num_kctl_alloc) {
138 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC;
139
140 /* array + terminator */
141 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
142 if (!knew)
143 return -ENOMEM;
144 if (spec->kctl_alloc) {
145 memcpy(knew, spec->kctl_alloc,
146 sizeof(*knew) * spec->num_kctl_alloc);
147 kfree(spec->kctl_alloc);
148 }
149 spec->kctl_alloc = knew;
150 spec->num_kctl_alloc = num;
151 }
152
153 knew = &spec->kctl_alloc[spec->num_kctl_used];
154 *knew = vt1708_control_templates[type];
155 knew->name = kstrdup(name, GFP_KERNEL);
156
157 if (!knew->name)
158 return -ENOMEM;
159 knew->private_value = val;
160 spec->num_kctl_used++;
161 return 0;
162}
163
164/* create input playback/capture controls for the given pin */
165static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
166 const char *ctlname, int idx, int mix_nid)
167{
168 char name[32];
169 int err;
170
171 sprintf(name, "%s Playback Volume", ctlname);
172 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
173 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
174 if (err < 0)
175 return err;
176 sprintf(name, "%s Playback Switch", ctlname);
177 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
178 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
179 if (err < 0)
180 return err;
181 return 0;
182}
183
184static void via_auto_set_output_and_unmute(struct hda_codec *codec,
185 hda_nid_t nid, int pin_type,
186 int dac_idx)
187{
188 /* set as output */
189 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
190 pin_type);
191 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
192 AMP_OUT_UNMUTE);
193}
194
195
196static void via_auto_init_multi_out(struct hda_codec *codec)
197{
198 struct via_spec *spec = codec->spec;
199 int i;
200
201 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
202 hda_nid_t nid = spec->autocfg.line_out_pins[i];
203 if (nid)
204 via_auto_set_output_and_unmute(codec, nid, PIN_OUT, i);
205 }
206}
207
208static void via_auto_init_hp_out(struct hda_codec *codec)
209{
210 struct via_spec *spec = codec->spec;
211 hda_nid_t pin;
212
213 pin = spec->autocfg.hp_pins[0];
214 if (pin) /* connect to front */
215 via_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
216}
217
218static void via_auto_init_analog_input(struct hda_codec *codec)
219{
220 struct via_spec *spec = codec->spec;
221 int i;
222
223 for (i = 0; i < AUTO_PIN_LAST; i++) {
224 hda_nid_t nid = spec->autocfg.input_pins[i];
225
226 snd_hda_codec_write(codec, nid, 0,
227 AC_VERB_SET_PIN_WIDGET_CONTROL,
228 (i <= AUTO_PIN_FRONT_MIC ?
229 PIN_VREF50 : PIN_IN));
230
231 }
232}
233/*
234 * input MUX handling
235 */
236static int via_mux_enum_info(struct snd_kcontrol *kcontrol,
237 struct snd_ctl_elem_info *uinfo)
238{
239 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
240 struct via_spec *spec = codec->spec;
241 return snd_hda_input_mux_info(spec->input_mux, uinfo);
242}
243
244static int via_mux_enum_get(struct snd_kcontrol *kcontrol,
245 struct snd_ctl_elem_value *ucontrol)
246{
247 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
248 struct via_spec *spec = codec->spec;
249 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
250
251 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
252 return 0;
253}
254
255static int via_mux_enum_put(struct snd_kcontrol *kcontrol,
256 struct snd_ctl_elem_value *ucontrol)
257{
258 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
259 struct via_spec *spec = codec->spec;
260 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
261 unsigned int vendor_id = codec->vendor_id;
262
263 /* AIW0 lydia 060801 add for correct sw0 input select */
264 if (IS_VT1708_VENDORID(vendor_id) && (adc_idx == 0))
265 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
266 0x18, &spec->cur_mux[adc_idx]);
267 else if ((IS_VT1709_10CH_VENDORID(vendor_id) ||
268 IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0) )
269 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
270 0x19, &spec->cur_mux[adc_idx]);
271 else
272 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
273 spec->adc_nids[adc_idx],
274 &spec->cur_mux[adc_idx]);
275}
276
277/* capture mixer elements */
278static struct snd_kcontrol_new vt1708_capture_mixer[] = {
279 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT),
280 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT),
281 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT),
282 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x27, 0x0, HDA_INPUT),
283 {
284 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
285 /* The multiple "Capture Source" controls confuse alsamixer
286 * So call somewhat different..
287 * FIXME: the controls appear in the "playback" view!
288 */
289 /* .name = "Capture Source", */
290 .name = "Input Source",
291 .count = 1,
292 .info = via_mux_enum_info,
293 .get = via_mux_enum_get,
294 .put = via_mux_enum_put,
295 },
296 { } /* end */
297};
298/*
299 * generic initialization of ADC, input mixers and output mixers
300 */
301static struct hda_verb vt1708_volume_init_verbs[] = {
302 /*
303 * Unmute ADC0-1 and set the default input to mic-in
304 */
305 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
306 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
307
308
309 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
310 * mixer widget
311 */
312 /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
313 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
314 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
315 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
316 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
317 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
318
319 /*
320 * Set up output mixers (0x19 - 0x1b)
321 */
322 /* set vol=0 to output mixers */
323 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
324 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
325 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
326
327 /* Setup default input to PW4 */
328 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
329 /* Set mic as default input of sw0 */
330 {0x18, AC_VERB_SET_CONNECT_SEL, 0x2},
331 /* PW9 Output enable */
332 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
333};
334
335static int via_playback_pcm_open(struct hda_pcm_stream *hinfo,
336 struct hda_codec *codec,
337 struct snd_pcm_substream *substream)
338{
339 struct via_spec *spec = codec->spec;
340 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream);
341}
342
343static int via_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
344 struct hda_codec *codec,
345 unsigned int stream_tag,
346 unsigned int format,
347 struct snd_pcm_substream *substream)
348{
349 struct via_spec *spec = codec->spec;
350 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
351 stream_tag, format, substream);
352}
353
354static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
355 struct hda_codec *codec,
356 struct snd_pcm_substream *substream)
357{
358 struct via_spec *spec = codec->spec;
359 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
360}
361
362/*
363 * Digital out
364 */
365static int via_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
366 struct hda_codec *codec,
367 struct snd_pcm_substream *substream)
368{
369 struct via_spec *spec = codec->spec;
370 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
371}
372
373static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
374 struct hda_codec *codec,
375 struct snd_pcm_substream *substream)
376{
377 struct via_spec *spec = codec->spec;
378 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
379}
380
381/*
382 * Analog capture
383 */
384static int via_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
385 struct hda_codec *codec,
386 unsigned int stream_tag,
387 unsigned int format,
388 struct snd_pcm_substream *substream)
389{
390 struct via_spec *spec = codec->spec;
391
392 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
393 stream_tag, 0, format);
394 return 0;
395}
396
397static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
398 struct hda_codec *codec,
399 struct snd_pcm_substream *substream)
400{
401 struct via_spec *spec = codec->spec;
402 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
403 0, 0, 0);
404 return 0;
405}
406
407static struct hda_pcm_stream vt1708_pcm_analog_playback = {
408 .substreams = 1,
409 .channels_min = 2,
410 .channels_max = 8,
411 .nid = 0x10, /* NID to query formats and rates */
412 .ops = {
413 .open = via_playback_pcm_open,
414 .prepare = via_playback_pcm_prepare,
415 .cleanup = via_playback_pcm_cleanup
416 },
417};
418
419static struct hda_pcm_stream vt1708_pcm_analog_capture = {
420 .substreams = 2,
421 .channels_min = 2,
422 .channels_max = 2,
423 .nid = 0x15, /* NID to query formats and rates */
424 .ops = {
425 .prepare = via_capture_pcm_prepare,
426 .cleanup = via_capture_pcm_cleanup
427 },
428};
429
430static struct hda_pcm_stream vt1708_pcm_digital_playback = {
431 .substreams = 1,
432 .channels_min = 2,
433 .channels_max = 2,
434 /* NID is set in via_build_pcms */
435 .ops = {
436 .open = via_dig_playback_pcm_open,
437 .close = via_dig_playback_pcm_close
438 },
439};
440
441static struct hda_pcm_stream vt1708_pcm_digital_capture = {
442 .substreams = 1,
443 .channels_min = 2,
444 .channels_max = 2,
445};
446
447static int via_build_controls(struct hda_codec *codec)
448{
449 struct via_spec *spec = codec->spec;
450 int err;
451 int i;
452
453 for (i = 0; i < spec->num_mixers; i++) {
454 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
455 if (err < 0)
456 return err;
457 }
458
459 if (spec->multiout.dig_out_nid) {
460 err = snd_hda_create_spdif_out_ctls(codec,
461 spec->multiout.dig_out_nid);
462 if (err < 0)
463 return err;
464 }
465 if (spec->dig_in_nid) {
466 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
467 if (err < 0)
468 return err;
469 }
470 return 0;
471}
472
473static int via_build_pcms(struct hda_codec *codec)
474{
475 struct via_spec *spec = codec->spec;
476 struct hda_pcm *info = spec->pcm_rec;
477
478 codec->num_pcms = 1;
479 codec->pcm_info = info;
480
481 info->name = spec->stream_name_analog;
482 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
483 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
484 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
485 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
486
487 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
488 spec->multiout.max_channels;
489
490 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
491 codec->num_pcms++;
492 info++;
493 info->name = spec->stream_name_digital;
494 if (spec->multiout.dig_out_nid) {
495 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
496 *(spec->stream_digital_playback);
497 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
498 spec->multiout.dig_out_nid;
499 }
500 if (spec->dig_in_nid) {
501 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
502 *(spec->stream_digital_capture);
503 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
504 spec->dig_in_nid;
505 }
506 }
507
508 return 0;
509}
510
511static void via_free(struct hda_codec *codec)
512{
513 struct via_spec *spec = codec->spec;
514 unsigned int i;
515
516 if (!spec)
517 return;
518
519 if (spec->kctl_alloc) {
520 for (i = 0; i < spec->num_kctl_used; i++)
521 kfree(spec->kctl_alloc[i].name);
522 kfree(spec->kctl_alloc);
523 }
524
525 kfree(codec->spec);
526}
527
528static int via_init(struct hda_codec *codec)
529{
530 struct via_spec *spec = codec->spec;
531 snd_hda_sequence_write(codec, spec->init_verbs);
532 return 0;
533}
534
535#ifdef CONFIG_PM
536/*
537 * resume
538 */
539static int via_resume(struct hda_codec *codec)
540{
541 struct via_spec *spec = codec->spec;
542 int i;
543
544 via_init(codec);
545 for (i = 0; i < spec->num_mixers; i++)
546 snd_hda_resume_ctls(codec, spec->mixers[i]);
547 if (spec->multiout.dig_out_nid)
548 snd_hda_resume_spdif_out(codec);
549 if (spec->dig_in_nid)
550 snd_hda_resume_spdif_in(codec);
551
552 return 0;
553}
554#endif
555
556/*
557 */
558static struct hda_codec_ops via_patch_ops = {
559 .build_controls = via_build_controls,
560 .build_pcms = via_build_pcms,
561 .init = via_init,
562 .free = via_free,
563#ifdef CONFIG_PM
564 .resume = via_resume,
565#endif
566};
567
568/* fill in the dac_nids table from the parsed pin configuration */
569static int vt1708_auto_fill_dac_nids(struct via_spec *spec,
570 const struct auto_pin_cfg *cfg)
571{
572 int i;
573 hda_nid_t nid;
574
575 spec->multiout.num_dacs = cfg->line_outs;
576
577 spec->multiout.dac_nids = spec->private_dac_nids;
578
579 for(i = 0; i < 4; i++) {
580 nid = cfg->line_out_pins[i];
581 if (nid) {
582 /* config dac list */
583 switch (i) {
584 case AUTO_SEQ_FRONT:
585 spec->multiout.dac_nids[i] = 0x10;
586 break;
587 case AUTO_SEQ_CENLFE:
588 spec->multiout.dac_nids[i] = 0x12;
589 break;
590 case AUTO_SEQ_SURROUND:
591 spec->multiout.dac_nids[i] = 0x13;
592 break;
593 case AUTO_SEQ_SIDE:
594 spec->multiout.dac_nids[i] = 0x11;
595 break;
596 }
597 }
598 }
599
600 return 0;
601}
602
603/* add playback controls from the parsed DAC table */
604static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
605 const struct auto_pin_cfg *cfg)
606{
607 char name[32];
608 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
609 hda_nid_t nid, nid_vol = 0;
610 int i, err;
611
612 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
613 nid = cfg->line_out_pins[i];
614
615 if (!nid)
616 continue;
617
618 if (i != AUTO_SEQ_FRONT)
619 nid_vol = 0x1b - i + 1;
620
621 if (i == AUTO_SEQ_CENLFE) {
622 /* Center/LFE */
623 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
624 "Center Playback Volume",
625 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
626 if (err < 0)
627 return err;
628 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
629 "LFE Playback Volume",
630 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
631 if (err < 0)
632 return err;
633 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
634 "Center Playback Switch",
635 HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, HDA_OUTPUT));
636 if (err < 0)
637 return err;
638 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
639 "LFE Playback Switch",
640 HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT));
641 if (err < 0)
642 return err;
643 } else if (i == AUTO_SEQ_FRONT){
644 /* add control to mixer index 0 */
645 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
646 "Master Front Playback Volume",
647 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT));
648 if (err < 0)
649 return err;
650 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
651 "Master Front Playback Switch",
652 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT));
653 if (err < 0)
654 return err;
655
656 /* add control to PW3 */
657 sprintf(name, "%s Playback Volume", chname[i]);
658 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
659 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
660 if (err < 0)
661 return err;
662 sprintf(name, "%s Playback Switch", chname[i]);
663 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
664 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
665 if (err < 0)
666 return err;
667 } else {
668 sprintf(name, "%s Playback Volume", chname[i]);
669 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
670 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
671 if (err < 0)
672 return err;
673 sprintf(name, "%s Playback Switch", chname[i]);
674 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
675 HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT));
676 if (err < 0)
677 return err;
678 }
679 }
680
681 return 0;
682}
683
684static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
685{
686 int err;
687
688 if (!pin)
689 return 0;
690
691 spec->multiout.hp_nid = VT1708_HP_NID; /* AOW3 */
692
693 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
694 "Headphone Playback Volume",
695 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
696 if (err < 0)
697 return err;
698 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
699 "Headphone Playback Switch",
700 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
701 if (err < 0)
702 return err;
703
704 return 0;
705}
706
707/* create playback/capture controls for input pins */
708static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec,
709 const struct auto_pin_cfg *cfg)
710{
711 static char *labels[] = {
712 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
713 };
714 struct hda_input_mux *imux = &spec->private_imux;
715 int i, err, idx = 0;
716
717 /* for internal loopback recording select */
718 imux->items[imux->num_items].label = "Stereo Mixer";
719 imux->items[imux->num_items].index = idx;
720 imux->num_items++;
721
722 for (i = 0; i < AUTO_PIN_LAST; i++) {
723 if (!cfg->input_pins[i])
724 continue;
725
726 switch (cfg->input_pins[i]) {
727 case 0x1d: /* Mic */
728 idx = 2;
729 break;
730
731 case 0x1e: /* Line In */
732 idx = 3;
733 break;
734
735 case 0x21: /* Front Mic */
736 idx = 4;
737 break;
738
739 case 0x24: /* CD */
740 idx = 1;
741 break;
742 }
743 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
744 idx, 0x17);
745 if (err < 0)
746 return err;
747 imux->items[imux->num_items].label = labels[i];
748 imux->items[imux->num_items].index = idx;
749 imux->num_items++;
750 }
751 return 0;
752}
753
754static int vt1708_parse_auto_config(struct hda_codec *codec)
755{
756 struct via_spec *spec = codec->spec;
757 int err;
758
759 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
760 if (err < 0)
761 return err;
762 err = vt1708_auto_fill_dac_nids(spec, &spec->autocfg);
763 if (err < 0)
764 return err;
765 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
766 return 0; /* can't find valid BIOS pin config */
767
768 err = vt1708_auto_create_multi_out_ctls(spec, &spec->autocfg);
769 if (err < 0)
770 return err;
771 err = vt1708_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
772 if (err < 0)
773 return err;
774 err = vt1708_auto_create_analog_input_ctls(spec, &spec->autocfg);
775 if (err < 0)
776 return err;
777
778 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
779
780 if (spec->autocfg.dig_out_pin)
781 spec->multiout.dig_out_nid = VT1708_DIGOUT_NID;
782 if (spec->autocfg.dig_in_pin)
783 spec->dig_in_nid = VT1708_DIGIN_NID;
784
785 if (spec->kctl_alloc)
786 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
787
788 spec->init_verbs = vt1708_volume_init_verbs;
789
790 spec->input_mux = &spec->private_imux;
791
792 return 1;
793}
794
795/* init callback for auto-configuration model -- overriding the default init */
796static int via_auto_init(struct hda_codec *codec)
797{
798 via_init(codec);
799 via_auto_init_multi_out(codec);
800 via_auto_init_hp_out(codec);
801 via_auto_init_analog_input(codec);
802 return 0;
803}
804
805static int patch_vt1708(struct hda_codec *codec)
806{
807 struct via_spec *spec;
808 int err;
809
810 /* create a codec specific record */
811 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
812 if (spec == NULL)
813 return -ENOMEM;
814
815 codec->spec = spec;
816
817 /* automatic parse from the BIOS config */
818 err = vt1708_parse_auto_config(codec);
819 if (err < 0) {
820 via_free(codec);
821 return err;
822 } else if (!err) {
823 printk(KERN_INFO "hda_codec: Cannot set up configuration "
824 "from BIOS. Using genenic mode...\n");
825 }
826
827
828 spec->stream_name_analog = "VT1708 Analog";
829 spec->stream_analog_playback = &vt1708_pcm_analog_playback;
830 spec->stream_analog_capture = &vt1708_pcm_analog_capture;
831
832 spec->stream_name_digital = "VT1708 Digital";
833 spec->stream_digital_playback = &vt1708_pcm_digital_playback;
834 spec->stream_digital_capture = &vt1708_pcm_digital_capture;
835
836
837 if (!spec->adc_nids && spec->input_mux) {
838 spec->adc_nids = vt1708_adc_nids;
839 spec->num_adc_nids = ARRAY_SIZE(vt1708_adc_nids);
840 spec->mixers[spec->num_mixers] = vt1708_capture_mixer;
841 spec->num_mixers++;
842 }
843
844 codec->patch_ops = via_patch_ops;
845
846 codec->patch_ops.init = via_auto_init;
847
848 return 0;
849}
850
851/* capture mixer elements */
852static struct snd_kcontrol_new vt1709_capture_mixer[] = {
853 HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT),
854 HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT),
855 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT),
856 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x15, 0x0, HDA_INPUT),
857 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x16, 0x0, HDA_INPUT),
858 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x16, 0x0, HDA_INPUT),
859 {
860 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
861 /* The multiple "Capture Source" controls confuse alsamixer
862 * So call somewhat different..
863 * FIXME: the controls appear in the "playback" view!
864 */
865 /* .name = "Capture Source", */
866 .name = "Input Source",
867 .count = 1,
868 .info = via_mux_enum_info,
869 .get = via_mux_enum_get,
870 .put = via_mux_enum_put,
871 },
872 { } /* end */
873};
874
875/*
876 * generic initialization of ADC, input mixers and output mixers
877 */
878static struct hda_verb vt1709_10ch_volume_init_verbs[] = {
879 /*
880 * Unmute ADC0-2 and set the default input to mic-in
881 */
882 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
883 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
884 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
885
886
887 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
888 * mixer widget
889 */
890 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
891 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
892 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
893 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
894 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
895 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
896
897 /*
898 * Set up output selector (0x1a, 0x1b, 0x29)
899 */
900 /* set vol=0 to output mixers */
901 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
902 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
903 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
904
905 /*
906 * Unmute PW3 and PW4
907 */
908 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
909 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
910
911 /* Set input of PW4 as AOW4 */
912 {0x20, AC_VERB_SET_CONNECT_SEL, 0x1},
913 /* Set mic as default input of sw0 */
914 {0x19, AC_VERB_SET_CONNECT_SEL, 0x2},
915 /* PW9 Output enable */
916 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
917 { }
918};
919
920static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = {
921 .substreams = 1,
922 .channels_min = 2,
923 .channels_max = 10,
924 .nid = 0x10, /* NID to query formats and rates */
925 .ops = {
926 .open = via_playback_pcm_open,
927 .prepare = via_playback_pcm_prepare,
928 .cleanup = via_playback_pcm_cleanup
929 },
930};
931
932static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = {
933 .substreams = 1,
934 .channels_min = 2,
935 .channels_max = 6,
936 .nid = 0x10, /* NID to query formats and rates */
937 .ops = {
938 .open = via_playback_pcm_open,
939 .prepare = via_playback_pcm_prepare,
940 .cleanup = via_playback_pcm_cleanup
941 },
942};
943
944static struct hda_pcm_stream vt1709_pcm_analog_capture = {
945 .substreams = 2,
946 .channels_min = 2,
947 .channels_max = 2,
948 .nid = 0x14, /* NID to query formats and rates */
949 .ops = {
950 .prepare = via_capture_pcm_prepare,
951 .cleanup = via_capture_pcm_cleanup
952 },
953};
954
955static struct hda_pcm_stream vt1709_pcm_digital_playback = {
956 .substreams = 1,
957 .channels_min = 2,
958 .channels_max = 2,
959 /* NID is set in via_build_pcms */
960 .ops = {
961 .open = via_dig_playback_pcm_open,
962 .close = via_dig_playback_pcm_close
963 },
964};
965
966static struct hda_pcm_stream vt1709_pcm_digital_capture = {
967 .substreams = 1,
968 .channels_min = 2,
969 .channels_max = 2,
970};
971
972static int vt1709_auto_fill_dac_nids(struct via_spec *spec,
973 const struct auto_pin_cfg *cfg)
974{
975 int i;
976 hda_nid_t nid;
977
978 if (cfg->line_outs == 4) /* 10 channels */
979 spec->multiout.num_dacs = cfg->line_outs+1; /* AOW0~AOW4 */
980 else if (cfg->line_outs == 3) /* 6 channels */
981 spec->multiout.num_dacs = cfg->line_outs; /* AOW0~AOW2 */
982
983 spec->multiout.dac_nids = spec->private_dac_nids;
984
985 if (cfg->line_outs == 4) { /* 10 channels */
986 for (i = 0; i < cfg->line_outs; i++) {
987 nid = cfg->line_out_pins[i];
988 if (nid) {
989 /* config dac list */
990 switch (i) {
991 case AUTO_SEQ_FRONT:
992 /* AOW0 */
993 spec->multiout.dac_nids[i] = 0x10;
994 break;
995 case AUTO_SEQ_CENLFE:
996 /* AOW2 */
997 spec->multiout.dac_nids[i] = 0x12;
998 break;
999 case AUTO_SEQ_SURROUND:
1000 /* AOW3 */
1001 spec->multiout.dac_nids[i] = 0x27;
1002 break;
1003 case AUTO_SEQ_SIDE:
1004 /* AOW1 */
1005 spec->multiout.dac_nids[i] = 0x11;
1006 break;
1007 default:
1008 break;
1009 }
1010 }
1011 }
1012 spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */
1013
1014 } else if (cfg->line_outs == 3) { /* 6 channels */
1015 for(i = 0; i < cfg->line_outs; i++) {
1016 nid = cfg->line_out_pins[i];
1017 if (nid) {
1018 /* config dac list */
1019 switch(i) {
1020 case AUTO_SEQ_FRONT:
1021 /* AOW0 */
1022 spec->multiout.dac_nids[i] = 0x10;
1023 break;
1024 case AUTO_SEQ_CENLFE:
1025 /* AOW2 */
1026 spec->multiout.dac_nids[i] = 0x12;
1027 break;
1028 case AUTO_SEQ_SURROUND:
1029 /* AOW1 */
1030 spec->multiout.dac_nids[i] = 0x11;
1031 break;
1032 default:
1033 break;
1034 }
1035 }
1036 }
1037 }
1038
1039 return 0;
1040}
1041
1042/* add playback controls from the parsed DAC table */
1043static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
1044 const struct auto_pin_cfg *cfg)
1045{
1046 char name[32];
1047 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" };
1048 hda_nid_t nid = 0;
1049 int i, err;
1050
1051 for (i = 0; i <= AUTO_SEQ_SIDE; i++) {
1052 nid = cfg->line_out_pins[i];
1053
1054 if (!nid)
1055 continue;
1056
1057 if (i == AUTO_SEQ_CENLFE) {
1058 /* Center/LFE */
1059 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1060 "Center Playback Volume",
1061 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT));
1062 if (err < 0)
1063 return err;
1064 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1065 "LFE Playback Volume",
1066 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT));
1067 if (err < 0)
1068 return err;
1069 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1070 "Center Playback Switch",
1071 HDA_COMPOSE_AMP_VAL(0x1b, 1, 0, HDA_OUTPUT));
1072 if (err < 0)
1073 return err;
1074 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1075 "LFE Playback Switch",
1076 HDA_COMPOSE_AMP_VAL(0x1b, 2, 0, HDA_OUTPUT));
1077 if (err < 0)
1078 return err;
1079 } else if (i == AUTO_SEQ_FRONT){
1080 /* add control to mixer index 0 */
1081 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1082 "Master Front Playback Volume",
1083 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT));
1084 if (err < 0)
1085 return err;
1086 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1087 "Master Front Playback Switch",
1088 HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT));
1089 if (err < 0)
1090 return err;
1091
1092 /* add control to PW3 */
1093 sprintf(name, "%s Playback Volume", chname[i]);
1094 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1095 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
1096 if (err < 0)
1097 return err;
1098 sprintf(name, "%s Playback Switch", chname[i]);
1099 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1100 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
1101 if (err < 0)
1102 return err;
1103 } else if (i == AUTO_SEQ_SURROUND) {
1104 sprintf(name, "%s Playback Volume", chname[i]);
1105 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1106 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT));
1107 if (err < 0)
1108 return err;
1109 sprintf(name, "%s Playback Switch", chname[i]);
1110 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1111 HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT));
1112 if (err < 0)
1113 return err;
1114 } else if (i == AUTO_SEQ_SIDE) {
1115 sprintf(name, "%s Playback Volume", chname[i]);
1116 err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name,
1117 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT));
1118 if (err < 0)
1119 return err;
1120 sprintf(name, "%s Playback Switch", chname[i]);
1121 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name,
1122 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT));
1123 if (err < 0)
1124 return err;
1125 }
1126 }
1127
1128 return 0;
1129}
1130
1131static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
1132{
1133 int err;
1134
1135 if (!pin)
1136 return 0;
1137
1138 if (spec->multiout.num_dacs == 5) /* 10 channels */
1139 spec->multiout.hp_nid = VT1709_HP_DAC_NID;
1140 else if (spec->multiout.num_dacs == 3) /* 6 channels */
1141 spec->multiout.hp_nid = 0;
1142
1143 err = via_add_control(spec, VIA_CTL_WIDGET_VOL,
1144 "Headphone Playback Volume",
1145 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1146 if (err < 0)
1147 return err;
1148 err = via_add_control(spec, VIA_CTL_WIDGET_MUTE,
1149 "Headphone Playback Switch",
1150 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
1151 if (err < 0)
1152 return err;
1153
1154 return 0;
1155}
1156
1157/* create playback/capture controls for input pins */
1158static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec,
1159 const struct auto_pin_cfg *cfg)
1160{
1161 static char *labels[] = {
1162 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL
1163 };
1164 struct hda_input_mux *imux = &spec->private_imux;
1165 int i, err, idx = 0;
1166
1167 /* for internal loopback recording select */
1168 imux->items[imux->num_items].label = "Stereo Mixer";
1169 imux->items[imux->num_items].index = idx;
1170 imux->num_items++;
1171
1172 for (i = 0; i < AUTO_PIN_LAST; i++) {
1173 if (!cfg->input_pins[i])
1174 continue;
1175
1176 switch (cfg->input_pins[i]) {
1177 case 0x1d: /* Mic */
1178 idx = 2;
1179 break;
1180
1181 case 0x1e: /* Line In */
1182 idx = 3;
1183 break;
1184
1185 case 0x21: /* Front Mic */
1186 idx = 4;
1187 break;
1188
1189 case 0x23: /* CD */
1190 idx = 1;
1191 break;
1192 }
1193 err = via_new_analog_input(spec, cfg->input_pins[i], labels[i],
1194 idx, 0x18);
1195 if (err < 0)
1196 return err;
1197 imux->items[imux->num_items].label = labels[i];
1198 imux->items[imux->num_items].index = idx;
1199 imux->num_items++;
1200 }
1201 return 0;
1202}
1203
1204static int vt1709_parse_auto_config(struct hda_codec *codec)
1205{
1206 struct via_spec *spec = codec->spec;
1207 int err;
1208
1209 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL);
1210 if (err < 0)
1211 return err;
1212 err = vt1709_auto_fill_dac_nids(spec, &spec->autocfg);
1213 if (err < 0)
1214 return err;
1215 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
1216 return 0; /* can't find valid BIOS pin config */
1217
1218 err = vt1709_auto_create_multi_out_ctls(spec, &spec->autocfg);
1219 if (err < 0)
1220 return err;
1221 err = vt1709_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
1222 if (err < 0)
1223 return err;
1224 err = vt1709_auto_create_analog_input_ctls(spec, &spec->autocfg);
1225 if (err < 0)
1226 return err;
1227
1228 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
1229
1230 if (spec->autocfg.dig_out_pin)
1231 spec->multiout.dig_out_nid = VT1709_DIGOUT_NID;
1232 if (spec->autocfg.dig_in_pin)
1233 spec->dig_in_nid = VT1709_DIGIN_NID;
1234
1235 if (spec->kctl_alloc)
1236 spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
1237
1238 spec->input_mux = &spec->private_imux;
1239
1240 return 1;
1241}
1242
1243static int patch_vt1709_10ch(struct hda_codec *codec)
1244{
1245 struct via_spec *spec;
1246 int err;
1247
1248 /* create a codec specific record */
1249 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1250 if (spec == NULL)
1251 return -ENOMEM;
1252
1253 codec->spec = spec;
1254
1255 err = vt1709_parse_auto_config(codec);
1256 if (err < 0) {
1257 via_free(codec);
1258 return err;
1259 } else if (!err) {
1260 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
1261 "Using genenic mode...\n");
1262 }
1263
1264 spec->init_verbs = vt1709_10ch_volume_init_verbs;
1265
1266 spec->stream_name_analog = "VT1709 Analog";
1267 spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback;
1268 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1269
1270 spec->stream_name_digital = "VT1709 Digital";
1271 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1272 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1273
1274
1275 if (!spec->adc_nids && spec->input_mux) {
1276 spec->adc_nids = vt1709_adc_nids;
1277 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1278 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1279 spec->num_mixers++;
1280 }
1281
1282 codec->patch_ops = via_patch_ops;
1283
1284 codec->patch_ops.init = via_auto_init;
1285
1286 return 0;
1287}
1288/*
1289 * generic initialization of ADC, input mixers and output mixers
1290 */
1291static struct hda_verb vt1709_6ch_volume_init_verbs[] = {
1292 /*
1293 * Unmute ADC0-2 and set the default input to mic-in
1294 */
1295 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1296 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1297 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1298
1299
1300 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
1301 * mixer widget
1302 */
1303 /* Amp Indices: AOW0=0, CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */
1304 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1305 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
1306 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
1307 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
1308 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
1309
1310 /*
1311 * Set up output selector (0x1a, 0x1b, 0x29)
1312 */
1313 /* set vol=0 to output mixers */
1314 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1315 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1316 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1317
1318 /*
1319 * Unmute PW3 and PW4
1320 */
1321 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1322 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
1323
1324 /* Set input of PW4 as MW0 */
1325 {0x20, AC_VERB_SET_CONNECT_SEL, 0},
1326 /* Set mic as default input of sw0 */
1327 {0x19, AC_VERB_SET_CONNECT_SEL, 0x2},
1328 /* PW9 Output enable */
1329 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
1330 { }
1331};
1332
1333static int patch_vt1709_6ch(struct hda_codec *codec)
1334{
1335 struct via_spec *spec;
1336 int err;
1337
1338 /* create a codec specific record */
1339 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL);
1340 if (spec == NULL)
1341 return -ENOMEM;
1342
1343 codec->spec = spec;
1344
1345 err = vt1709_parse_auto_config(codec);
1346 if (err < 0) {
1347 via_free(codec);
1348 return err;
1349 } else if (!err) {
1350 printk(KERN_INFO "hda_codec: Cannot set up configuration. "
1351 "Using genenic mode...\n");
1352 }
1353
1354 spec->init_verbs = vt1709_6ch_volume_init_verbs;
1355
1356 spec->stream_name_analog = "VT1709 Analog";
1357 spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback;
1358 spec->stream_analog_capture = &vt1709_pcm_analog_capture;
1359
1360 spec->stream_name_digital = "VT1709 Digital";
1361 spec->stream_digital_playback = &vt1709_pcm_digital_playback;
1362 spec->stream_digital_capture = &vt1709_pcm_digital_capture;
1363
1364
1365 if (!spec->adc_nids && spec->input_mux) {
1366 spec->adc_nids = vt1709_adc_nids;
1367 spec->num_adc_nids = ARRAY_SIZE(vt1709_adc_nids);
1368 spec->mixers[spec->num_mixers] = vt1709_capture_mixer;
1369 spec->num_mixers++;
1370 }
1371
1372 codec->patch_ops = via_patch_ops;
1373
1374 codec->patch_ops.init = via_auto_init;
1375
1376 return 0;
1377}
1378
1379/*
1380 * patch entries
1381 */
1382struct hda_codec_preset snd_hda_preset_via[] = {
1383 { .id = 0x11061708, .name = "VIA VT1708", .patch = patch_vt1708},
1384 { .id = 0x11061709, .name = "VIA VT1708", .patch = patch_vt1708},
1385 { .id = 0x1106170A, .name = "VIA VT1708", .patch = patch_vt1708},
1386 { .id = 0x1106170B, .name = "VIA VT1708", .patch = patch_vt1708},
1387 { .id = 0x1106E710, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},
1388 { .id = 0x1106E711, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},
1389 { .id = 0x1106E712, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},
1390 { .id = 0x1106E713, .name = "VIA VT1709 10-Ch", .patch = patch_vt1709_10ch},
1391 { .id = 0x1106E714, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},
1392 { .id = 0x1106E715, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},
1393 { .id = 0x1106E716, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},
1394 { .id = 0x1106E717, .name = "VIA VT1709 6-Ch", .patch = patch_vt1709_6ch},
1395 {} /* terminator */
1396};
diff --git a/sound/pci/ice1712/Makefile b/sound/pci/ice1712/Makefile
index 7837cef8855c..6efdd62f6837 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 8snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o juli.o phase.o wtm.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/amp.c b/sound/pci/ice1712/amp.c
index 59c4078ad331..6e22d326df32 100644
--- a/sound/pci/ice1712/amp.c
+++ b/sound/pci/ice1712/amp.c
@@ -42,7 +42,7 @@ static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val)
42 42
43static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice) 43static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice)
44{ 44{
45 static unsigned short wm_inits[] = { 45 static const unsigned short wm_inits[] = {
46 WM_ATTEN_L, 0x0000, /* 0 db */ 46 WM_ATTEN_L, 0x0000, /* 0 db */
47 WM_ATTEN_R, 0x0000, /* 0 db */ 47 WM_ATTEN_R, 0x0000, /* 0 db */
48 WM_DAC_CTRL, 0x0008, /* 24bit I2S */ 48 WM_DAC_CTRL, 0x0008, /* 24bit I2S */
@@ -75,7 +75,7 @@ static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice)
75 75
76 76
77/* entry point */ 77/* entry point */
78struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = { 78const struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = {
79 { 79 {
80 .subvendor = VT1724_SUBDEVICE_AV710, 80 .subvendor = VT1724_SUBDEVICE_AV710,
81 .name = "Chaintech AV-710", 81 .name = "Chaintech AV-710",
diff --git a/sound/pci/ice1712/amp.h b/sound/pci/ice1712/amp.h
index a0fc89b48122..7b667bad0c6b 100644
--- a/sound/pci/ice1712/amp.h
+++ b/sound/pci/ice1712/amp.h
@@ -42,7 +42,7 @@
42#define WM_DAC_CTRL 0x02 42#define WM_DAC_CTRL 0x02
43#define WM_INT_CTRL 0x03 43#define WM_INT_CTRL 0x03
44 44
45extern struct snd_ice1712_card_info snd_vt1724_amp_cards[]; 45extern const struct snd_ice1712_card_info snd_vt1724_amp_cards[];
46 46
47 47
48#endif /* __SOUND_AMP_H */ 48#endif /* __SOUND_AMP_H */
diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c
index 9e76cebd2d22..6941d85dfec9 100644
--- a/sound/pci/ice1712/aureon.c
+++ b/sound/pci/ice1712/aureon.c
@@ -294,7 +294,7 @@ static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short r
294static int aureon_ac97_init (struct snd_ice1712 *ice) 294static int aureon_ac97_init (struct snd_ice1712 *ice)
295{ 295{
296 int i; 296 int i;
297 static unsigned short ac97_defaults[] = { 297 static const unsigned short ac97_defaults[] = {
298 0x00, 0x9640, 298 0x00, 0x9640,
299 0x02, 0x8000, 299 0x02, 0x8000,
300 0x04, 0x8000, 300 0x04, 0x8000,
@@ -474,7 +474,8 @@ static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned
474 474
475 tmp = snd_ice1712_gpio_read(ice); 475 tmp = snd_ice1712_gpio_read(ice);
476 476
477 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT) { 477 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
478 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) {
478 snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS)); 479 snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS));
479 mosi = PRODIGY_SPI_MOSI; 480 mosi = PRODIGY_SPI_MOSI;
480 clk = PRODIGY_SPI_CLK; 481 clk = PRODIGY_SPI_CLK;
@@ -601,7 +602,9 @@ static unsigned short wm_get(struct snd_ice1712 *ice, int reg)
601static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val) 602static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val)
602{ 603{
603 aureon_spi_write(ice, 604 aureon_spi_write(ice,
604 (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ? PRODIGY_WM_CS : AUREON_WM_CS), 605 ((ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
606 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) ?
607 PRODIGY_WM_CS : AUREON_WM_CS),
605 (reg << 9) | (val & 0x1ff), 16); 608 (reg << 9) | (val & 0x1ff), 16);
606} 609}
607 610
@@ -661,17 +664,17 @@ static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
661 return change; 664 return change;
662} 665}
663 666
664static DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); 667static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
665static DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); 668static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
666static DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0); 669static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0);
667static DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0); 670static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0);
668static DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0); 671static const DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0);
669 672
670/* 673/*
671 * Logarithmic volume values for WM8770 674 * Logarithmic volume values for WM8770
672 * Computed as 20 * Log10(255 / x) 675 * Computed as 20 * Log10(255 / x)
673 */ 676 */
674static unsigned char wm_vol[256] = { 677static const unsigned char wm_vol[256] = {
675 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23, 678 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
676 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, 679 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
677 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, 680 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
@@ -1064,14 +1067,14 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
1064 */ 1067 */
1065static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1068static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1066{ 1069{
1067 static char *texts[] = { 1070 static const char * const texts[] = {
1068 "CD", //AIN1 1071 "CD", //AIN1
1069 "Aux", //AIN2 1072 "Aux", //AIN2
1070 "Line", //AIN3 1073 "Line", //AIN3
1071 "Mic", //AIN4 1074 "Mic", //AIN4
1072 "AC97" //AIN5 1075 "AC97" //AIN5
1073 }; 1076 };
1074 static char *universe_texts[] = { 1077 static const char * const universe_texts[] = {
1075 "Aux1", //AIN1 1078 "Aux1", //AIN1
1076 "CD", //AIN2 1079 "CD", //AIN2
1077 "Phono", //AIN3 1080 "Phono", //AIN3
@@ -1137,11 +1140,11 @@ static int wm_adc_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val
1137static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1140static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1138{ 1141{
1139 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1142 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1140 static char *aureon_texts[] = { 1143 static const char * const aureon_texts[] = {
1141 "CD", //RXP0 1144 "CD", //RXP0
1142 "Optical" //RXP1 1145 "Optical" //RXP1
1143 }; 1146 };
1144 static char *prodigy_texts[] = { 1147 static const char * const prodigy_texts[] = {
1145 "CD", 1148 "CD",
1146 "Coax" 1149 "Coax"
1147 }; 1150 };
@@ -1288,12 +1291,14 @@ static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable)
1288 1291
1289 tmp2 = tmp = snd_ice1712_gpio_read(ice); 1292 tmp2 = tmp = snd_ice1712_gpio_read(ice);
1290 if (enable) 1293 if (enable)
1291 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) 1294 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1295 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1292 tmp |= AUREON_HP_SEL; 1296 tmp |= AUREON_HP_SEL;
1293 else 1297 else
1294 tmp |= PRODIGY_HP_SEL; 1298 tmp |= PRODIGY_HP_SEL;
1295 else 1299 else
1296 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) 1300 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1301 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT)
1297 tmp &= ~ AUREON_HP_SEL; 1302 tmp &= ~ AUREON_HP_SEL;
1298 else 1303 else
1299 tmp &= ~ PRODIGY_HP_SEL; 1304 tmp &= ~ PRODIGY_HP_SEL;
@@ -1363,7 +1368,7 @@ static int aureon_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v
1363 */ 1368 */
1364static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo) 1369static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo)
1365{ 1370{
1366 static char *texts[2] = { "128x", "64x" }; 1371 static const char * const texts[2] = { "128x", "64x" };
1367 1372
1368 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1373 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1369 uinfo->count = 1; 1374 uinfo->count = 1;
@@ -1406,7 +1411,7 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl
1406 * mixers 1411 * mixers
1407 */ 1412 */
1408 1413
1409static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { 1414static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1410 { 1415 {
1411 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1416 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1412 .name = "Master Playback Switch", 1417 .name = "Master Playback Switch",
@@ -1521,7 +1526,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = {
1521 } 1526 }
1522}; 1527};
1523 1528
1524static struct snd_kcontrol_new wm_controls[] __devinitdata = { 1529static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
1525 { 1530 {
1526 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1531 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1527 .name = "PCM Playback Switch", 1532 .name = "PCM Playback Switch",
@@ -1587,7 +1592,7 @@ static struct snd_kcontrol_new wm_controls[] __devinitdata = {
1587 } 1592 }
1588}; 1593};
1589 1594
1590static struct snd_kcontrol_new ac97_controls[] __devinitdata = { 1595static const struct snd_kcontrol_new ac97_controls[] __devinitdata = {
1591 { 1596 {
1592 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1597 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1593 .name = "AC97 Playback Switch", 1598 .name = "AC97 Playback Switch",
@@ -1692,7 +1697,7 @@ static struct snd_kcontrol_new ac97_controls[] __devinitdata = {
1692 } 1697 }
1693}; 1698};
1694 1699
1695static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { 1700static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
1696 { 1701 {
1697 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1702 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1698 .name = "AC97 Playback Switch", 1703 .name = "AC97 Playback Switch",
@@ -1824,8 +1829,7 @@ static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = {
1824 1829
1825}; 1830};
1826 1831
1827 1832static const struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
1828static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
1829 { 1833 {
1830 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1834 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1831 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 1835 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
@@ -1870,7 +1874,6 @@ static struct snd_kcontrol_new cs8415_controls[] __devinitdata = {
1870 } 1874 }
1871}; 1875};
1872 1876
1873
1874static int __devinit aureon_add_controls(struct snd_ice1712 *ice) 1877static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1875{ 1878{
1876 unsigned int i, counts; 1879 unsigned int i, counts;
@@ -1898,7 +1901,8 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1898 return err; 1901 return err;
1899 } 1902 }
1900 } 1903 }
1901 else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) { 1904 else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1905 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1902 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) { 1906 for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) {
1903 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice)); 1907 err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice));
1904 if (err < 0) 1908 if (err < 0)
@@ -1906,7 +1910,8 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1906 } 1910 }
1907 } 1911 }
1908 1912
1909 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) { 1913 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
1914 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
1910 unsigned char id; 1915 unsigned char id;
1911 snd_ice1712_save_gpio_status(ice); 1916 snd_ice1712_save_gpio_status(ice);
1912 id = aureon_cs8415_get(ice, CS8415_ID); 1917 id = aureon_cs8415_get(ice, CS8415_ID);
@@ -1936,7 +1941,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice)
1936 */ 1941 */
1937static int __devinit aureon_init(struct snd_ice1712 *ice) 1942static int __devinit aureon_init(struct snd_ice1712 *ice)
1938{ 1943{
1939 static unsigned short wm_inits_aureon[] = { 1944 static const unsigned short wm_inits_aureon[] = {
1940 /* These come first to reduce init pop noise */ 1945 /* These come first to reduce init pop noise */
1941 0x1b, 0x044, /* ADC Mux (AC'97 source) */ 1946 0x1b, 0x044, /* ADC Mux (AC'97 source) */
1942 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */ 1947 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
@@ -1972,7 +1977,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
1972 0x1a, 0x000, /* -12dB ADC/R */ 1977 0x1a, 0x000, /* -12dB ADC/R */
1973 (unsigned short)-1 1978 (unsigned short)-1
1974 }; 1979 };
1975 static unsigned short wm_inits_prodigy[] = { 1980 static const unsigned short wm_inits_prodigy[] = {
1976 1981
1977 /* These come first to reduce init pop noise */ 1982 /* These come first to reduce init pop noise */
1978 0x1b, 0x000, /* ADC Mux */ 1983 0x1b, 0x000, /* ADC Mux */
@@ -2014,7 +2019,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2014 (unsigned short)-1 2019 (unsigned short)-1
2015 2020
2016 }; 2021 };
2017 static unsigned short cs_inits[] = { 2022 static const unsigned short cs_inits[] = {
2018 0x0441, /* RUN */ 2023 0x0441, /* RUN */
2019 0x0180, /* no mute, OMCK output on RMCK pin */ 2024 0x0180, /* no mute, OMCK output on RMCK pin */
2020 0x0201, /* S/PDIF source on RXP1 */ 2025 0x0201, /* S/PDIF source on RXP1 */
@@ -2022,7 +2027,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2022 (unsigned short)-1 2027 (unsigned short)-1
2023 }; 2028 };
2024 unsigned int tmp; 2029 unsigned int tmp;
2025 unsigned short *p; 2030 const unsigned short *p;
2026 int err, i; 2031 int err, i;
2027 2032
2028 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) { 2033 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON51_SKY) {
@@ -2062,7 +2067,8 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2062 2067
2063 /* initialize WM8770 codec */ 2068 /* initialize WM8770 codec */
2064 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 || 2069 if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 ||
2065 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT) 2070 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT ||
2071 ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT)
2066 p = wm_inits_prodigy; 2072 p = wm_inits_prodigy;
2067 else 2073 else
2068 p = wm_inits_aureon; 2074 p = wm_inits_aureon;
@@ -2070,7 +2076,8 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2070 wm_put(ice, p[0], p[1]); 2076 wm_put(ice, p[0], p[1]);
2071 2077
2072 /* initialize CS8415A codec */ 2078 /* initialize CS8415A codec */
2073 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT) { 2079 if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT &&
2080 ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) {
2074 for (p = cs_inits; *p != (unsigned short)-1; p++) 2081 for (p = cs_inits; *p != (unsigned short)-1; p++)
2075 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24); 2082 aureon_spi_write(ice, AUREON_CS8415_CS, *p | 0x200000, 24);
2076 ice->spec.aureon.cs8415_mux = 1; 2083 ice->spec.aureon.cs8415_mux = 1;
@@ -2100,73 +2107,58 @@ static int __devinit aureon_init(struct snd_ice1712 *ice)
2100 * hence the driver needs to sets up it properly. 2107 * hence the driver needs to sets up it properly.
2101 */ 2108 */
2102 2109
2103static unsigned char aureon51_eeprom[] __devinitdata = { 2110static const unsigned char aureon51_eeprom[] __devinitdata = {
2104 0x0a, /* SYSCONF: clock 512, spdif-in/ADC, 3DACs */ 2111 [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */
2105 0x80, /* ACLINK: I2S */ 2112 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2106 0xfc, /* I2S: vol, 96k, 24bit, 192k */ 2113 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2107 0xc3, /* SPDIF: out-en, out-int, spdif-in */ 2114 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2108 0xff, /* GPIO_DIR */ 2115 [ICE_EEP2_GPIO_DIR] = 0xff,
2109 0xff, /* GPIO_DIR1 */ 2116 [ICE_EEP2_GPIO_DIR1] = 0xff,
2110 0x5f, /* GPIO_DIR2 */ 2117 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2111 0x00, /* GPIO_MASK */ 2118 [ICE_EEP2_GPIO_MASK] = 0x00,
2112 0x00, /* GPIO_MASK1 */ 2119 [ICE_EEP2_GPIO_MASK1] = 0x00,
2113 0x00, /* GPIO_MASK2 */ 2120 [ICE_EEP2_GPIO_MASK2] = 0x00,
2114 0x00, /* GPIO_STATE */ 2121 [ICE_EEP2_GPIO_STATE] = 0x00,
2115 0x00, /* GPIO_STATE1 */ 2122 [ICE_EEP2_GPIO_STATE1] = 0x00,
2116 0x00, /* GPIO_STATE2 */ 2123 [ICE_EEP2_GPIO_STATE2] = 0x00,
2117}; 2124};
2118 2125
2119static unsigned char aureon71_eeprom[] __devinitdata = { 2126static const unsigned char aureon71_eeprom[] __devinitdata = {
2120 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */ 2127 [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
2121 0x80, /* ACLINK: I2S */ 2128 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2122 0xfc, /* I2S: vol, 96k, 24bit, 192k */ 2129 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2123 0xc3, /* SPDIF: out-en, out-int, spdif-in */ 2130 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2124 0xff, /* GPIO_DIR */ 2131 [ICE_EEP2_GPIO_DIR] = 0xff,
2125 0xff, /* GPIO_DIR1 */ 2132 [ICE_EEP2_GPIO_DIR1] = 0xff,
2126 0x5f, /* GPIO_DIR2 */ 2133 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2127 0x00, /* GPIO_MASK */ 2134 [ICE_EEP2_GPIO_MASK] = 0x00,
2128 0x00, /* GPIO_MASK1 */ 2135 [ICE_EEP2_GPIO_MASK1] = 0x00,
2129 0x00, /* GPIO_MASK2 */ 2136 [ICE_EEP2_GPIO_MASK2] = 0x00,
2130 0x00, /* GPIO_STATE */ 2137 [ICE_EEP2_GPIO_STATE] = 0x00,
2131 0x00, /* GPIO_STATE1 */ 2138 [ICE_EEP2_GPIO_STATE1] = 0x00,
2132 0x00, /* GPIO_STATE2 */ 2139 [ICE_EEP2_GPIO_STATE2] = 0x00,
2133}; 2140};
2134 2141#define prodigy71_eeprom aureon71_eeprom
2135static unsigned char prodigy71_eeprom[] __devinitdata = { 2142
2136 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */ 2143static const unsigned char prodigy71lt_eeprom[] __devinitdata = {
2137 0x80, /* ACLINK: I2S */ 2144 [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */
2138 0xfc, /* I2S: vol, 96k, 24bit, 192k */ 2145 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
2139 0xc3, /* SPDIF: out-en, out-int, spdif-in */ 2146 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
2140 0xff, /* GPIO_DIR */ 2147 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
2141 0xff, /* GPIO_DIR1 */ 2148 [ICE_EEP2_GPIO_DIR] = 0xff,
2142 0x5f, /* GPIO_DIR2 */ 2149 [ICE_EEP2_GPIO_DIR1] = 0xff,
2143 0x00, /* GPIO_MASK */ 2150 [ICE_EEP2_GPIO_DIR2] = 0x5f,
2144 0x00, /* GPIO_MASK1 */ 2151 [ICE_EEP2_GPIO_MASK] = 0x00,
2145 0x00, /* GPIO_MASK2 */ 2152 [ICE_EEP2_GPIO_MASK1] = 0x00,
2146 0x00, /* GPIO_STATE */ 2153 [ICE_EEP2_GPIO_MASK2] = 0x00,
2147 0x00, /* GPIO_STATE1 */ 2154 [ICE_EEP2_GPIO_STATE] = 0x00,
2148 0x00, /* GPIO_STATE2 */ 2155 [ICE_EEP2_GPIO_STATE1] = 0x00,
2156 [ICE_EEP2_GPIO_STATE2] = 0x00,
2149}; 2157};
2150 2158#define prodigy71xt_eeprom prodigy71lt_eeprom
2151static unsigned char prodigy71lt_eeprom[] __devinitdata = {
2152 0x4b, /* SYSCINF: clock 512, spdif-in/ADC, 4DACs */
2153 0x80, /* ACLINK: I2S */
2154 0xfc, /* I2S: vol, 96k, 24bit, 192k */
2155 0xc3, /* SPDIF: out-en, out-int, spdif-in */
2156 0xff, /* GPIO_DIR */
2157 0xff, /* GPIO_DIR1 */
2158 0x5f, /* GPIO_DIR2 */
2159 0x00, /* GPIO_MASK */
2160 0x00, /* GPIO_MASK1 */
2161 0x00, /* GPIO_MASK2 */
2162 0x00, /* GPIO_STATE */
2163 0x00, /* GPIO_STATE1 */
2164 0x00, /* GPIO_STATE2 */
2165};
2166
2167 2159
2168/* entry point */ 2160/* entry point */
2169struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { 2161const struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
2170 { 2162 {
2171 .subvendor = VT1724_SUBDEVICE_AUREON51_SKY, 2163 .subvendor = VT1724_SUBDEVICE_AUREON51_SKY,
2172 .name = "Terratec Aureon 5.1-Sky", 2164 .name = "Terratec Aureon 5.1-Sky",
@@ -2217,5 +2209,15 @@ struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = {
2217 .eeprom_data = prodigy71lt_eeprom, 2209 .eeprom_data = prodigy71lt_eeprom,
2218 .driver = "Prodigy71LT", 2210 .driver = "Prodigy71LT",
2219 }, 2211 },
2212 {
2213 .subvendor = VT1724_SUBDEVICE_PRODIGY71XT,
2214 .name = "Audiotrak Prodigy 7.1 XT",
2215 .model = "prodigy71xt",
2216 .chip_init = aureon_init,
2217 .build_controls = aureon_add_controls,
2218 .eeprom_size = sizeof(prodigy71xt_eeprom),
2219 .eeprom_data = prodigy71xt_eeprom,
2220 .driver = "Prodigy71LT",
2221 },
2220 { } /* terminator */ 2222 { } /* terminator */
2221}; 2223};
diff --git a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h
index 3b7bea656c57..79e58e88ed47 100644
--- a/sound/pci/ice1712/aureon.h
+++ b/sound/pci/ice1712/aureon.h
@@ -28,15 +28,17 @@
28 "{Terratec,Aureon 7.1 Space},"\ 28 "{Terratec,Aureon 7.1 Space},"\
29 "{Terratec,Aureon 7.1 Universe}," \ 29 "{Terratec,Aureon 7.1 Universe}," \
30 "{AudioTrak,Prodigy 7.1}," \ 30 "{AudioTrak,Prodigy 7.1}," \
31 "{AudioTrak,Prodigy 7.1 LT}," 31 "{AudioTrak,Prodigy 7.1 LT},"\
32 "{AudioTrak,Prodigy 7.1 XT},"
32 33
33#define VT1724_SUBDEVICE_AUREON51_SKY 0x3b154711 /* Aureon 5.1 Sky */ 34#define VT1724_SUBDEVICE_AUREON51_SKY 0x3b154711 /* Aureon 5.1 Sky */
34#define VT1724_SUBDEVICE_AUREON71_SPACE 0x3b154511 /* Aureon 7.1 Space */ 35#define VT1724_SUBDEVICE_AUREON71_SPACE 0x3b154511 /* Aureon 7.1 Space */
35#define VT1724_SUBDEVICE_AUREON71_UNIVERSE 0x3b155311 /* Aureon 7.1 Universe */ 36#define VT1724_SUBDEVICE_AUREON71_UNIVERSE 0x3b155311 /* Aureon 7.1 Universe */
36#define VT1724_SUBDEVICE_PRODIGY71 0x33495345 /* PRODIGY 7.1 */ 37#define VT1724_SUBDEVICE_PRODIGY71 0x33495345 /* PRODIGY 7.1 */
37#define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */ 38#define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */
39#define VT1724_SUBDEVICE_PRODIGY71XT 0x36315441 /* PRODIGY 7.1 XT*/
38 40
39extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; 41extern const struct snd_ice1712_card_info snd_vt1724_aureon_cards[];
40 42
41/* GPIO bits */ 43/* GPIO bits */
42#define AUREON_CS8415_CS (1 << 22) 44#define AUREON_CS8415_CS (1 << 22)
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index af659800c9b0..3eeb36c6e985 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -416,7 +416,7 @@ static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kco
416 return 0; 416 return 0;
417} 417}
418 418
419static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = 419static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata =
420{ 420{
421 .access = (SNDRV_CTL_ELEM_ACCESS_READ), 421 .access = (SNDRV_CTL_ELEM_ACCESS_READ),
422 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 422 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -429,7 +429,7 @@ static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devini
429 * initialize the chips on M-Audio cards 429 * initialize the chips on M-Audio cards
430 */ 430 */
431 431
432static struct snd_akm4xxx akm_audiophile __devinitdata = { 432static const struct snd_akm4xxx akm_audiophile __devinitdata = {
433 .type = SND_AK4528, 433 .type = SND_AK4528,
434 .num_adcs = 2, 434 .num_adcs = 2,
435 .num_dacs = 2, 435 .num_dacs = 2,
@@ -438,7 +438,7 @@ static struct snd_akm4xxx akm_audiophile __devinitdata = {
438 } 438 }
439}; 439};
440 440
441static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { 441static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
442 .caddr = 2, 442 .caddr = 2,
443 .cif = 0, 443 .cif = 0,
444 .data_mask = ICE1712_DELTA_AP_DOUT, 444 .data_mask = ICE1712_DELTA_AP_DOUT,
@@ -450,7 +450,7 @@ static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = {
450 .mask_flags = 0, 450 .mask_flags = 0,
451}; 451};
452 452
453static struct snd_akm4xxx akm_delta410 __devinitdata = { 453static const struct snd_akm4xxx akm_delta410 __devinitdata = {
454 .type = SND_AK4529, 454 .type = SND_AK4529,
455 .num_adcs = 2, 455 .num_adcs = 2,
456 .num_dacs = 8, 456 .num_dacs = 8,
@@ -459,7 +459,7 @@ static struct snd_akm4xxx akm_delta410 __devinitdata = {
459 } 459 }
460}; 460};
461 461
462static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { 462static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
463 .caddr = 0, 463 .caddr = 0,
464 .cif = 0, 464 .cif = 0,
465 .data_mask = ICE1712_DELTA_AP_DOUT, 465 .data_mask = ICE1712_DELTA_AP_DOUT,
@@ -471,7 +471,7 @@ static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = {
471 .mask_flags = 0, 471 .mask_flags = 0,
472}; 472};
473 473
474static struct snd_akm4xxx akm_delta1010lt __devinitdata = { 474static const struct snd_akm4xxx akm_delta1010lt __devinitdata = {
475 .type = SND_AK4524, 475 .type = SND_AK4524,
476 .num_adcs = 8, 476 .num_adcs = 8,
477 .num_dacs = 8, 477 .num_dacs = 8,
@@ -481,7 +481,7 @@ static struct snd_akm4xxx akm_delta1010lt __devinitdata = {
481 } 481 }
482}; 482};
483 483
484static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { 484static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
485 .caddr = 2, 485 .caddr = 2,
486 .cif = 0, /* the default level of the CIF pin from AK4524 */ 486 .cif = 0, /* the default level of the CIF pin from AK4524 */
487 .data_mask = ICE1712_DELTA_1010LT_DOUT, 487 .data_mask = ICE1712_DELTA_1010LT_DOUT,
@@ -493,7 +493,7 @@ static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
493 .mask_flags = 0, 493 .mask_flags = 0,
494}; 494};
495 495
496static struct snd_akm4xxx akm_delta44 __devinitdata = { 496static const struct snd_akm4xxx akm_delta44 __devinitdata = {
497 .type = SND_AK4524, 497 .type = SND_AK4524,
498 .num_adcs = 4, 498 .num_adcs = 4,
499 .num_dacs = 4, 499 .num_dacs = 4,
@@ -503,7 +503,7 @@ static struct snd_akm4xxx akm_delta44 __devinitdata = {
503 } 503 }
504}; 504};
505 505
506static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { 506static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
507 .caddr = 2, 507 .caddr = 2,
508 .cif = 0, /* the default level of the CIF pin from AK4524 */ 508 .cif = 0, /* the default level of the CIF pin from AK4524 */
509 .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA, 509 .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA,
@@ -515,7 +515,7 @@ static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = {
515 .mask_flags = 0, 515 .mask_flags = 0,
516}; 516};
517 517
518static struct snd_akm4xxx akm_vx442 __devinitdata = { 518static const struct snd_akm4xxx akm_vx442 __devinitdata = {
519 .type = SND_AK4524, 519 .type = SND_AK4524,
520 .num_adcs = 4, 520 .num_adcs = 4,
521 .num_dacs = 4, 521 .num_dacs = 4,
@@ -525,7 +525,7 @@ static struct snd_akm4xxx akm_vx442 __devinitdata = {
525 } 525 }
526}; 526};
527 527
528static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = { 528static const struct snd_ak4xxx_private akm_vx442_priv __devinitdata = {
529 .caddr = 2, 529 .caddr = 2,
530 .cif = 0, 530 .cif = 0,
531 .data_mask = ICE1712_VX442_DOUT, 531 .data_mask = ICE1712_VX442_DOUT,
@@ -650,15 +650,15 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
650 * additional controls for M-Audio cards 650 * additional controls for M-Audio cards
651 */ 651 */
652 652
653static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = 653static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata =
654ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); 654ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0);
655static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = 655static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata =
656ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0); 656ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0);
657static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = 657static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata =
658ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); 658ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
659static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = 659static const struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata =
660ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); 660ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0);
661static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata = 661static const struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata =
662ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); 662ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE);
663 663
664 664
@@ -735,7 +735,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice)
735 735
736 736
737/* entry point */ 737/* entry point */
738struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = { 738const struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = {
739 { 739 {
740 .subvendor = ICE1712_SUBDEVICE_DELTA1010, 740 .subvendor = ICE1712_SUBDEVICE_DELTA1010,
741 .name = "M Audio Delta 1010", 741 .name = "M Audio Delta 1010",
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
index 746ebde94522..e65d669af639 100644
--- a/sound/pci/ice1712/delta.h
+++ b/sound/pci/ice1712/delta.h
@@ -46,7 +46,7 @@
46#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100 46#define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100
47 47
48/* entry point */ 48/* entry point */
49extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; 49extern const struct snd_ice1712_card_info snd_ice1712_delta_cards[];
50 50
51 51
52/* 52/*
diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c
index b135389fec6c..9b7ff302c072 100644
--- a/sound/pci/ice1712/ews.c
+++ b/sound/pci/ice1712/ews.c
@@ -332,7 +332,7 @@ static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate)
332 332
333/* 333/*
334 */ 334 */
335static struct snd_akm4xxx akm_ews88mt __devinitdata = { 335static const struct snd_akm4xxx akm_ews88mt __devinitdata = {
336 .num_adcs = 8, 336 .num_adcs = 8,
337 .num_dacs = 8, 337 .num_dacs = 8,
338 .type = SND_AK4524, 338 .type = SND_AK4524,
@@ -342,7 +342,7 @@ static struct snd_akm4xxx akm_ews88mt __devinitdata = {
342 } 342 }
343}; 343};
344 344
345static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { 345static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
346 .caddr = 2, 346 .caddr = 2,
347 .cif = 1, /* CIF high */ 347 .cif = 1, /* CIF high */
348 .data_mask = ICE1712_EWS88_SERIAL_DATA, 348 .data_mask = ICE1712_EWS88_SERIAL_DATA,
@@ -354,7 +354,7 @@ static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = {
354 .mask_flags = 0, 354 .mask_flags = 0,
355}; 355};
356 356
357static struct snd_akm4xxx akm_ewx2496 __devinitdata = { 357static const struct snd_akm4xxx akm_ewx2496 __devinitdata = {
358 .num_adcs = 2, 358 .num_adcs = 2,
359 .num_dacs = 2, 359 .num_dacs = 2,
360 .type = SND_AK4524, 360 .type = SND_AK4524,
@@ -363,7 +363,7 @@ static struct snd_akm4xxx akm_ewx2496 __devinitdata = {
363 } 363 }
364}; 364};
365 365
366static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { 366static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
367 .caddr = 2, 367 .caddr = 2,
368 .cif = 1, /* CIF high */ 368 .cif = 1, /* CIF high */
369 .data_mask = ICE1712_EWS88_SERIAL_DATA, 369 .data_mask = ICE1712_EWS88_SERIAL_DATA,
@@ -375,7 +375,7 @@ static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = {
375 .mask_flags = 0, 375 .mask_flags = 0,
376}; 376};
377 377
378static struct snd_akm4xxx akm_6fire __devinitdata = { 378static const struct snd_akm4xxx akm_6fire __devinitdata = {
379 .num_adcs = 6, 379 .num_adcs = 6,
380 .num_dacs = 6, 380 .num_dacs = 6,
381 .type = SND_AK4524, 381 .type = SND_AK4524,
@@ -384,7 +384,7 @@ static struct snd_akm4xxx akm_6fire __devinitdata = {
384 } 384 }
385}; 385};
386 386
387static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = { 387static const struct snd_ak4xxx_private akm_6fire_priv __devinitdata = {
388 .caddr = 2, 388 .caddr = 2,
389 .cif = 1, /* CIF high */ 389 .cif = 1, /* CIF high */
390 .data_mask = ICE1712_6FIRE_SERIAL_DATA, 390 .data_mask = ICE1712_6FIRE_SERIAL_DATA,
@@ -578,7 +578,7 @@ static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct sn
578 return val != nval; 578 return val != nval;
579} 579}
580 580
581static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = { 581static const struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = {
582 { 582 {
583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 583 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
584 .name = "Input Sensitivity Switch", 584 .name = "Input Sensitivity Switch",
@@ -678,7 +678,7 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st
678 return ndata != data; 678 return ndata != data;
679} 679}
680 680
681static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = { 681static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
682 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 682 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
683 .name = "Input Sensitivity Switch", 683 .name = "Input Sensitivity Switch",
684 .info = snd_ice1712_ewx_io_sense_info, 684 .info = snd_ice1712_ewx_io_sense_info,
@@ -687,7 +687,7 @@ static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = {
687 .count = 8, 687 .count = 8,
688}; 688};
689 689
690static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = { 690static const struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = {
691 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 691 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
692 .name = "Output Sensitivity Switch", 692 .name = "Output Sensitivity Switch",
693 .info = snd_ice1712_ewx_io_sense_info, 693 .info = snd_ice1712_ewx_io_sense_info,
@@ -769,7 +769,7 @@ static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct
769 .private_value = xshift | (xinvert << 8),\ 769 .private_value = xshift | (xinvert << 8),\
770} 770}
771 771
772static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { 772static const struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = {
773 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */ 773 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */
774 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0), 774 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0),
775 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0), 775 EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0),
@@ -909,7 +909,7 @@ static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, str
909 .private_value = xshift | (xinvert << 8),\ 909 .private_value = xshift | (xinvert << 8),\
910} 910}
911 911
912static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = { 912static const struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = {
913 { 913 {
914 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 914 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
915 .name = "Analog Input Select", 915 .name = "Analog Input Select",
@@ -989,7 +989,7 @@ static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice)
989 989
990 990
991/* entry point */ 991/* entry point */
992struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = { 992const struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = {
993 { 993 {
994 .subvendor = ICE1712_SUBDEVICE_EWX2496, 994 .subvendor = ICE1712_SUBDEVICE_EWX2496,
995 .name = "TerraTec EWX24/96", 995 .name = "TerraTec EWX24/96",
diff --git a/sound/pci/ice1712/ews.h b/sound/pci/ice1712/ews.h
index a12a0b053558..df449b4741f6 100644
--- a/sound/pci/ice1712/ews.h
+++ b/sound/pci/ice1712/ews.h
@@ -40,7 +40,7 @@
40#define ICE1712_SUBDEVICE_PHASE88 0x3b155111 40#define ICE1712_SUBDEVICE_PHASE88 0x3b155111
41 41
42/* entry point */ 42/* entry point */
43extern struct snd_ice1712_card_info snd_ice1712_ews_cards[]; 43extern const struct snd_ice1712_card_info snd_ice1712_ews_cards[];
44 44
45 45
46/* TerraTec EWX 24/96 configuration definitions */ 46/* TerraTec EWX 24/96 configuration definitions */
diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c
index 3f27d04e7d3c..df97313aaf83 100644
--- a/sound/pci/ice1712/hoontech.c
+++ b/sound/pci/ice1712/hoontech.c
@@ -239,7 +239,7 @@ static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip)
239static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice) 239static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
240{ 240{
241 /* Hoontech STDSP24 with modified hardware */ 241 /* Hoontech STDSP24 with modified hardware */
242 static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = { 242 static const struct snd_akm4xxx akm_stdsp24_mv __devinitdata = {
243 .num_adcs = 2, 243 .num_adcs = 2,
244 .num_dacs = 2, 244 .num_dacs = 2,
245 .type = SND_AK4524, 245 .type = SND_AK4524,
@@ -248,7 +248,7 @@ static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice)
248 } 248 }
249 }; 249 };
250 250
251 static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = { 251 static const struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = {
252 .caddr = 2, 252 .caddr = 2,
253 .cif = 1, /* CIF high */ 253 .cif = 1, /* CIF high */
254 .data_mask = ICE1712_STDSP24_SERIAL_DATA, 254 .data_mask = ICE1712_STDSP24_SERIAL_DATA,
@@ -298,7 +298,7 @@ static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice)
298 298
299 299
300/* entry point */ 300/* entry point */
301struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = { 301const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
302 { 302 {
303 .subvendor = ICE1712_SUBDEVICE_STDSP24, 303 .subvendor = ICE1712_SUBDEVICE_STDSP24,
304 .name = "Hoontech SoundTrack Audio DSP24", 304 .name = "Hoontech SoundTrack Audio DSP24",
@@ -325,4 +325,3 @@ struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = {
325 }, 325 },
326 { } /* terminator */ 326 { } /* terminator */
327}; 327};
328
diff --git a/sound/pci/ice1712/hoontech.h b/sound/pci/ice1712/hoontech.h
index 1ee538b20fbf..b62d6e4f6c71 100644
--- a/sound/pci/ice1712/hoontech.h
+++ b/sound/pci/ice1712/hoontech.h
@@ -35,7 +35,7 @@
35#define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */ 35#define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */
36#define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */ 36#define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */
37 37
38extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[]; 38extern const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[];
39 39
40 40
41/* Hoontech SoundTrack Audio DSP 24 GPIO definitions */ 41/* Hoontech SoundTrack Audio DSP 24 GPIO definitions */
diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c
index 8ba31cfb9045..830a1bbd7110 100644
--- a/sound/pci/ice1712/ice1712.c
+++ b/sound/pci/ice1712/ice1712.c
@@ -107,7 +107,7 @@ module_param_array(dxr_enable, int, NULL, 0444);
107MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); 107MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE.");
108 108
109 109
110static struct pci_device_id snd_ice1712_ids[] = { 110static const struct pci_device_id snd_ice1712_ids[] = {
111 { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICE1712 */ 111 { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_ICE_1712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* ICE1712 */
112 { 0, } 112 { 0, }
113}; 113};
@@ -287,7 +287,7 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru
287 return val != nval; 287 return val != nval;
288} 288}
289 289
290static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = { 290static const struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = {
291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 291 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
292 .name = "Digital Mixer To AC97", 292 .name = "Digital Mixer To AC97",
293 .info = snd_ice1712_digmix_route_ac97_info, 293 .info = snd_ice1712_digmix_route_ac97_info,
@@ -719,7 +719,7 @@ static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *s
719 return bytes_to_frames(substream->runtime, ptr); 719 return bytes_to_frames(substream->runtime, ptr);
720} 720}
721 721
722static struct snd_pcm_hardware snd_ice1712_playback = 722static const struct snd_pcm_hardware snd_ice1712_playback =
723{ 723{
724 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 724 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
725 SNDRV_PCM_INFO_BLOCK_TRANSFER | 725 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -739,7 +739,7 @@ static struct snd_pcm_hardware snd_ice1712_playback =
739 .fifo_size = 0, 739 .fifo_size = 0,
740}; 740};
741 741
742static struct snd_pcm_hardware snd_ice1712_playback_ds = 742static const struct snd_pcm_hardware snd_ice1712_playback_ds =
743{ 743{
744 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 744 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
745 SNDRV_PCM_INFO_BLOCK_TRANSFER | 745 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -759,7 +759,7 @@ static struct snd_pcm_hardware snd_ice1712_playback_ds =
759 .fifo_size = 0, 759 .fifo_size = 0,
760}; 760};
761 761
762static struct snd_pcm_hardware snd_ice1712_capture = 762static const struct snd_pcm_hardware snd_ice1712_capture =
763{ 763{
764 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 764 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
765 SNDRV_PCM_INFO_BLOCK_TRANSFER | 765 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1133,7 +1133,7 @@ static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substrea
1133 return bytes_to_frames(substream->runtime, ptr); 1133 return bytes_to_frames(substream->runtime, ptr);
1134} 1134}
1135 1135
1136static struct snd_pcm_hardware snd_ice1712_playback_pro = 1136static const struct snd_pcm_hardware snd_ice1712_playback_pro =
1137{ 1137{
1138 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1138 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1139 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1139 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1153,7 +1153,7 @@ static struct snd_pcm_hardware snd_ice1712_playback_pro =
1153 .fifo_size = 0, 1153 .fifo_size = 0,
1154}; 1154};
1155 1155
1156static struct snd_pcm_hardware snd_ice1712_capture_pro = 1156static const struct snd_pcm_hardware snd_ice1712_capture_pro =
1157{ 1157{
1158 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1158 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1159 SNDRV_PCM_INFO_BLOCK_TRANSFER | 1159 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -1378,9 +1378,9 @@ static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struc
1378 return change; 1378 return change;
1379} 1379}
1380 1380
1381static DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0); 1381static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0);
1382 1382
1383static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = { 1383static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = {
1384 { 1384 {
1385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1385 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1386 .name = "Multi Playback Switch", 1386 .name = "Multi Playback Switch",
@@ -1404,7 +1404,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata
1404 }, 1404 },
1405}; 1405};
1406 1406
1407static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = { 1407static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = {
1408 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1408 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1409 .name = "H/W Multi Capture Switch", 1409 .name = "H/W Multi Capture Switch",
1410 .info = snd_ice1712_pro_mixer_switch_info, 1410 .info = snd_ice1712_pro_mixer_switch_info,
@@ -1413,7 +1413,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinit
1413 .private_value = 10, 1413 .private_value = 10,
1414}; 1414};
1415 1415
1416static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { 1416static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = {
1417 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1417 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1418 .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH), 1418 .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH),
1419 .info = snd_ice1712_pro_mixer_switch_info, 1419 .info = snd_ice1712_pro_mixer_switch_info,
@@ -1423,7 +1423,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitd
1423 .count = 2, 1423 .count = 2,
1424}; 1424};
1425 1425
1426static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = { 1426static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = {
1427 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1427 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1428 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1428 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1429 SNDRV_CTL_ELEM_ACCESS_TLV_READ), 1429 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
@@ -1435,7 +1435,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinit
1435 .tlv = { .p = db_scale_playback } 1435 .tlv = { .p = db_scale_playback }
1436}; 1436};
1437 1437
1438static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { 1438static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = {
1439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1440 .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME), 1440 .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME),
1441 .info = snd_ice1712_pro_mixer_volume_info, 1441 .info = snd_ice1712_pro_mixer_volume_info,
@@ -1627,7 +1627,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol,
1627 return 0; 1627 return 0;
1628} 1628}
1629 1629
1630static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = { 1630static const struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = {
1631 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1631 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1632 .name = "ICE1712 EEPROM", 1632 .name = "ICE1712 EEPROM",
1633 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1633 .access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1663,7 +1663,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol,
1663 return 0; 1663 return 0;
1664} 1664}
1665 1665
1666static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = 1666static const struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata =
1667{ 1667{
1668 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1668 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1669 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1669 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1714,7 +1714,7 @@ static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol,
1714 return 0; 1714 return 0;
1715} 1715}
1716 1716
1717static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = 1717static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
1718{ 1718{
1719 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1719 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1720 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1720 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1723,7 +1723,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata =
1723 .get = snd_ice1712_spdif_maskc_get, 1723 .get = snd_ice1712_spdif_maskc_get,
1724}; 1724};
1725 1725
1726static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = 1726static const struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata =
1727{ 1727{
1728 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1728 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1729 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1729 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1750,7 +1750,7 @@ static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol,
1750 return 0; 1750 return 0;
1751} 1751}
1752 1752
1753static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = 1753static const struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata =
1754{ 1754{
1755 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 1755 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
1756 SNDRV_CTL_ELEM_ACCESS_INACTIVE), 1756 SNDRV_CTL_ELEM_ACCESS_INACTIVE),
@@ -1811,7 +1811,7 @@ int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol,
1811static int snd_ice1712_pro_internal_clock_info(struct snd_kcontrol *kcontrol, 1811static int snd_ice1712_pro_internal_clock_info(struct snd_kcontrol *kcontrol,
1812 struct snd_ctl_elem_info *uinfo) 1812 struct snd_ctl_elem_info *uinfo)
1813{ 1813{
1814 static char *texts[] = { 1814 static const char * const texts[] = {
1815 "8000", /* 0: 6 */ 1815 "8000", /* 0: 6 */
1816 "9600", /* 1: 3 */ 1816 "9600", /* 1: 3 */
1817 "11025", /* 2: 10 */ 1817 "11025", /* 2: 10 */
@@ -1840,7 +1840,7 @@ static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
1840 struct snd_ctl_elem_value *ucontrol) 1840 struct snd_ctl_elem_value *ucontrol)
1841{ 1841{
1842 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1842 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1843 static unsigned char xlate[16] = { 1843 static const unsigned char xlate[16] = {
1844 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10 1844 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10
1845 }; 1845 };
1846 unsigned char val; 1846 unsigned char val;
@@ -1864,7 +1864,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1864 struct snd_ctl_elem_value *ucontrol) 1864 struct snd_ctl_elem_value *ucontrol)
1865{ 1865{
1866 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1866 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1867 static unsigned int xrate[13] = { 1867 static const unsigned int xrate[13] = {
1868 8000, 9600, 11025, 12000, 16000, 22050, 24000, 1868 8000, 9600, 11025, 12000, 16000, 22050, 24000,
1869 32000, 44100, 48000, 64000, 88200, 96000 1869 32000, 44100, 48000, 64000, 88200, 96000
1870 }; 1870 };
@@ -1891,7 +1891,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1891 return change; 1891 return change;
1892} 1892}
1893 1893
1894static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = { 1894static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = {
1895 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1895 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1896 .name = "Multi Track Internal Clock", 1896 .name = "Multi Track Internal Clock",
1897 .info = snd_ice1712_pro_internal_clock_info, 1897 .info = snd_ice1712_pro_internal_clock_info,
@@ -1902,7 +1902,7 @@ static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = {
1902static int snd_ice1712_pro_internal_clock_default_info(struct snd_kcontrol *kcontrol, 1902static int snd_ice1712_pro_internal_clock_default_info(struct snd_kcontrol *kcontrol,
1903 struct snd_ctl_elem_info *uinfo) 1903 struct snd_ctl_elem_info *uinfo)
1904{ 1904{
1905 static char *texts[] = { 1905 static const char * const texts[] = {
1906 "8000", /* 0: 6 */ 1906 "8000", /* 0: 6 */
1907 "9600", /* 1: 3 */ 1907 "9600", /* 1: 3 */
1908 "11025", /* 2: 10 */ 1908 "11025", /* 2: 10 */
@@ -1931,7 +1931,7 @@ static int snd_ice1712_pro_internal_clock_default_get(struct snd_kcontrol *kcont
1931 struct snd_ctl_elem_value *ucontrol) 1931 struct snd_ctl_elem_value *ucontrol)
1932{ 1932{
1933 int val; 1933 int val;
1934 static unsigned int xrate[13] = { 1934 static const unsigned int xrate[13] = {
1935 8000, 9600, 11025, 12000, 16000, 22050, 24000, 1935 8000, 9600, 11025, 12000, 16000, 22050, 24000,
1936 32000, 44100, 48000, 64000, 88200, 96000 1936 32000, 44100, 48000, 64000, 88200, 96000
1937 }; 1937 };
@@ -1948,7 +1948,7 @@ static int snd_ice1712_pro_internal_clock_default_get(struct snd_kcontrol *kcont
1948static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcontrol, 1948static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcontrol,
1949 struct snd_ctl_elem_value *ucontrol) 1949 struct snd_ctl_elem_value *ucontrol)
1950{ 1950{
1951 static unsigned int xrate[13] = { 1951 static const unsigned int xrate[13] = {
1952 8000, 9600, 11025, 12000, 16000, 22050, 24000, 1952 8000, 9600, 11025, 12000, 16000, 22050, 24000,
1953 32000, 44100, 48000, 64000, 88200, 96000 1953 32000, 44100, 48000, 64000, 88200, 96000
1954 }; 1954 };
@@ -1962,7 +1962,7 @@ static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcont
1962 return change; 1962 return change;
1963} 1963}
1964 1964
1965static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = { 1965static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = {
1966 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1966 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1967 .name = "Multi Track Internal Clock Default", 1967 .name = "Multi Track Internal Clock Default",
1968 .info = snd_ice1712_pro_internal_clock_default_info, 1968 .info = snd_ice1712_pro_internal_clock_default_info,
@@ -2001,7 +2001,7 @@ static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
2001 return change; 2001 return change;
2002} 2002}
2003 2003
2004static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { 2004static const struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = {
2005 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2005 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2006 .name = "Multi Track Rate Locking", 2006 .name = "Multi Track Rate Locking",
2007 .info = snd_ice1712_pro_rate_locking_info, 2007 .info = snd_ice1712_pro_rate_locking_info,
@@ -2040,7 +2040,7 @@ static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
2040 return change; 2040 return change;
2041} 2041}
2042 2042
2043static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = { 2043static const struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = {
2044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2045 .name = "Multi Track Rate Reset", 2045 .name = "Multi Track Rate Reset",
2046 .info = snd_ice1712_pro_rate_reset_info, 2046 .info = snd_ice1712_pro_rate_reset_info,
@@ -2054,7 +2054,7 @@ static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = {
2054static int snd_ice1712_pro_route_info(struct snd_kcontrol *kcontrol, 2054static int snd_ice1712_pro_route_info(struct snd_kcontrol *kcontrol,
2055 struct snd_ctl_elem_info *uinfo) 2055 struct snd_ctl_elem_info *uinfo)
2056{ 2056{
2057 static char *texts[] = { 2057 static const char * const texts[] = {
2058 "PCM Out", /* 0 */ 2058 "PCM Out", /* 0 */
2059 "H/W In 0", "H/W In 1", "H/W In 2", "H/W In 3", /* 1-4 */ 2059 "H/W In 0", "H/W In 1", "H/W In 2", "H/W In 3", /* 1-4 */
2060 "H/W In 4", "H/W In 5", "H/W In 6", "H/W In 7", /* 5-8 */ 2060 "H/W In 4", "H/W In 5", "H/W In 6", "H/W In 7", /* 5-8 */
@@ -2207,7 +2207,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
2207 return change; 2207 return change;
2208} 2208}
2209 2209
2210static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = { 2210static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = {
2211 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2211 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2212 .name = "H/W Playback Route", 2212 .name = "H/W Playback Route",
2213 .info = snd_ice1712_pro_route_info, 2213 .info = snd_ice1712_pro_route_info,
@@ -2215,7 +2215,7 @@ static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata
2215 .put = snd_ice1712_pro_route_analog_put, 2215 .put = snd_ice1712_pro_route_analog_put,
2216}; 2216};
2217 2217
2218static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { 2218static const struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = {
2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2219 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2220 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", 2220 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
2221 .info = snd_ice1712_pro_route_info, 2221 .info = snd_ice1712_pro_route_info,
@@ -2257,7 +2257,7 @@ static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol,
2257 return change; 2257 return change;
2258} 2258}
2259 2259
2260static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = { 2260static const struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = {
2261 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2261 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2262 .name = "Multi Track Volume Rate", 2262 .name = "Multi Track Volume Rate",
2263 .info = snd_ice1712_pro_volume_rate_info, 2263 .info = snd_ice1712_pro_volume_rate_info,
@@ -2290,7 +2290,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol,
2290 return 0; 2290 return 0;
2291} 2291}
2292 2292
2293static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { 2293static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {
2294 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2294 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2295 .name = "Multi Track Peak", 2295 .name = "Multi Track Peak",
2296 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 2296 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -2305,7 +2305,7 @@ static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = {
2305/* 2305/*
2306 * list of available boards 2306 * list of available boards
2307 */ 2307 */
2308static struct snd_ice1712_card_info *card_tables[] __devinitdata = { 2308static const struct snd_ice1712_card_info *card_tables[] __devinitdata = {
2309 snd_ice1712_hoontech_cards, 2309 snd_ice1712_hoontech_cards,
2310 snd_ice1712_delta_cards, 2310 snd_ice1712_delta_cards,
2311 snd_ice1712_ews_cards, 2311 snd_ice1712_ews_cards,
@@ -2329,7 +2329,7 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice,
2329{ 2329{
2330 int dev = 0xa0; /* EEPROM device address */ 2330 int dev = 0xa0; /* EEPROM device address */
2331 unsigned int i, size; 2331 unsigned int i, size;
2332 struct snd_ice1712_card_info **tbl, *c; 2332 const struct snd_ice1712_card_info **tbl, *c;
2333 2333
2334 if (! modelname || ! *modelname) { 2334 if (! modelname || ! *modelname) {
2335 ice->eeprom.subvendor = 0; 2335 ice->eeprom.subvendor = 0;
@@ -2658,7 +2658,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
2658 * 2658 *
2659 */ 2659 */
2660 2660
2661static struct snd_ice1712_card_info no_matched __devinitdata; 2661static const struct snd_ice1712_card_info no_matched __devinitdata;
2662 2662
2663static int __devinit snd_ice1712_probe(struct pci_dev *pci, 2663static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2664 const struct pci_device_id *pci_id) 2664 const struct pci_device_id *pci_id)
@@ -2667,7 +2667,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci,
2667 struct snd_card *card; 2667 struct snd_card *card;
2668 struct snd_ice1712 *ice; 2668 struct snd_ice1712 *ice;
2669 int pcm_dev = 0, err; 2669 int pcm_dev = 0, err;
2670 struct snd_ice1712_card_info **tbl, *c; 2670 const struct snd_ice1712_card_info **tbl, *c;
2671 2671
2672 if (dev >= SNDRV_CARDS) 2672 if (dev >= SNDRV_CARDS)
2673 return -ENODEV; 2673 return -ENODEV;
diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h
index ce27eac40d4e..c3d9feaaf57d 100644
--- a/sound/pci/ice1712/ice1712.h
+++ b/sound/pci/ice1712/ice1712.h
@@ -28,6 +28,7 @@
28#include <sound/i2c.h> 28#include <sound/i2c.h>
29#include <sound/ak4xxx-adda.h> 29#include <sound/ak4xxx-adda.h>
30#include <sound/ak4114.h> 30#include <sound/ak4114.h>
31#include <sound/pt2258.h>
31#include <sound/pcm.h> 32#include <sound/pcm.h>
32#include <sound/mpu401.h> 33#include <sound/mpu401.h>
33 34
@@ -381,6 +382,11 @@ struct snd_ice1712 {
381 unsigned short master[2]; 382 unsigned short master[2];
382 unsigned short vol[8]; 383 unsigned short vol[8];
383 } phase28; 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;
384 /* Hoontech-specific setting */ 390 /* Hoontech-specific setting */
385 struct hoontech_spec { 391 struct hoontech_spec {
386 unsigned char boxbits[4]; 392 unsigned char boxbits[4];
@@ -462,6 +468,14 @@ static inline void snd_ice1712_gpio_write_bits(struct snd_ice1712 *ice,
462 snd_ice1712_gpio_write(ice, mask & bits); 468 snd_ice1712_gpio_write(ice, mask & bits);
463} 469}
464 470
471static inline int snd_ice1712_gpio_read_bits(struct snd_ice1712 *ice,
472 unsigned int mask)
473{
474 ice->gpio.direction &= ~mask;
475 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
476 return (snd_ice1712_gpio_read(ice) & mask);
477}
478
465int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice); 479int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice);
466 480
467int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak, const struct snd_akm4xxx *template, 481int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak, const struct snd_akm4xxx *template,
@@ -500,8 +514,8 @@ struct snd_ice1712_card_info {
500 unsigned int mpu401_2_info_flags; 514 unsigned int mpu401_2_info_flags;
501 const char *mpu401_1_name; 515 const char *mpu401_1_name;
502 const char *mpu401_2_name; 516 const char *mpu401_2_name;
503 unsigned int eeprom_size; 517 const unsigned int eeprom_size;
504 unsigned char *eeprom_data; 518 const unsigned char *eeprom_data;
505}; 519};
506 520
507 521
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index 3e3a102e6c34..1127ebdf5fec 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -50,7 +50,7 @@
50#include "prodigy192.h" 50#include "prodigy192.h"
51#include "juli.h" 51#include "juli.h"
52#include "phase.h" 52#include "phase.h"
53 53#include "wtm.h"
54 54
55MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); 55MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
56MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)"); 56MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)");
@@ -64,6 +64,7 @@ MODULE_SUPPORTED_DEVICE("{"
64 PRODIGY192_DEVICE_DESC 64 PRODIGY192_DEVICE_DESC
65 JULI_DEVICE_DESC 65 JULI_DEVICE_DESC
66 PHASE_DEVICE_DESC 66 PHASE_DEVICE_DESC
67 WTM_DEVICE_DESC
67 "{VIA,VT1720}," 68 "{VIA,VT1720},"
68 "{VIA,VT1724}," 69 "{VIA,VT1724},"
69 "{ICEnsemble,Generic ICE1724}," 70 "{ICEnsemble,Generic ICE1724},"
@@ -86,7 +87,7 @@ MODULE_PARM_DESC(model, "Use the given board model.");
86 87
87 88
88/* Both VT1720 and VT1724 have the same PCI IDs */ 89/* Both VT1720 and VT1724 have the same PCI IDs */
89static struct pci_device_id snd_vt1724_ids[] = { 90static const struct pci_device_id snd_vt1724_ids[] = {
90 { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, 91 { PCI_VENDOR_ID_ICE, PCI_DEVICE_ID_VT1724, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
91 { 0, } 92 { 0, }
92}; 93};
@@ -341,7 +342,7 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
341 342
342 what = 0; 343 what = 0;
343 snd_pcm_group_for_each(pos, substream) { 344 snd_pcm_group_for_each(pos, substream) {
344 struct vt1724_pcm_reg *reg; 345 const struct vt1724_pcm_reg *reg;
345 s = snd_pcm_group_substream_entry(pos); 346 s = snd_pcm_group_substream_entry(pos);
346 reg = s->runtime->private_data; 347 reg = s->runtime->private_data;
347 what |= reg->start; 348 what |= reg->start;
@@ -605,7 +606,7 @@ static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(struct snd_pcm_substrea
605static int snd_vt1724_pcm_prepare(struct snd_pcm_substream *substream) 606static int snd_vt1724_pcm_prepare(struct snd_pcm_substream *substream)
606{ 607{
607 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); 608 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
608 struct vt1724_pcm_reg *reg = substream->runtime->private_data; 609 const struct vt1724_pcm_reg *reg = substream->runtime->private_data;
609 610
610 spin_lock_irq(&ice->reg_lock); 611 spin_lock_irq(&ice->reg_lock);
611 outl(substream->runtime->dma_addr, ice->profi_port + reg->addr); 612 outl(substream->runtime->dma_addr, ice->profi_port + reg->addr);
@@ -620,7 +621,7 @@ static int snd_vt1724_pcm_prepare(struct snd_pcm_substream *substream)
620static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substream) 621static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substream)
621{ 622{
622 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); 623 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
623 struct vt1724_pcm_reg *reg = substream->runtime->private_data; 624 const struct vt1724_pcm_reg *reg = substream->runtime->private_data;
624 size_t ptr; 625 size_t ptr;
625 626
626 if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & reg->start)) 627 if (!(inl(ICEMT1724(ice, DMA_CONTROL)) & reg->start))
@@ -646,21 +647,21 @@ static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substr
646#endif 647#endif
647} 648}
648 649
649static struct vt1724_pcm_reg vt1724_playback_pro_reg = { 650static const struct vt1724_pcm_reg vt1724_playback_pro_reg = {
650 .addr = VT1724_MT_PLAYBACK_ADDR, 651 .addr = VT1724_MT_PLAYBACK_ADDR,
651 .size = VT1724_MT_PLAYBACK_SIZE, 652 .size = VT1724_MT_PLAYBACK_SIZE,
652 .count = VT1724_MT_PLAYBACK_COUNT, 653 .count = VT1724_MT_PLAYBACK_COUNT,
653 .start = VT1724_PDMA0_START, 654 .start = VT1724_PDMA0_START,
654}; 655};
655 656
656static struct vt1724_pcm_reg vt1724_capture_pro_reg = { 657static const struct vt1724_pcm_reg vt1724_capture_pro_reg = {
657 .addr = VT1724_MT_CAPTURE_ADDR, 658 .addr = VT1724_MT_CAPTURE_ADDR,
658 .size = VT1724_MT_CAPTURE_SIZE, 659 .size = VT1724_MT_CAPTURE_SIZE,
659 .count = VT1724_MT_CAPTURE_COUNT, 660 .count = VT1724_MT_CAPTURE_COUNT,
660 .start = VT1724_RDMA0_START, 661 .start = VT1724_RDMA0_START,
661}; 662};
662 663
663static struct snd_pcm_hardware snd_vt1724_playback_pro = 664static const struct snd_pcm_hardware snd_vt1724_playback_pro =
664{ 665{
665 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 666 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
666 SNDRV_PCM_INFO_BLOCK_TRANSFER | 667 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -679,7 +680,7 @@ static struct snd_pcm_hardware snd_vt1724_playback_pro =
679 .periods_max = 1024, 680 .periods_max = 1024,
680}; 681};
681 682
682static struct snd_pcm_hardware snd_vt1724_spdif = 683static const struct snd_pcm_hardware snd_vt1724_spdif =
683{ 684{
684 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 685 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
685 SNDRV_PCM_INFO_BLOCK_TRANSFER | 686 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -701,7 +702,7 @@ static struct snd_pcm_hardware snd_vt1724_spdif =
701 .periods_max = 1024, 702 .periods_max = 1024,
702}; 703};
703 704
704static struct snd_pcm_hardware snd_vt1724_2ch_stereo = 705static const struct snd_pcm_hardware snd_vt1724_2ch_stereo =
705{ 706{
706 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 707 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
707 SNDRV_PCM_INFO_BLOCK_TRANSFER | 708 SNDRV_PCM_INFO_BLOCK_TRANSFER |
@@ -773,7 +774,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream)
773 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); 774 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
774 int chs; 775 int chs;
775 776
776 runtime->private_data = &vt1724_playback_pro_reg; 777 runtime->private_data = (void *)&vt1724_playback_pro_reg;
777 ice->playback_pro_substream = substream; 778 ice->playback_pro_substream = substream;
778 runtime->hw = snd_vt1724_playback_pro; 779 runtime->hw = snd_vt1724_playback_pro;
779 snd_pcm_set_sync(substream); 780 snd_pcm_set_sync(substream);
@@ -802,7 +803,7 @@ static int snd_vt1724_capture_pro_open(struct snd_pcm_substream *substream)
802 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); 803 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
803 struct snd_pcm_runtime *runtime = substream->runtime; 804 struct snd_pcm_runtime *runtime = substream->runtime;
804 805
805 runtime->private_data = &vt1724_capture_pro_reg; 806 runtime->private_data = (void *)&vt1724_capture_pro_reg;
806 ice->capture_pro_substream = substream; 807 ice->capture_pro_substream = substream;
807 runtime->hw = snd_vt1724_2ch_stereo; 808 runtime->hw = snd_vt1724_2ch_stereo;
808 snd_pcm_set_sync(substream); 809 snd_pcm_set_sync(substream);
@@ -888,14 +889,14 @@ static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 * ice, int device)
888 * SPDIF PCM 889 * SPDIF PCM
889 */ 890 */
890 891
891static struct vt1724_pcm_reg vt1724_playback_spdif_reg = { 892static const struct vt1724_pcm_reg vt1724_playback_spdif_reg = {
892 .addr = VT1724_MT_PDMA4_ADDR, 893 .addr = VT1724_MT_PDMA4_ADDR,
893 .size = VT1724_MT_PDMA4_SIZE, 894 .size = VT1724_MT_PDMA4_SIZE,
894 .count = VT1724_MT_PDMA4_COUNT, 895 .count = VT1724_MT_PDMA4_COUNT,
895 .start = VT1724_PDMA4_START, 896 .start = VT1724_PDMA4_START,
896}; 897};
897 898
898static struct vt1724_pcm_reg vt1724_capture_spdif_reg = { 899static const struct vt1724_pcm_reg vt1724_capture_spdif_reg = {
899 .addr = VT1724_MT_RDMA1_ADDR, 900 .addr = VT1724_MT_RDMA1_ADDR,
900 .size = VT1724_MT_RDMA1_SIZE, 901 .size = VT1724_MT_RDMA1_SIZE,
901 .count = VT1724_MT_RDMA1_COUNT, 902 .count = VT1724_MT_RDMA1_COUNT,
@@ -953,7 +954,7 @@ static int snd_vt1724_playback_spdif_open(struct snd_pcm_substream *substream)
953 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); 954 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
954 struct snd_pcm_runtime *runtime = substream->runtime; 955 struct snd_pcm_runtime *runtime = substream->runtime;
955 956
956 runtime->private_data = &vt1724_playback_spdif_reg; 957 runtime->private_data = (void *)&vt1724_playback_spdif_reg;
957 ice->playback_con_substream = substream; 958 ice->playback_con_substream = substream;
958 if (ice->force_pdma4) { 959 if (ice->force_pdma4) {
959 runtime->hw = snd_vt1724_2ch_stereo; 960 runtime->hw = snd_vt1724_2ch_stereo;
@@ -985,7 +986,7 @@ static int snd_vt1724_capture_spdif_open(struct snd_pcm_substream *substream)
985 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); 986 struct snd_ice1712 *ice = snd_pcm_substream_chip(substream);
986 struct snd_pcm_runtime *runtime = substream->runtime; 987 struct snd_pcm_runtime *runtime = substream->runtime;
987 988
988 runtime->private_data = &vt1724_capture_spdif_reg; 989 runtime->private_data = (void *)&vt1724_capture_spdif_reg;
989 ice->capture_con_substream = substream; 990 ice->capture_con_substream = substream;
990 if (ice->force_rdma1) { 991 if (ice->force_rdma1) {
991 runtime->hw = snd_vt1724_2ch_stereo; 992 runtime->hw = snd_vt1724_2ch_stereo;
@@ -1090,7 +1091,7 @@ static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 * ice, int device)
1090 * independent surround PCMs 1091 * independent surround PCMs
1091 */ 1092 */
1092 1093
1093static struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = { 1094static const struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = {
1094 { 1095 {
1095 .addr = VT1724_MT_PDMA1_ADDR, 1096 .addr = VT1724_MT_PDMA1_ADDR,
1096 .size = VT1724_MT_PDMA1_SIZE, 1097 .size = VT1724_MT_PDMA1_SIZE,
@@ -1136,7 +1137,7 @@ static int snd_vt1724_playback_indep_open(struct snd_pcm_substream *substream)
1136 return -EBUSY; /* FIXME: should handle blocking mode properly */ 1137 return -EBUSY; /* FIXME: should handle blocking mode properly */
1137 } 1138 }
1138 mutex_unlock(&ice->open_mutex); 1139 mutex_unlock(&ice->open_mutex);
1139 runtime->private_data = &vt1724_playback_dma_regs[substream->number]; 1140 runtime->private_data = (void *)&vt1724_playback_dma_regs[substream->number];
1140 ice->playback_con_substream_ds[substream->number] = substream; 1141 ice->playback_con_substream_ds[substream->number] = substream;
1141 runtime->hw = snd_vt1724_2ch_stereo; 1142 runtime->hw = snd_vt1724_2ch_stereo;
1142 snd_pcm_set_sync(substream); 1143 snd_pcm_set_sync(substream);
@@ -1317,7 +1318,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol,
1317 return 0; 1318 return 0;
1318} 1319}
1319 1320
1320static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = { 1321static const struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = {
1321 .iface = SNDRV_CTL_ELEM_IFACE_CARD, 1322 .iface = SNDRV_CTL_ELEM_IFACE_CARD,
1322 .name = "ICE1724 EEPROM", 1323 .name = "ICE1724 EEPROM",
1323 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1324 .access = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -1430,7 +1431,7 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol,
1430 return (val != old); 1431 return (val != old);
1431} 1432}
1432 1433
1433static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = 1434static const struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata =
1434{ 1435{
1435 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1436 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
1436 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), 1437 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
@@ -1462,7 +1463,7 @@ static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol,
1462 return 0; 1463 return 0;
1463} 1464}
1464 1465
1465static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = 1466static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
1466{ 1467{
1467 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1468 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1468 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1469 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1471,7 +1472,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata =
1471 .get = snd_vt1724_spdif_maskc_get, 1472 .get = snd_vt1724_spdif_maskc_get,
1472}; 1473};
1473 1474
1474static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = 1475static const struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata =
1475{ 1476{
1476 .access = SNDRV_CTL_ELEM_ACCESS_READ, 1477 .access = SNDRV_CTL_ELEM_ACCESS_READ,
1477 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 1478 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
@@ -1516,7 +1517,7 @@ static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol,
1516 return old != val; 1517 return old != val;
1517} 1518}
1518 1519
1519static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = 1520static const struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata =
1520{ 1521{
1521 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1522 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1522 /* FIXME: the following conflict with IEC958 Playback Route */ 1523 /* FIXME: the following conflict with IEC958 Playback Route */
@@ -1584,7 +1585,7 @@ int snd_ice1712_gpio_put(struct snd_kcontrol *kcontrol,
1584static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol, 1585static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol,
1585 struct snd_ctl_elem_info *uinfo) 1586 struct snd_ctl_elem_info *uinfo)
1586{ 1587{
1587 static char *texts_1724[] = { 1588 static const char * const texts_1724[] = {
1588 "8000", /* 0: 6 */ 1589 "8000", /* 0: 6 */
1589 "9600", /* 1: 3 */ 1590 "9600", /* 1: 3 */
1590 "11025", /* 2: 10 */ 1591 "11025", /* 2: 10 */
@@ -1602,7 +1603,7 @@ static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol,
1602 "192000", /* 14: 14 */ 1603 "192000", /* 14: 14 */
1603 "IEC958 Input", /* 15: -- */ 1604 "IEC958 Input", /* 15: -- */
1604 }; 1605 };
1605 static char *texts_1720[] = { 1606 static const char * const texts_1720[] = {
1606 "8000", /* 0: 6 */ 1607 "8000", /* 0: 6 */
1607 "9600", /* 1: 3 */ 1608 "9600", /* 1: 3 */
1608 "11025", /* 2: 10 */ 1609 "11025", /* 2: 10 */
@@ -1635,7 +1636,7 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol,
1635 struct snd_ctl_elem_value *ucontrol) 1636 struct snd_ctl_elem_value *ucontrol)
1636{ 1637{
1637 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); 1638 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
1638 static unsigned char xlate[16] = { 1639 static const unsigned char xlate[16] = {
1639 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 13, 255, 14, 10 1640 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 13, 255, 14, 10
1640 }; 1641 };
1641 unsigned char val; 1642 unsigned char val;
@@ -1694,7 +1695,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol,
1694 return change; 1695 return change;
1695} 1696}
1696 1697
1697static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { 1698static const struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = {
1698 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1699 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1699 .name = "Multi Track Internal Clock", 1700 .name = "Multi Track Internal Clock",
1700 .info = snd_vt1724_pro_internal_clock_info, 1701 .info = snd_vt1724_pro_internal_clock_info,
@@ -1733,7 +1734,7 @@ static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol,
1733 return change; 1734 return change;
1734} 1735}
1735 1736
1736static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { 1737static const struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = {
1737 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1738 .name = "Multi Track Rate Locking", 1739 .name = "Multi Track Rate Locking",
1739 .info = snd_vt1724_pro_rate_locking_info, 1740 .info = snd_vt1724_pro_rate_locking_info,
@@ -1772,7 +1773,7 @@ static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol,
1772 return change; 1773 return change;
1773} 1774}
1774 1775
1775static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = { 1776static const struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = {
1776 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1777 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1777 .name = "Multi Track Rate Reset", 1778 .name = "Multi Track Rate Reset",
1778 .info = snd_vt1724_pro_rate_reset_info, 1779 .info = snd_vt1724_pro_rate_reset_info,
@@ -1816,7 +1817,7 @@ static int get_route_val(struct snd_ice1712 *ice, int shift)
1816{ 1817{
1817 unsigned long val; 1818 unsigned long val;
1818 unsigned char eitem; 1819 unsigned char eitem;
1819 static unsigned char xlate[8] = { 1820 static const unsigned char xlate[8] = {
1820 0, 255, 1, 2, 255, 255, 3, 4, 1821 0, 255, 1, 2, 255, 255, 3, 4,
1821 }; 1822 };
1822 1823
@@ -1835,7 +1836,7 @@ static int put_route_val(struct snd_ice1712 *ice, unsigned int val, int shift)
1835{ 1836{
1836 unsigned int old_val, nval; 1837 unsigned int old_val, nval;
1837 int change; 1838 int change;
1838 static unsigned char xroute[8] = { 1839 static const unsigned char xroute[8] = {
1839 0, /* PCM */ 1840 0, /* PCM */
1840 2, /* PSDIN0 Left */ 1841 2, /* PSDIN0 Left */
1841 3, /* PSDIN0 Right */ 1842 3, /* PSDIN0 Right */
@@ -1891,7 +1892,7 @@ static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol,
1891 digital_route_shift(idx)); 1892 digital_route_shift(idx));
1892} 1893}
1893 1894
1894static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = { 1895static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = {
1895 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1896 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1896 .name = "H/W Playback Route", 1897 .name = "H/W Playback Route",
1897 .info = snd_vt1724_pro_route_info, 1898 .info = snd_vt1724_pro_route_info,
@@ -1899,7 +1900,7 @@ static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata =
1899 .put = snd_vt1724_pro_route_analog_put, 1900 .put = snd_vt1724_pro_route_analog_put,
1900}; 1901};
1901 1902
1902static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { 1903static const struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = {
1903 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1904 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1904 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", 1905 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route",
1905 .info = snd_vt1724_pro_route_info, 1906 .info = snd_vt1724_pro_route_info,
@@ -1935,7 +1936,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol,
1935 return 0; 1936 return 0;
1936} 1937}
1937 1938
1938static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { 1939static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
1939 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1940 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1940 .name = "Multi Track Peak", 1941 .name = "Multi Track Peak",
1941 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, 1942 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE,
@@ -1947,9 +1948,9 @@ static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = {
1947 * 1948 *
1948 */ 1949 */
1949 1950
1950static struct snd_ice1712_card_info no_matched __devinitdata; 1951static const struct snd_ice1712_card_info no_matched __devinitdata;
1951 1952
1952static struct snd_ice1712_card_info *card_tables[] __devinitdata = { 1953static const struct snd_ice1712_card_info *card_tables[] __devinitdata = {
1953 snd_vt1724_revo_cards, 1954 snd_vt1724_revo_cards,
1954 snd_vt1724_amp_cards, 1955 snd_vt1724_amp_cards,
1955 snd_vt1724_aureon_cards, 1956 snd_vt1724_aureon_cards,
@@ -1958,6 +1959,7 @@ static struct snd_ice1712_card_info *card_tables[] __devinitdata = {
1958 snd_vt1724_prodigy192_cards, 1959 snd_vt1724_prodigy192_cards,
1959 snd_vt1724_juli_cards, 1960 snd_vt1724_juli_cards,
1960 snd_vt1724_phase_cards, 1961 snd_vt1724_phase_cards,
1962 snd_vt1724_wtm_cards,
1961 NULL, 1963 NULL,
1962}; 1964};
1963 1965
@@ -2007,7 +2009,7 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice,
2007{ 2009{
2008 const int dev = 0xa0; /* EEPROM device address */ 2010 const int dev = 0xa0; /* EEPROM device address */
2009 unsigned int i, size; 2011 unsigned int i, size;
2010 struct snd_ice1712_card_info **tbl, *c; 2012 const struct snd_ice1712_card_info **tbl, *c;
2011 2013
2012 if (! modelname || ! *modelname) { 2014 if (! modelname || ! *modelname) {
2013 ice->eeprom.subvendor = 0; 2015 ice->eeprom.subvendor = 0;
@@ -2306,7 +2308,7 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci,
2306 struct snd_card *card; 2308 struct snd_card *card;
2307 struct snd_ice1712 *ice; 2309 struct snd_ice1712 *ice;
2308 int pcm_dev = 0, err; 2310 int pcm_dev = 0, err;
2309 struct snd_ice1712_card_info **tbl, *c; 2311 const struct snd_ice1712_card_info **tbl, *c;
2310 2312
2311 if (dev >= SNDRV_CARDS) 2313 if (dev >= SNDRV_CARDS)
2312 return -ENODEV; 2314 return -ENODEV;
diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c
index 5176b41ea9d3..d88172fa95da 100644
--- a/sound/pci/ice1712/juli.c
+++ b/sound/pci/ice1712/juli.c
@@ -125,7 +125,7 @@ static void juli_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
125 snd_akm4xxx_reset(ak, 0); 125 snd_akm4xxx_reset(ak, 0);
126} 126}
127 127
128static struct snd_akm4xxx akm_juli_dac __devinitdata = { 128static const struct snd_akm4xxx akm_juli_dac __devinitdata = {
129 .type = SND_AK4358, 129 .type = SND_AK4358,
130 .num_dacs = 2, 130 .num_dacs = 2,
131 .ops = { 131 .ops = {
@@ -146,7 +146,7 @@ static int __devinit juli_add_controls(struct snd_ice1712 *ice)
146 */ 146 */
147static int __devinit juli_init(struct snd_ice1712 *ice) 147static int __devinit juli_init(struct snd_ice1712 *ice)
148{ 148{
149 static unsigned char ak4114_init_vals[] = { 149 static const unsigned char ak4114_init_vals[] = {
150 /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, 150 /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
151 /* AK4114_REQ_FORMAT */ AK4114_DIF_I24I2S, 151 /* AK4114_REQ_FORMAT */ AK4114_DIF_I24I2S,
152 /* AK4114_REG_IO0 */ AK4114_TX1E, 152 /* AK4114_REG_IO0 */ AK4114_TX1E,
@@ -154,7 +154,7 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
154 /* AK4114_REG_INT0_MASK */ 0, 154 /* AK4114_REG_INT0_MASK */ 0,
155 /* AK4114_REG_INT1_MASK */ 0 155 /* AK4114_REG_INT1_MASK */ 0
156 }; 156 };
157 static unsigned char ak4114_init_txcsb[] = { 157 static const unsigned char ak4114_init_txcsb[] = {
158 0x41, 0x02, 0x2c, 0x00, 0x00 158 0x41, 0x02, 0x2c, 0x00, 0x00
159 }; 159 };
160 int err; 160 int err;
@@ -206,24 +206,24 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
206 * hence the driver needs to sets up it properly. 206 * hence the driver needs to sets up it properly.
207 */ 207 */
208 208
209static unsigned char juli_eeprom[] __devinitdata = { 209static const unsigned char juli_eeprom[] __devinitdata = {
210 0x20, /* SYSCONF: clock 512, mpu401, 1xADC, 1xDACs */ 210 [ICE_EEP2_SYSCONF] = 0x20, /* clock 512, mpu401, 1xADC, 1xDACs */
211 0x80, /* ACLINK: I2S */ 211 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
212 0xf8, /* I2S: vol, 96k, 24bit, 192k */ 212 [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */
213 0xc3, /* SPDIF: out-en, out-int, spdif-in */ 213 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
214 0x9f, /* GPIO_DIR */ 214 [ICE_EEP2_GPIO_DIR] = 0x9f,
215 0xff, /* GPIO_DIR1 */ 215 [ICE_EEP2_GPIO_DIR1] = 0xff,
216 0x7f, /* GPIO_DIR2 */ 216 [ICE_EEP2_GPIO_DIR2] = 0x7f,
217 0x9f, /* GPIO_MASK */ 217 [ICE_EEP2_GPIO_MASK] = 0x9f,
218 0xff, /* GPIO_MASK1 */ 218 [ICE_EEP2_GPIO_MASK1] = 0xff,
219 0x7f, /* GPIO_MASK2 */ 219 [ICE_EEP2_GPIO_MASK2] = 0x7f,
220 0x16, /* GPIO_STATE: internal clock, multiple 1x, 48kHz */ 220 [ICE_EEP2_GPIO_STATE] = 0x16, /* internal clock, multiple 1x, 48kHz */
221 0x80, /* GPIO_STATE1: mute */ 221 [ICE_EEP2_GPIO_STATE1] = 0x80, /* mute */
222 0x00, /* GPIO_STATE2 */ 222 [ICE_EEP2_GPIO_STATE2] = 0x00,
223}; 223};
224 224
225/* entry point */ 225/* entry point */
226struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = { 226const struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = {
227 { 227 {
228 .subvendor = VT1724_SUBDEVICE_JULI, 228 .subvendor = VT1724_SUBDEVICE_JULI,
229 .name = "ESI Juli@", 229 .name = "ESI Juli@",
diff --git a/sound/pci/ice1712/juli.h b/sound/pci/ice1712/juli.h
index d9f8534fd92e..1b9294f8bce3 100644
--- a/sound/pci/ice1712/juli.h
+++ b/sound/pci/ice1712/juli.h
@@ -5,6 +5,6 @@
5 5
6#define VT1724_SUBDEVICE_JULI 0x31305345 /* Juli@ */ 6#define VT1724_SUBDEVICE_JULI 0x31305345 /* Juli@ */
7 7
8extern struct snd_ice1712_card_info snd_vt1724_juli_cards[]; 8extern const struct snd_ice1712_card_info snd_vt1724_juli_cards[];
9 9
10#endif /* __SOUND_JULI_H */ 10#endif /* __SOUND_JULI_H */
diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c
index e08d73f4ff85..0751718f4d7b 100644
--- a/sound/pci/ice1712/phase.c
+++ b/sound/pci/ice1712/phase.c
@@ -71,7 +71,7 @@
71 * Logarithmic volume values for WM8770 71 * Logarithmic volume values for WM8770
72 * Computed as 20 * Log10(255 / x) 72 * Computed as 20 * Log10(255 / x)
73 */ 73 */
74static unsigned char wm_vol[256] = { 74static const unsigned char wm_vol[256] = {
75 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23, 75 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
76 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, 76 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
77 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, 77 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
@@ -89,13 +89,13 @@ static unsigned char wm_vol[256] = {
89#define WM_VOL_MAX (sizeof(wm_vol) - 1) 89#define WM_VOL_MAX (sizeof(wm_vol) - 1)
90#define WM_VOL_MUTE 0x8000 90#define WM_VOL_MUTE 0x8000
91 91
92static struct snd_akm4xxx akm_phase22 __devinitdata = { 92static const struct snd_akm4xxx akm_phase22 __devinitdata = {
93 .type = SND_AK4524, 93 .type = SND_AK4524,
94 .num_dacs = 2, 94 .num_dacs = 2,
95 .num_adcs = 2, 95 .num_adcs = 2,
96}; 96};
97 97
98static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { 98static const struct snd_ak4xxx_private akm_phase22_priv __devinitdata = {
99 .caddr = 2, 99 .caddr = 2,
100 .cif = 1, 100 .cif = 1,
101 .data_mask = 1 << 4, 101 .data_mask = 1 << 4,
@@ -152,36 +152,36 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice)
152 return 0; 152 return 0;
153} 153}
154 154
155static unsigned char phase22_eeprom[] __devinitdata = { 155static const unsigned char phase22_eeprom[] __devinitdata = {
156 0x00, /* SYSCONF: 1xADC, 1xDACs */ 156 [ICE_EEP2_SYSCONF] = 0x00, /* 1xADC, 1xDACs */
157 0x80, /* ACLINK: I2S */ 157 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
158 0xf8, /* I2S: vol, 96k, 24bit*/ 158 [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit */
159 0xc3, /* SPDIF: out-en, out-int, spdif-in */ 159 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
160 0xFF, /* GPIO_DIR */ 160 [ICE_EEP2_GPIO_DIR] = 0xff,
161 0xFF, /* GPIO_DIR1 */ 161 [ICE_EEP2_GPIO_DIR1] = 0xff,
162 0xFF, /* GPIO_DIR2 */ 162 [ICE_EEP2_GPIO_DIR2] = 0xff,
163 0x00, /* GPIO_MASK */ 163 [ICE_EEP2_GPIO_MASK] = 0x00,
164 0x00, /* GPIO_MASK1 */ 164 [ICE_EEP2_GPIO_MASK1] = 0x00,
165 0x00, /* GPIO_MASK2 */ 165 [ICE_EEP2_GPIO_MASK2] = 0x00,
166 0x00, /* GPIO_STATE: */ 166 [ICE_EEP2_GPIO_STATE] = 0x00,
167 0x00, /* GPIO_STATE1: */ 167 [ICE_EEP2_GPIO_STATE1] = 0x00,
168 0x00, /* GPIO_STATE2 */ 168 [ICE_EEP2_GPIO_STATE2] = 0x00,
169}; 169};
170 170
171static unsigned char phase28_eeprom[] __devinitdata = { 171static const unsigned char phase28_eeprom[] __devinitdata = {
172 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */ 172 [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */
173 0x80, /* ACLINK: I2S */ 173 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
174 0xfc, /* I2S: vol, 96k, 24bit, 192k */ 174 [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */
175 0xc3, /* SPDIF: out-en, out-int, spdif-in */ 175 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
176 0xff, /* GPIO_DIR */ 176 [ICE_EEP2_GPIO_DIR] = 0xff,
177 0xff, /* GPIO_DIR1 */ 177 [ICE_EEP2_GPIO_DIR1] = 0xff,
178 0x5f, /* GPIO_DIR2 */ 178 [ICE_EEP2_GPIO_DIR2] = 0x5f,
179 0x00, /* GPIO_MASK */ 179 [ICE_EEP2_GPIO_MASK] = 0x00,
180 0x00, /* GPIO_MASK1 */ 180 [ICE_EEP2_GPIO_MASK1] = 0x00,
181 0x00, /* GPIO_MASK2 */ 181 [ICE_EEP2_GPIO_MASK2] = 0x00,
182 0x00, /* GPIO_STATE */ 182 [ICE_EEP2_GPIO_STATE] = 0x00,
183 0x00, /* GPIO_STATE1 */ 183 [ICE_EEP2_GPIO_STATE1] = 0x00,
184 0x00, /* GPIO_STATE2 */ 184 [ICE_EEP2_GPIO_STATE2] = 0x00,
185}; 185};
186 186
187/* 187/*
@@ -343,7 +343,7 @@ static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_
343 343
344static int __devinit phase28_init(struct snd_ice1712 *ice) 344static int __devinit phase28_init(struct snd_ice1712 *ice)
345{ 345{
346 static unsigned short wm_inits_phase28[] = { 346 static const unsigned short wm_inits_phase28[] = {
347 /* These come first to reduce init pop noise */ 347 /* These come first to reduce init pop noise */
348 0x1b, 0x044, /* ADC Mux (AC'97 source) */ 348 0x1b, 0x044, /* ADC Mux (AC'97 source) */
349 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */ 349 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */
@@ -382,7 +382,7 @@ static int __devinit phase28_init(struct snd_ice1712 *ice)
382 382
383 unsigned int tmp; 383 unsigned int tmp;
384 struct snd_akm4xxx *ak; 384 struct snd_akm4xxx *ak;
385 unsigned short *p; 385 const unsigned short *p;
386 int i; 386 int i;
387 387
388 ice->num_total_dacs = 8; 388 ice->num_total_dacs = 8;
@@ -697,10 +697,10 @@ static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ct
697 return 0; 697 return 0;
698} 698}
699 699
700static DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); 700static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1);
701static DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); 701static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1);
702 702
703static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { 703static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
704 { 704 {
705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 705 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
706 .name = "Master Playback Switch", 706 .name = "Master Playback Switch",
@@ -815,7 +815,7 @@ static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = {
815 } 815 }
816}; 816};
817 817
818static struct snd_kcontrol_new wm_controls[] __devinitdata = { 818static const struct snd_kcontrol_new wm_controls[] __devinitdata = {
819 { 819 {
820 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 820 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
821 .name = "PCM Playback Switch", 821 .name = "PCM Playback Switch",
@@ -870,7 +870,7 @@ static int __devinit phase28_add_controls(struct snd_ice1712 *ice)
870 return 0; 870 return 0;
871} 871}
872 872
873struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { 873const struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = {
874 { 874 {
875 .subvendor = VT1724_SUBDEVICE_PHASE22, 875 .subvendor = VT1724_SUBDEVICE_PHASE22,
876 .name = "Terratec PHASE 22", 876 .name = "Terratec PHASE 22",
diff --git a/sound/pci/ice1712/phase.h b/sound/pci/ice1712/phase.h
index 13e841b55488..ad379a99bf92 100644
--- a/sound/pci/ice1712/phase.h
+++ b/sound/pci/ice1712/phase.h
@@ -31,7 +31,7 @@
31#define VT1724_SUBDEVICE_PHASE28 0x3b154911 31#define VT1724_SUBDEVICE_PHASE28 0x3b154911
32 32
33/* entry point */ 33/* entry point */
34extern struct snd_ice1712_card_info snd_vt1724_phase_cards[]; 34extern const struct snd_ice1712_card_info snd_vt1724_phase_cards[];
35 35
36/* PHASE28 GPIO bits */ 36/* PHASE28 GPIO bits */
37#define PHASE28_SPI_MISO (1 << 21) 37#define PHASE28_SPI_MISO (1 << 21)
diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c
index 6c74c2d2e7f3..9552497f0765 100644
--- a/sound/pci/ice1712/pontis.c
+++ b/sound/pci/ice1712/pontis.c
@@ -434,7 +434,7 @@ static unsigned int spi_read(struct snd_ice1712 *ice, unsigned int dev, unsigned
434 */ 434 */
435static int cs_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 435static int cs_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
436{ 436{
437 static char *texts[] = { 437 static const char * const texts[] = {
438 "Coax", /* RXP0 */ 438 "Coax", /* RXP0 */
439 "Optical", /* RXP1 */ 439 "Optical", /* RXP1 */
440 "CD", /* RXP2 */ 440 "CD", /* RXP2 */
@@ -565,13 +565,13 @@ static int pontis_gpio_data_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
565 return changed; 565 return changed;
566} 566}
567 567
568static DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1); 568static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1);
569 569
570/* 570/*
571 * mixers 571 * mixers
572 */ 572 */
573 573
574static struct snd_kcontrol_new pontis_controls[] __devinitdata = { 574static const struct snd_kcontrol_new pontis_controls[] __devinitdata = {
575 { 575 {
576 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 576 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
577 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | 577 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -741,7 +741,7 @@ static int __devinit pontis_add_controls(struct snd_ice1712 *ice)
741 */ 741 */
742static int __devinit pontis_init(struct snd_ice1712 *ice) 742static int __devinit pontis_init(struct snd_ice1712 *ice)
743{ 743{
744 static unsigned short wm_inits[] = { 744 static const unsigned short wm_inits[] = {
745 /* These come first to reduce init pop noise */ 745 /* These come first to reduce init pop noise */
746 WM_ADC_MUX, 0x00c0, /* ADC mute */ 746 WM_ADC_MUX, 0x00c0, /* ADC mute */
747 WM_DAC_MUTE, 0x0001, /* DAC softmute */ 747 WM_DAC_MUTE, 0x0001, /* DAC softmute */
@@ -750,7 +750,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice)
750 WM_POWERDOWN, 0x0008, /* All power-up except HP */ 750 WM_POWERDOWN, 0x0008, /* All power-up except HP */
751 WM_RESET, 0x0000, /* reset */ 751 WM_RESET, 0x0000, /* reset */
752 }; 752 };
753 static unsigned short wm_inits2[] = { 753 static const unsigned short wm_inits2[] = {
754 WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */ 754 WM_MASTER_CTRL, 0x0022, /* 256fs, slave mode */
755 WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */ 755 WM_DAC_INT, 0x0022, /* I2S, normal polarity, 24bit */
756 WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */ 756 WM_ADC_INT, 0x0022, /* I2S, normal polarity, 24bit */
@@ -776,7 +776,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice)
776 WM_DAC_MUTE, 0x0000, /* DAC unmute */ 776 WM_DAC_MUTE, 0x0000, /* DAC unmute */
777 WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */ 777 WM_ADC_MUX, 0x0003, /* ADC unmute, both CD/Line On */
778 }; 778 };
779 static unsigned char cs_inits[] = { 779 static const unsigned char cs_inits[] = {
780 0x04, 0x80, /* RUN, RXP0 */ 780 0x04, 0x80, /* RUN, RXP0 */
781 0x05, 0x05, /* slave, 24bit */ 781 0x05, 0x05, /* slave, 24bit */
782 0x01, 0x00, 782 0x01, 0x00,
@@ -826,24 +826,24 @@ static int __devinit pontis_init(struct snd_ice1712 *ice)
826 * hence the driver needs to sets up it properly. 826 * hence the driver needs to sets up it properly.
827 */ 827 */
828 828
829static unsigned char pontis_eeprom[] __devinitdata = { 829static const unsigned char pontis_eeprom[] __devinitdata = {
830 0x08, /* SYSCONF: clock 256, mpu401, spdif-in/ADC, 1DAC */ 830 [ICE_EEP2_SYSCONF] = 0x08, /* clock 256, mpu401, spdif-in/ADC, 1DAC */
831 0x80, /* ACLINK: I2S */ 831 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
832 0xf8, /* I2S: vol, 96k, 24bit, 192k */ 832 [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */
833 0xc3, /* SPDIF: out-en, out-int, spdif-in */ 833 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
834 0x07, /* GPIO_DIR */ 834 [ICE_EEP2_GPIO_DIR] = 0x07,
835 0x00, /* GPIO_DIR1 */ 835 [ICE_EEP2_GPIO_DIR1] = 0x00,
836 0x00, /* GPIO_DIR2 (ignored) */ 836 [ICE_EEP2_GPIO_DIR2] = 0x00, /* ignored */
837 0x0f, /* GPIO_MASK (4-7 reserved for CS8416) */ 837 [ICE_EEP2_GPIO_MASK] = 0x0f, /* 4-7 reserved for CS8416 */
838 0xff, /* GPIO_MASK1 */ 838 [ICE_EEP2_GPIO_MASK1] = 0xff,
839 0x00, /* GPIO_MASK2 (ignored) */ 839 [ICE_EEP2_GPIO_MASK2] = 0x00, /* ignored */
840 0x06, /* GPIO_STATE (0-low, 1-high, 2-high) */ 840 [ICE_EEP2_GPIO_STATE] = 0x06, /* 0-low, 1-high, 2-high */
841 0x00, /* GPIO_STATE1 */ 841 [ICE_EEP2_GPIO_STATE1] = 0x00,
842 0x00, /* GPIO_STATE2 (ignored) */ 842 [ICE_EEP2_GPIO_STATE2] = 0x00, /* ignored */
843}; 843};
844 844
845/* entry point */ 845/* entry point */
846struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = { 846const struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = {
847 { 847 {
848 .subvendor = VT1720_SUBDEVICE_PONTIS_MS300, 848 .subvendor = VT1720_SUBDEVICE_PONTIS_MS300,
849 .name = "Pontis MS300", 849 .name = "Pontis MS300",
diff --git a/sound/pci/ice1712/pontis.h b/sound/pci/ice1712/pontis.h
index d0d1378b935c..1a418255c19e 100644
--- a/sound/pci/ice1712/pontis.h
+++ b/sound/pci/ice1712/pontis.h
@@ -28,6 +28,6 @@
28 28
29#define VT1720_SUBDEVICE_PONTIS_MS300 0x00020002 /* a dummy id for MS300 */ 29#define VT1720_SUBDEVICE_PONTIS_MS300 0x00020002 /* a dummy id for MS300 */
30 30
31extern struct snd_ice1712_card_info snd_vt1720_pontis_cards[]; 31extern const struct snd_ice1712_card_info snd_vt1720_pontis_cards[];
32 32
33#endif /* __SOUND_PONTIS_H */ 33#endif /* __SOUND_PONTIS_H */
diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c
index 41b2605daa3a..31cc66eb9f8f 100644
--- a/sound/pci/ice1712/prodigy192.c
+++ b/sound/pci/ice1712/prodigy192.c
@@ -357,14 +357,14 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl
357} 357}
358#endif 358#endif
359 359
360static DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); 360static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0);
361static DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); 361static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0);
362 362
363/* 363/*
364 * mixers 364 * mixers
365 */ 365 */
366 366
367static struct snd_kcontrol_new stac_controls[] __devinitdata = { 367static const struct snd_kcontrol_new stac_controls[] __devinitdata = {
368 { 368 {
369 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 369 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
370 .name = "Master Playback Switch", 370 .name = "Master Playback Switch",
@@ -475,7 +475,7 @@ static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice)
475 */ 475 */
476static int __devinit prodigy192_init(struct snd_ice1712 *ice) 476static int __devinit prodigy192_init(struct snd_ice1712 *ice)
477{ 477{
478 static unsigned short stac_inits_prodigy[] = { 478 static const unsigned short stac_inits_prodigy[] = {
479 STAC946X_RESET, 0, 479 STAC946X_RESET, 0,
480/* STAC946X_MASTER_VOLUME, 0, 480/* STAC946X_MASTER_VOLUME, 0,
481 STAC946X_LF_VOLUME, 0, 481 STAC946X_LF_VOLUME, 0,
@@ -486,7 +486,7 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)
486 STAC946X_LFE_VOLUME, 0,*/ 486 STAC946X_LFE_VOLUME, 0,*/
487 (unsigned short)-1 487 (unsigned short)-1
488 }; 488 };
489 unsigned short *p; 489 const unsigned short *p;
490 490
491 /* prodigy 192 */ 491 /* prodigy 192 */
492 ice->num_total_dacs = 6; 492 ice->num_total_dacs = 6;
@@ -506,25 +506,25 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice)
506 * hence the driver needs to sets up it properly. 506 * hence the driver needs to sets up it properly.
507 */ 507 */
508 508
509static unsigned char prodigy71_eeprom[] __devinitdata = { 509static const unsigned char prodigy71_eeprom[] __devinitdata = {
510 0x2b, /* SYSCONF: clock 512, mpu401, spdif-in/ADC, 4DACs */ 510 [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC, 4DACs */
511 0x80, /* ACLINK: I2S */ 511 [ICE_EEP2_ACLINK] = 0x80, /* I2S */
512 0xf8, /* I2S: vol, 96k, 24bit, 192k */ 512 [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */
513 0xc3, /* SPDIF: out-en, out-int, spdif-in */ 513 [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */
514 0xff, /* GPIO_DIR */ 514 [ICE_EEP2_GPIO_DIR] = 0xff,
515 0xff, /* GPIO_DIR1 */ 515 [ICE_EEP2_GPIO_DIR1] = 0xff,
516 0xbf, /* GPIO_DIR2 */ 516 [ICE_EEP2_GPIO_DIR2] = 0xbf,
517 0x00, /* GPIO_MASK */ 517 [ICE_EEP2_GPIO_MASK] = 0x00,
518 0x00, /* GPIO_MASK1 */ 518 [ICE_EEP2_GPIO_MASK1] = 0x00,
519 0x00, /* GPIO_MASK2 */ 519 [ICE_EEP2_GPIO_MASK2] = 0x00,
520 0x00, /* GPIO_STATE */ 520 [ICE_EEP2_GPIO_STATE] = 0x00,
521 0x00, /* GPIO_STATE1 */ 521 [ICE_EEP2_GPIO_STATE1] = 0x00,
522 0x00, /* GPIO_STATE2 */ 522 [ICE_EEP2_GPIO_STATE2] = 0x00,
523}; 523};
524 524
525 525
526/* entry point */ 526/* entry point */
527struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { 527const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = {
528 { 528 {
529 .subvendor = VT1724_SUBDEVICE_PRODIGY192VE, 529 .subvendor = VT1724_SUBDEVICE_PRODIGY192VE,
530 .name = "Audiotrak Prodigy 192", 530 .name = "Audiotrak Prodigy 192",
diff --git a/sound/pci/ice1712/prodigy192.h b/sound/pci/ice1712/prodigy192.h
index 94c824e24e06..2fa2e62b9e04 100644
--- a/sound/pci/ice1712/prodigy192.h
+++ b/sound/pci/ice1712/prodigy192.h
@@ -6,6 +6,6 @@
6 6
7#define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */ 7#define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */
8 8
9extern struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[]; 9extern const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[];
10 10
11#endif /* __SOUND_PRODIGY192_H */ 11#endif /* __SOUND_PRODIGY192_H */
diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c
index bf98ea34feb0..025a7e8497c3 100644
--- a/sound/pci/ice1712/revo.c
+++ b/sound/pci/ice1712/revo.c
@@ -84,38 +84,142 @@ static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
84} 84}
85 85
86/* 86/*
87 * I2C access to the PT2258 volume controller on GPIO 6/7 (Revolution 5.1)
88 */
89
90static void revo_i2c_start(struct snd_i2c_bus *bus)
91{
92 struct snd_ice1712 *ice = bus->private_data;
93 snd_ice1712_save_gpio_status(ice);
94}
95
96static void revo_i2c_stop(struct snd_i2c_bus *bus)
97{
98 struct snd_ice1712 *ice = bus->private_data;
99 snd_ice1712_restore_gpio_status(ice);
100}
101
102static void revo_i2c_direction(struct snd_i2c_bus *bus, int clock, int data)
103{
104 struct snd_ice1712 *ice = bus->private_data;
105 unsigned int mask, val;
106
107 val = 0;
108 if (clock)
109 val |= VT1724_REVO_I2C_CLOCK; /* write SCL */
110 if (data)
111 val |= VT1724_REVO_I2C_DATA; /* write SDA */
112 mask = VT1724_REVO_I2C_CLOCK | VT1724_REVO_I2C_DATA;
113 ice->gpio.direction &= ~mask;
114 ice->gpio.direction |= val;
115 snd_ice1712_gpio_set_dir(ice, ice->gpio.direction);
116 snd_ice1712_gpio_set_mask(ice, ~mask);
117}
118
119static void revo_i2c_setlines(struct snd_i2c_bus *bus, int clk, int data)
120{
121 struct snd_ice1712 *ice = bus->private_data;
122 unsigned int val = 0;
123
124 if (clk)
125 val |= VT1724_REVO_I2C_CLOCK;
126 if (data)
127 val |= VT1724_REVO_I2C_DATA;
128 snd_ice1712_gpio_write_bits(ice,
129 VT1724_REVO_I2C_DATA |
130 VT1724_REVO_I2C_CLOCK, val);
131 udelay(5);
132}
133
134static int revo_i2c_getdata(struct snd_i2c_bus *bus, int ack)
135{
136 struct snd_ice1712 *ice = bus->private_data;
137 int bit;
138
139 if (ack)
140 udelay(5);
141 bit = snd_ice1712_gpio_read_bits(ice, VT1724_REVO_I2C_DATA) ? 1 : 0;
142 return bit;
143}
144
145static struct snd_i2c_bit_ops revo51_bit_ops = {
146 .start = revo_i2c_start,
147 .stop = revo_i2c_stop,
148 .direction = revo_i2c_direction,
149 .setlines = revo_i2c_setlines,
150 .getdata = revo_i2c_getdata,
151};
152
153static int revo51_i2c_init(struct snd_ice1712 *ice,
154 struct snd_pt2258 *pt)
155{
156 int err;
157
158 /* create the I2C bus */
159 err = snd_i2c_bus_create(ice->card, "ICE1724 GPIO6", NULL, &ice->i2c);
160 if (err < 0)
161 return err;
162
163 ice->i2c->private_data = ice;
164 ice->i2c->hw_ops.bit = &revo51_bit_ops;
165
166 /* create the I2C device */
167 err = snd_i2c_device_create(ice->i2c, "PT2258", 0x40,
168 &ice->spec.revo51.dev);
169 if (err < 0)
170 return err;
171
172 pt->card = ice->card;
173 pt->i2c_bus = ice->i2c;
174 pt->i2c_dev = ice->spec.revo51.dev;
175 ice->spec.revo51.pt2258 = pt;
176
177 snd_pt2258_reset(pt);
178
179 return 0;
180}
181
182/*
87 * initialize the chips on M-Audio Revolution cards 183 * initialize the chips on M-Audio Revolution cards
88 */ 184 */
89 185
90#define AK_DAC(xname,xch) { .name = xname, .num_channels = xch } 186#define AK_DAC(xname,xch) { .name = xname, .num_channels = xch }
91 187
92static struct snd_akm4xxx_dac_channel revo71_front[] = { 188static const struct snd_akm4xxx_dac_channel revo71_front[] = {
93 AK_DAC("PCM Playback Volume", 2) 189 AK_DAC("PCM Playback Volume", 2)
94}; 190};
95 191
96static struct snd_akm4xxx_dac_channel revo71_surround[] = { 192static const struct snd_akm4xxx_dac_channel revo71_surround[] = {
97 AK_DAC("PCM Center Playback Volume", 1), 193 AK_DAC("PCM Center Playback Volume", 1),
98 AK_DAC("PCM LFE Playback Volume", 1), 194 AK_DAC("PCM LFE Playback Volume", 1),
99 AK_DAC("PCM Side Playback Volume", 2), 195 AK_DAC("PCM Side Playback Volume", 2),
100 AK_DAC("PCM Rear Playback Volume", 2), 196 AK_DAC("PCM Rear Playback Volume", 2),
101}; 197};
102 198
103static struct snd_akm4xxx_dac_channel revo51_dac[] = { 199static const struct snd_akm4xxx_dac_channel revo51_dac[] = {
104 AK_DAC("PCM Playback Volume", 2), 200 AK_DAC("PCM Playback Volume", 2),
105 AK_DAC("PCM Center Playback Volume", 1), 201 AK_DAC("PCM Center Playback Volume", 1),
106 AK_DAC("PCM LFE Playback Volume", 1), 202 AK_DAC("PCM LFE Playback Volume", 1),
107 AK_DAC("PCM Rear Playback Volume", 2), 203 AK_DAC("PCM Rear Playback Volume", 2),
108}; 204};
109 205
110static struct snd_akm4xxx_adc_channel revo51_adc[] = { 206static const char *revo51_adc_input_names[] = {
207 "Mic",
208 "Line",
209 "CD",
210 NULL
211};
212
213static const struct snd_akm4xxx_adc_channel revo51_adc[] = {
111 { 214 {
112 .name = "PCM Capture Volume", 215 .name = "PCM Capture Volume",
113 .switch_name = "PCM Capture Switch", 216 .switch_name = "PCM Capture Switch",
114 .num_channels = 2 217 .num_channels = 2,
218 .input_names = revo51_adc_input_names
115 }, 219 },
116}; 220};
117 221
118static struct snd_akm4xxx akm_revo_front __devinitdata = { 222static const struct snd_akm4xxx akm_revo_front __devinitdata = {
119 .type = SND_AK4381, 223 .type = SND_AK4381,
120 .num_dacs = 2, 224 .num_dacs = 2,
121 .ops = { 225 .ops = {
@@ -124,7 +228,7 @@ static struct snd_akm4xxx akm_revo_front __devinitdata = {
124 .dac_info = revo71_front, 228 .dac_info = revo71_front,
125}; 229};
126 230
127static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { 231static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
128 .caddr = 1, 232 .caddr = 1,
129 .cif = 0, 233 .cif = 0,
130 .data_mask = VT1724_REVO_CDOUT, 234 .data_mask = VT1724_REVO_CDOUT,
@@ -136,7 +240,7 @@ static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = {
136 .mask_flags = 0, 240 .mask_flags = 0,
137}; 241};
138 242
139static struct snd_akm4xxx akm_revo_surround __devinitdata = { 243static const struct snd_akm4xxx akm_revo_surround __devinitdata = {
140 .type = SND_AK4355, 244 .type = SND_AK4355,
141 .idx_offset = 1, 245 .idx_offset = 1,
142 .num_dacs = 6, 246 .num_dacs = 6,
@@ -146,7 +250,7 @@ static struct snd_akm4xxx akm_revo_surround __devinitdata = {
146 .dac_info = revo71_surround, 250 .dac_info = revo71_surround,
147}; 251};
148 252
149static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { 253static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
150 .caddr = 3, 254 .caddr = 3,
151 .cif = 0, 255 .cif = 0,
152 .data_mask = VT1724_REVO_CDOUT, 256 .data_mask = VT1724_REVO_CDOUT,
@@ -158,7 +262,7 @@ static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = {
158 .mask_flags = 0, 262 .mask_flags = 0,
159}; 263};
160 264
161static struct snd_akm4xxx akm_revo51 __devinitdata = { 265static const struct snd_akm4xxx akm_revo51 __devinitdata = {
162 .type = SND_AK4358, 266 .type = SND_AK4358,
163 .num_dacs = 6, 267 .num_dacs = 6,
164 .ops = { 268 .ops = {
@@ -167,36 +271,213 @@ static struct snd_akm4xxx akm_revo51 __devinitdata = {
167 .dac_info = revo51_dac, 271 .dac_info = revo51_dac,
168}; 272};
169 273
170static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { 274static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = {
171 .caddr = 2, 275 .caddr = 2,
172 .cif = 0, 276 .cif = 0,
173 .data_mask = VT1724_REVO_CDOUT, 277 .data_mask = VT1724_REVO_CDOUT,
174 .clk_mask = VT1724_REVO_CCLK, 278 .clk_mask = VT1724_REVO_CCLK,
175 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, 279 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
176 .cs_addr = VT1724_REVO_CS1 | VT1724_REVO_CS2, 280 .cs_addr = VT1724_REVO_CS1,
177 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, 281 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
178 .add_flags = VT1724_REVO_CCLK, /* high at init */ 282 .add_flags = VT1724_REVO_CCLK, /* high at init */
179 .mask_flags = 0, 283 .mask_flags = 0,
180}; 284};
181 285
182static struct snd_akm4xxx akm_revo51_adc __devinitdata = { 286static const struct snd_akm4xxx akm_revo51_adc __devinitdata = {
183 .type = SND_AK5365, 287 .type = SND_AK5365,
184 .num_adcs = 2, 288 .num_adcs = 2,
185 .adc_info = revo51_adc, 289 .adc_info = revo51_adc,
186}; 290};
187 291
188static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { 292static const struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = {
189 .caddr = 2, 293 .caddr = 2,
190 .cif = 0, 294 .cif = 0,
191 .data_mask = VT1724_REVO_CDOUT, 295 .data_mask = VT1724_REVO_CDOUT,
192 .clk_mask = VT1724_REVO_CCLK, 296 .clk_mask = VT1724_REVO_CCLK,
193 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, 297 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS1,
194 .cs_addr = VT1724_REVO_CS0 | VT1724_REVO_CS2, 298 .cs_addr = VT1724_REVO_CS0,
195 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1 | VT1724_REVO_CS2, 299 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS1,
300 .add_flags = VT1724_REVO_CCLK, /* high at init */
301 .mask_flags = 0,
302};
303
304static struct snd_pt2258 ptc_revo51_volume;
305
306/* AK4358 for AP192 DAC, AK5385A for ADC */
307static void ap192_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate)
308{
309 struct snd_ice1712 *ice = ak->private_data[0];
310
311 revo_set_rate_val(ak, rate);
312
313#if 1 /* FIXME: do we need this procedure? */
314 /* reset DFS pin of AK5385A for ADC, too */
315 /* DFS0 (pin 18) -- GPIO10 pin 77 */
316 snd_ice1712_save_gpio_status(ice);
317 snd_ice1712_gpio_write_bits(ice, 1 << 10,
318 rate > 48000 ? (1 << 10) : 0);
319 snd_ice1712_restore_gpio_status(ice);
320#endif
321}
322
323static const struct snd_akm4xxx_dac_channel ap192_dac[] = {
324 AK_DAC("PCM Playback Volume", 2)
325};
326
327static const struct snd_akm4xxx akm_ap192 __devinitdata = {
328 .type = SND_AK4358,
329 .num_dacs = 2,
330 .ops = {
331 .set_rate_val = ap192_set_rate_val
332 },
333 .dac_info = ap192_dac,
334};
335
336static const struct snd_ak4xxx_private akm_ap192_priv __devinitdata = {
337 .caddr = 2,
338 .cif = 0,
339 .data_mask = VT1724_REVO_CDOUT,
340 .clk_mask = VT1724_REVO_CCLK,
341 .cs_mask = VT1724_REVO_CS0 | VT1724_REVO_CS3,
342 .cs_addr = VT1724_REVO_CS3,
343 .cs_none = VT1724_REVO_CS0 | VT1724_REVO_CS3,
196 .add_flags = VT1724_REVO_CCLK, /* high at init */ 344 .add_flags = VT1724_REVO_CCLK, /* high at init */
197 .mask_flags = 0, 345 .mask_flags = 0,
198}; 346};
199 347
348#if 0
349/* FIXME: ak4114 makes the sound much lower due to some confliction,
350 * so let's disable it right now...
351 */
352#define BUILD_AK4114_AP192
353#endif
354
355#ifdef BUILD_AK4114_AP192
356/* AK4114 support on Audiophile 192 */
357/* CDTO (pin 32) -- GPIO2 pin 52
358 * CDTI (pin 33) -- GPIO3 pin 53 (shared with AK4358)
359 * CCLK (pin 34) -- GPIO1 pin 51 (shared with AK4358)
360 * CSN (pin 35) -- GPIO7 pin 59
361 */
362#define AK4114_ADDR 0x00
363
364static void write_data(struct snd_ice1712 *ice, unsigned int gpio,
365 unsigned int data, int idx)
366{
367 for (; idx >= 0; idx--) {
368 /* drop clock */
369 gpio &= ~VT1724_REVO_CCLK;
370 snd_ice1712_gpio_write(ice, gpio);
371 udelay(1);
372 /* set data */
373 if (data & (1 << idx))
374 gpio |= VT1724_REVO_CDOUT;
375 else
376 gpio &= ~VT1724_REVO_CDOUT;
377 snd_ice1712_gpio_write(ice, gpio);
378 udelay(1);
379 /* raise clock */
380 gpio |= VT1724_REVO_CCLK;
381 snd_ice1712_gpio_write(ice, gpio);
382 udelay(1);
383 }
384}
385
386static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio,
387 int idx)
388{
389 unsigned char data = 0;
390
391 for (; idx >= 0; idx--) {
392 /* drop clock */
393 gpio &= ~VT1724_REVO_CCLK;
394 snd_ice1712_gpio_write(ice, gpio);
395 udelay(1);
396 /* read data */
397 if (snd_ice1712_gpio_read(ice) & VT1724_REVO_CDIN)
398 data |= (1 << idx);
399 udelay(1);
400 /* raise clock */
401 gpio |= VT1724_REVO_CCLK;
402 snd_ice1712_gpio_write(ice, gpio);
403 udelay(1);
404 }
405 return data;
406}
407
408static unsigned char ap192_4wire_start(struct snd_ice1712 *ice)
409{
410 unsigned int tmp;
411
412 snd_ice1712_save_gpio_status(ice);
413 tmp = snd_ice1712_gpio_read(ice);
414 tmp |= VT1724_REVO_CCLK; /* high at init */
415 tmp |= VT1724_REVO_CS0;
416 tmp &= ~VT1724_REVO_CS3;
417 snd_ice1712_gpio_write(ice, tmp);
418 udelay(1);
419 return tmp;
420}
421
422static void ap192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp)
423{
424 tmp |= VT1724_REVO_CS3;
425 tmp |= VT1724_REVO_CS0;
426 snd_ice1712_gpio_write(ice, tmp);
427 udelay(1);
428 snd_ice1712_restore_gpio_status(ice);
429}
430
431static void ap192_ak4114_write(void *private_data, unsigned char addr,
432 unsigned char data)
433{
434 struct snd_ice1712 *ice = private_data;
435 unsigned int tmp, addrdata;
436
437 tmp = ap192_4wire_start(ice);
438 addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f);
439 addrdata = (addrdata << 8) | data;
440 write_data(ice, tmp, addrdata, 15);
441 ap192_4wire_finish(ice, tmp);
442}
443
444static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr)
445{
446 struct snd_ice1712 *ice = private_data;
447 unsigned int tmp;
448 unsigned char data;
449
450 tmp = ap192_4wire_start(ice);
451 write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7);
452 data = read_data(ice, tmp, 7);
453 ap192_4wire_finish(ice, tmp);
454 return data;
455}
456
457static int ap192_ak4114_init(struct snd_ice1712 *ice)
458{
459 static const unsigned char ak4114_init_vals[] = {
460 AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1,
461 AK4114_DIF_I24I2S,
462 AK4114_TX1E,
463 AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1),
464 0,
465 0
466 };
467 static const unsigned char ak4114_init_txcsb[] = {
468 0x41, 0x02, 0x2c, 0x00, 0x00
469 };
470 struct ak4114 *ak;
471 int err;
472
473 return snd_ak4114_create(ice->card,
474 ap192_ak4114_read,
475 ap192_ak4114_write,
476 ak4114_init_vals, ak4114_init_txcsb,
477 ice, &ak);
478}
479#endif /* BUILD_AK4114_AP192 */
480
200static int __devinit revo_init(struct snd_ice1712 *ice) 481static int __devinit revo_init(struct snd_ice1712 *ice)
201{ 482{
202 struct snd_akm4xxx *ak; 483 struct snd_akm4xxx *ak;
@@ -213,6 +494,10 @@ static int __devinit revo_init(struct snd_ice1712 *ice)
213 ice->num_total_dacs = 6; 494 ice->num_total_dacs = 6;
214 ice->num_total_adcs = 2; 495 ice->num_total_adcs = 2;
215 break; 496 break;
497 case VT1724_SUBDEVICE_AUDIOPHILE192:
498 ice->num_total_dacs = 2;
499 ice->num_total_adcs = 2;
500 break;
216 default: 501 default:
217 snd_BUG(); 502 snd_BUG();
218 return -EINVAL; 503 return -EINVAL;
@@ -235,14 +520,28 @@ static int __devinit revo_init(struct snd_ice1712 *ice)
235 break; 520 break;
236 case VT1724_SUBDEVICE_REVOLUTION51: 521 case VT1724_SUBDEVICE_REVOLUTION51:
237 ice->akm_codecs = 2; 522 ice->akm_codecs = 2;
238 if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo51, &akm_revo51_priv, ice)) < 0) 523 err = snd_ice1712_akm4xxx_init(ak, &akm_revo51,
524 &akm_revo51_priv, ice);
525 if (err < 0)
239 return err; 526 return err;
240 err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo51_adc, 527 err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo51_adc,
241 &akm_revo51_adc_priv, ice); 528 &akm_revo51_adc_priv, ice);
242 if (err < 0) 529 if (err < 0)
243 return err; 530 return err;
244 /* unmute all codecs - needed! */ 531 err = revo51_i2c_init(ice, &ptc_revo51_volume);
245 snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE); 532 if (err < 0)
533 return err;
534 /* unmute all codecs */
535 snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE,
536 VT1724_REVO_MUTE);
537 break;
538 case VT1724_SUBDEVICE_AUDIOPHILE192:
539 ice->akm_codecs = 1;
540 err = snd_ice1712_akm4xxx_init(ak, &akm_ap192, &akm_ap192_priv,
541 ice);
542 if (err < 0)
543 return err;
544
246 break; 545 break;
247 } 546 }
248 547
@@ -256,16 +555,34 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice)
256 555
257 switch (ice->eeprom.subvendor) { 556 switch (ice->eeprom.subvendor) {
258 case VT1724_SUBDEVICE_REVOLUTION71: 557 case VT1724_SUBDEVICE_REVOLUTION71:
558 err = snd_ice1712_akm4xxx_build_controls(ice);
559 if (err < 0)
560 return err;
561 break;
259 case VT1724_SUBDEVICE_REVOLUTION51: 562 case VT1724_SUBDEVICE_REVOLUTION51:
260 err = snd_ice1712_akm4xxx_build_controls(ice); 563 err = snd_ice1712_akm4xxx_build_controls(ice);
261 if (err < 0) 564 if (err < 0)
262 return err; 565 return err;
566 err = snd_pt2258_build_controls(ice->spec.revo51.pt2258);
567 if (err < 0)
568 return err;
569 break;
570 case VT1724_SUBDEVICE_AUDIOPHILE192:
571 err = snd_ice1712_akm4xxx_build_controls(ice);
572 if (err < 0)
573 return err;
574#ifdef BUILD_AK4114_AP192
575 err = ap192_ak4114_init(ice);
576 if (err < 0)
577 return err;
578#endif
579 break;
263 } 580 }
264 return 0; 581 return 0;
265} 582}
266 583
267/* entry point */ 584/* entry point */
268struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { 585const struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = {
269 { 586 {
270 .subvendor = VT1724_SUBDEVICE_REVOLUTION71, 587 .subvendor = VT1724_SUBDEVICE_REVOLUTION71,
271 .name = "M Audio Revolution-7.1", 588 .name = "M Audio Revolution-7.1",
@@ -280,5 +597,12 @@ struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = {
280 .chip_init = revo_init, 597 .chip_init = revo_init,
281 .build_controls = revo_add_controls, 598 .build_controls = revo_add_controls,
282 }, 599 },
600 {
601 .subvendor = VT1724_SUBDEVICE_AUDIOPHILE192,
602 .name = "M Audio Audiophile192",
603 .model = "ap192",
604 .chip_init = revo_init,
605 .build_controls = revo_add_controls,
606 },
283 { } /* terminator */ 607 { } /* terminator */
284}; 608};
diff --git a/sound/pci/ice1712/revo.h b/sound/pci/ice1712/revo.h
index efbb86ec3289..2a24488fad80 100644
--- a/sound/pci/ice1712/revo.h
+++ b/sound/pci/ice1712/revo.h
@@ -26,13 +26,15 @@
26 26
27#define REVO_DEVICE_DESC \ 27#define REVO_DEVICE_DESC \
28 "{MidiMan M Audio,Revolution 7.1},"\ 28 "{MidiMan M Audio,Revolution 7.1},"\
29 "{MidiMan M Audio,Revolution 5.1}," 29 "{MidiMan M Audio,Revolution 5.1},"\
30 "{MidiMan M Audio,Audiophile 192},"
30 31
31#define VT1724_SUBDEVICE_REVOLUTION71 0x12143036 32#define VT1724_SUBDEVICE_REVOLUTION71 0x12143036
32#define VT1724_SUBDEVICE_REVOLUTION51 0x12143136 33#define VT1724_SUBDEVICE_REVOLUTION51 0x12143136
34#define VT1724_SUBDEVICE_AUDIOPHILE192 0x12143236
33 35
34/* entry point */ 36/* entry point */
35extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; 37extern const struct snd_ice1712_card_info snd_vt1724_revo_cards[];
36 38
37 39
38/* 40/*
@@ -42,9 +44,12 @@ extern struct snd_ice1712_card_info snd_vt1724_revo_cards[];
42#define VT1724_REVO_CCLK 0x02 44#define VT1724_REVO_CCLK 0x02
43#define VT1724_REVO_CDIN 0x04 /* not used */ 45#define VT1724_REVO_CDIN 0x04 /* not used */
44#define VT1724_REVO_CDOUT 0x08 46#define VT1724_REVO_CDOUT 0x08
45#define VT1724_REVO_CS0 0x10 /* AK5365 chipselect for Rev. 5.1 */ 47#define VT1724_REVO_CS0 0x10 /* AK5365 chipselect for (revo51) */
46#define VT1724_REVO_CS1 0x20 /* front AKM4381 chipselect */ 48#define VT1724_REVO_CS1 0x20 /* front AKM4381 chipselect */
47#define VT1724_REVO_CS2 0x40 /* surround AKM4355 chipselect */ 49#define VT1724_REVO_CS2 0x40 /* surround AKM4355 CS (revo71) */
50#define VT1724_REVO_I2C_DATA 0x40 /* I2C: PT 2258 SDA (on revo51) */
51#define VT1724_REVO_I2C_CLOCK 0x80 /* I2C: PT 2258 SCL (on revo51) */
52#define VT1724_REVO_CS3 0x80 /* AK4114 for AP192 */
48#define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */ 53#define VT1724_REVO_MUTE (1<<22) /* 0 = all mute, 1 = normal operation */
49 54
50#endif /* __SOUND_REVO_H */ 55#endif /* __SOUND_REVO_H */
diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c
index 7ca263c13091..72b060d63c29 100644
--- a/sound/pci/ice1712/vt1720_mobo.c
+++ b/sound/pci/ice1712/vt1720_mobo.c
@@ -30,6 +30,7 @@
30#include <sound/core.h> 30#include <sound/core.h>
31 31
32#include "ice1712.h" 32#include "ice1712.h"
33#include "envy24ht.h"
33#include "vt1720_mobo.h" 34#include "vt1720_mobo.h"
34 35
35 36
@@ -55,41 +56,41 @@ static int __devinit k8x800_add_controls(struct snd_ice1712 *ice)
55 56
56/* EEPROM image */ 57/* EEPROM image */
57 58
58static unsigned char k8x800_eeprom[] __devinitdata = { 59static const unsigned char k8x800_eeprom[] __devinitdata = {
59 0x01, /* SYSCONF: clock 256, 1ADC, 2DACs */ 60 [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */
60 0x02, /* ACLINK: ACLINK, packed */ 61 [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */
61 0x00, /* I2S: - */ 62 [ICE_EEP2_I2S] = 0x00, /* - */
62 0x00, /* SPDIF: - */ 63 [ICE_EEP2_SPDIF] = 0x00, /* - */
63 0xff, /* GPIO_DIR */ 64 [ICE_EEP2_GPIO_DIR] = 0xff,
64 0xff, /* GPIO_DIR1 */ 65 [ICE_EEP2_GPIO_DIR1] = 0xff,
65 0x00, /* - */ 66 [ICE_EEP2_GPIO_DIR2] = 0x00, /* - */
66 0xff, /* GPIO_MASK */ 67 [ICE_EEP2_GPIO_MASK] = 0xff,
67 0xff, /* GPIO_MASK1 */ 68 [ICE_EEP2_GPIO_MASK1] = 0xff,
68 0x00, /* - */ 69 [ICE_EEP2_GPIO_MASK2] = 0x00, /* - */
69 0x00, /* GPIO_STATE */ 70 [ICE_EEP2_GPIO_STATE] = 0x00,
70 0x00, /* GPIO_STATE1 */ 71 [ICE_EEP2_GPIO_STATE1] = 0x00,
71 0x00, /* - */ 72 [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */
72}; 73};
73 74
74static unsigned char sn25p_eeprom[] __devinitdata = { 75static const unsigned char sn25p_eeprom[] __devinitdata = {
75 0x01, /* SYSCONF: clock 256, 1ADC, 2DACs */ 76 [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */
76 0x02, /* ACLINK: ACLINK, packed */ 77 [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */
77 0x00, /* I2S: - */ 78 [ICE_EEP2_I2S] = 0x00, /* - */
78 0x41, /* SPDIF: - */ 79 [ICE_EEP2_SPDIF] = 0x41, /* - */
79 0xff, /* GPIO_DIR */ 80 [ICE_EEP2_GPIO_DIR] = 0xff,
80 0xff, /* GPIO_DIR1 */ 81 [ICE_EEP2_GPIO_DIR1] = 0xff,
81 0x00, /* - */ 82 [ICE_EEP2_GPIO_DIR2] = 0x00, /* - */
82 0xff, /* GPIO_MASK */ 83 [ICE_EEP2_GPIO_MASK] = 0xff,
83 0xff, /* GPIO_MASK1 */ 84 [ICE_EEP2_GPIO_MASK1] = 0xff,
84 0x00, /* - */ 85 [ICE_EEP2_GPIO_MASK2] = 0x00, /* - */
85 0x00, /* GPIO_STATE */ 86 [ICE_EEP2_GPIO_STATE] = 0x00,
86 0x00, /* GPIO_STATE1 */ 87 [ICE_EEP2_GPIO_STATE1] = 0x00,
87 0x00, /* - */ 88 [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */
88}; 89};
89 90
90 91
91/* entry point */ 92/* entry point */
92struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { 93const struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = {
93 { 94 {
94 .subvendor = VT1720_SUBDEVICE_K8X800, 95 .subvendor = VT1720_SUBDEVICE_K8X800,
95 .name = "Albatron K8X800 Pro II", 96 .name = "Albatron K8X800 Pro II",
diff --git a/sound/pci/ice1712/vt1720_mobo.h b/sound/pci/ice1712/vt1720_mobo.h
index 0b1b0ee1bea7..70af3ad64a5d 100644
--- a/sound/pci/ice1712/vt1720_mobo.h
+++ b/sound/pci/ice1712/vt1720_mobo.h
@@ -36,6 +36,6 @@
36#define VT1720_SUBDEVICE_9CJS 0x0f272327 36#define VT1720_SUBDEVICE_9CJS 0x0f272327
37#define VT1720_SUBDEVICE_SN25P 0x97123650 37#define VT1720_SUBDEVICE_SN25P 0x97123650
38 38
39extern struct snd_ice1712_card_info snd_vt1720_mobo_cards[]; 39extern const struct snd_ice1712_card_info snd_vt1720_mobo_cards[];
40 40
41#endif /* __SOUND_VT1720_MOBO_H */ 41#endif /* __SOUND_VT1720_MOBO_H */
diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c
new file mode 100644
index 000000000000..4a706b16a0b9
--- /dev/null
+++ b/sound/pci/ice1712/wtm.c
@@ -0,0 +1,542 @@
1/*
2 * ALSA driver for ICEnsemble VT1724 (Envy24HT)
3 *
4 * Lowlevel functions for Ego Sys Waveterminal 192M
5 *
6 * Copyright (c) 2006 Guedez Clement <klem.dev@gmail.com>
7 * Some functions are taken from the Prodigy192 driver
8 * source
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26
27
28#include <sound/driver.h>
29#include <asm/io.h>
30#include <linux/delay.h>
31#include <linux/interrupt.h>
32#include <linux/init.h>
33#include <linux/slab.h>
34#include <sound/core.h>
35
36#include "ice1712.h"
37#include "envy24ht.h"
38#include "wtm.h"
39#include "stac946x.h"
40
41
42/*
43 * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus
44 */
45static inline void stac9460_put(struct snd_ice1712 *ice, int reg,
46 unsigned char val)
47{
48 snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val);
49}
50
51static inline unsigned char stac9460_get(struct snd_ice1712 *ice, int reg)
52{
53 return snd_vt1724_read_i2c(ice, STAC9460_I2C_ADDR, reg);
54}
55
56/*
57 * 2*ADC 2*DAC no2 ringbuffer r/w on i2c bus
58 */
59static inline void stac9460_2_put(struct snd_ice1712 *ice, int reg,
60 unsigned char val)
61{
62 snd_vt1724_write_i2c(ice, STAC9460_2_I2C_ADDR, reg, val);
63}
64
65static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg)
66{
67 return snd_vt1724_read_i2c(ice, STAC9460_2_I2C_ADDR, reg);
68}
69
70
71/*
72 * DAC mute control
73 */
74static int stac9460_dac_mute_info(struct snd_kcontrol *kcontrol,
75 struct snd_ctl_elem_info *uinfo)
76{
77 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
78 uinfo->count = 1;
79 uinfo->value.integer.min = 0;
80 return 0;
81}
82
83static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol,
84 struct snd_ctl_elem_value *ucontrol)
85{
86 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
87 unsigned char val;
88 int idx, id;
89
90 if (kcontrol->private_value) {
91 idx = STAC946X_MASTER_VOLUME;
92 id = 0;
93 } else {
94 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
95 idx = id + STAC946X_LF_VOLUME;
96 }
97 if (id < 6)
98 val = stac9460_get(ice, idx);
99 else
100 val = stac9460_2_get(ice,idx - 6);
101 ucontrol->value.integer.value[0] = (~val >> 7) & 0x1;
102 return 0;
103}
104
105static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol,
106 struct snd_ctl_elem_value *ucontrol)
107{
108 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
109 unsigned char new, old;
110 int id, idx;
111 int change;
112
113 if (kcontrol->private_value) {
114 idx = STAC946X_MASTER_VOLUME;
115 old = stac9460_get(ice, idx);
116 new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) |
117 (old & ~0x80);
118 change = (new != old);
119 if (change) {
120 stac9460_put(ice, idx, new);
121 stac9460_2_put(ice, idx, new);
122 }
123 } else {
124 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
125 idx = id + STAC946X_LF_VOLUME;
126 if (id < 6)
127 old = stac9460_get(ice, idx);
128 else
129 old = stac9460_2_get(ice, idx - 6);
130 new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) |
131 (old & ~0x80);
132 change = (new != old);
133 if (change) {
134 if (id < 6)
135 stac9460_put(ice, idx, new);
136 else
137 stac9460_2_put(ice, idx - 6, new);
138 }
139 }
140 return change;
141}
142
143/*
144 * DAC volume attenuation mixer control
145 */
146static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol,
147 struct snd_ctl_elem_info *uinfo)
148{
149 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
150 uinfo->count = 1;
151 uinfo->value.integer.min = 0; /* mute */
152 uinfo->value.integer.max = 0x7f; /* 0dB */
153 return 0;
154}
155
156static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol,
157 struct snd_ctl_elem_value *ucontrol)
158{
159 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
160 int idx, id;
161 unsigned char vol;
162
163 if (kcontrol->private_value) {
164 idx = STAC946X_MASTER_VOLUME;
165 id = 0;
166 } else {
167 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
168 idx = id + STAC946X_LF_VOLUME;
169 }
170 if (id < 6)
171 vol = stac9460_get(ice, idx) & 0x7f;
172 else
173 vol = stac9460_2_get(ice, idx - 6) & 0x7f;
174 ucontrol->value.integer.value[0] = 0x7f - vol;
175 return 0;
176}
177
178static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol,
179 struct snd_ctl_elem_value *ucontrol)
180{
181 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
182 int idx, id;
183 unsigned char tmp, ovol, nvol;
184 int change;
185
186 if (kcontrol->private_value) {
187 idx = STAC946X_MASTER_VOLUME;
188 nvol = ucontrol->value.integer.value[0];
189 tmp = stac9460_get(ice, idx);
190 ovol = 0x7f - (tmp & 0x7f);
191 change = (ovol != nvol);
192 if (change) {
193 stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
194 stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80));
195 }
196 } else {
197 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
198 idx = id + STAC946X_LF_VOLUME;
199 nvol = ucontrol->value.integer.value[0];
200 if (id < 6)
201 tmp = stac9460_get(ice, idx);
202 else
203 tmp = stac9460_2_get(ice, idx - 6);
204 ovol = 0x7f - (tmp & 0x7f);
205 change = (ovol != nvol);
206 if (change) {
207 if (id < 6)
208 stac9460_put(ice, idx, (0x7f - nvol) |
209 (tmp & 0x80));
210 else
211 stac9460_2_put(ice, idx-6, (0x7f - nvol) |
212 (tmp & 0x80));
213 }
214 }
215 return change;
216}
217
218/*
219 * ADC mute control
220 */
221static int stac9460_adc_mute_info(struct snd_kcontrol *kcontrol,
222 struct snd_ctl_elem_info *uinfo)
223{
224 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
225 uinfo->count = 2;
226 uinfo->value.integer.min = 0;
227 uinfo->value.integer.max = 1;
228 return 0;
229}
230
231static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol,
232 struct snd_ctl_elem_value *ucontrol)
233{
234 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
235 unsigned char val;
236 int i, id;
237
238 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
239 if (id == 0) {
240 for (i = 0; i < 2; ++i) {
241 val = stac9460_get(ice, STAC946X_MIC_L_VOLUME + i);
242 ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
243 }
244 } else {
245 for (i = 0; i < 2; ++i) {
246 val = stac9460_2_get(ice, STAC946X_MIC_L_VOLUME + i);
247 ucontrol->value.integer.value[i] = ~val>>7 & 0x1;
248 }
249 }
250 return 0;
251}
252
253static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol,
254 struct snd_ctl_elem_value *ucontrol)
255{
256 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
257 unsigned char new, old;
258 int i, reg, id;
259 int change;
260
261 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
262 if (id == 0) {
263 for (i = 0; i < 2; ++i) {
264 reg = STAC946X_MIC_L_VOLUME + i;
265 old = stac9460_get(ice, reg);
266 new = (~ucontrol->value.integer.value[i]<<7&0x80) |
267 (old&~0x80);
268 change = (new != old);
269 if (change)
270 stac9460_put(ice, reg, new);
271 }
272 } else {
273 for (i = 0; i < 2; ++i) {
274 reg = STAC946X_MIC_L_VOLUME + i;
275 old = stac9460_2_get(ice, reg);
276 new = (~ucontrol->value.integer.value[i]<<7&0x80) |
277 (old&~0x80);
278 change = (new != old);
279 if (change)
280 stac9460_2_put(ice, reg, new);
281 }
282 }
283 return change;
284}
285
286/*
287 *ADC gain mixer control
288 */
289static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol,
290 struct snd_ctl_elem_info *uinfo)
291{
292 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
293 uinfo->count = 2;
294 uinfo->value.integer.min = 0; /* 0dB */
295 uinfo->value.integer.max = 0x0f; /* 22.5dB */
296 return 0;
297}
298
299static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol,
300 struct snd_ctl_elem_value *ucontrol)
301{
302 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
303 int i, reg, id;
304 unsigned char vol;
305
306 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
307 if (id == 0) {
308 for (i = 0; i < 2; ++i) {
309 reg = STAC946X_MIC_L_VOLUME + i;
310 vol = stac9460_get(ice, reg) & 0x0f;
311 ucontrol->value.integer.value[i] = 0x0f - vol;
312 }
313 } else {
314 for (i = 0; i < 2; ++i) {
315 reg = STAC946X_MIC_L_VOLUME + i;
316 vol = stac9460_2_get(ice, reg) & 0x0f;
317 ucontrol->value.integer.value[i] = 0x0f - vol;
318 }
319 }
320 return 0;
321}
322
323static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol,
324 struct snd_ctl_elem_value *ucontrol)
325{
326 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
327 int i, reg, id;
328 unsigned char ovol, nvol;
329 int change;
330
331 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
332 if (id == 0) {
333 for (i = 0; i < 2; ++i) {
334 reg = STAC946X_MIC_L_VOLUME + i;
335 nvol = ucontrol->value.integer.value[i];
336 ovol = 0x0f - stac9460_get(ice, reg);
337 change = ((ovol & 0x0f) != nvol);
338 if (change)
339 stac9460_put(ice, reg, (0x0f - nvol) |
340 (ovol & ~0x0f));
341 }
342 } else {
343 for (i = 0; i < 2; ++i) {
344 reg = STAC946X_MIC_L_VOLUME + i;
345 nvol = ucontrol->value.integer.value[i];
346 ovol = 0x0f - stac9460_2_get(ice, reg);
347 change = ((ovol & 0x0f) != nvol);
348 if (change)
349 stac9460_2_put(ice, reg, (0x0f - nvol) |
350 (ovol & ~0x0f));
351 }
352 }
353 return change;
354}
355
356/*
357 * MIC / LINE switch fonction
358 */
359
360static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol,
361 struct snd_ctl_elem_info *uinfo)
362{
363 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
364 uinfo->count = 1;
365 uinfo->value.integer.min = 0;
366 uinfo->value.integer.max = 1;
367 return 0;
368}
369
370static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol,
371 struct snd_ctl_elem_value *ucontrol)
372{
373 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
374 unsigned char val;
375 int id;
376
377 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
378 if (id == 0)
379 val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
380 else
381 val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
382 ucontrol->value.integer.value[0] = ~val>>7 & 0x1;
383 return 0;
384}
385
386static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol,
387 struct snd_ctl_elem_value *ucontrol)
388{
389 struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol);
390 unsigned char new, old;
391 int change, id;
392
393 id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
394 if (id == 0)
395 old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE);
396 else
397 old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE);
398 new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | (old & ~0x80);
399 change = (new != old);
400 if (change) {
401 if (id == 0)
402 stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new);
403 else
404 stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new);
405 }
406 return change;
407}
408
409/*
410 * Control tabs
411 */
412static const struct snd_kcontrol_new stac9640_controls[] __devinitdata = {
413 {
414 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
415 .name = "Master Playback Switch",
416 .info = stac9460_dac_mute_info,
417 .get = stac9460_dac_mute_get,
418 .put = stac9460_dac_mute_put,
419 .private_value = 1
420 },
421 {
422 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
423 .name = "Master Playback Volume",
424 .info = stac9460_dac_vol_info,
425 .get = stac9460_dac_vol_get,
426 .put = stac9460_dac_vol_put,
427 .private_value = 1,
428 },
429 {
430 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
431 .name = "MIC/Line switch",
432 .count = 2,
433 .info = stac9460_mic_sw_info,
434 .get = stac9460_mic_sw_get,
435 .put = stac9460_mic_sw_put,
436
437 },
438 {
439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
440 .name = "DAC Switch",
441 .count = 8,
442 .info = stac9460_dac_mute_info,
443 .get = stac9460_dac_mute_get,
444 .put = stac9460_dac_mute_put,
445 },
446 {
447 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
448 .name = "DAC Volume",
449 .count = 8,
450 .info = stac9460_dac_vol_info,
451 .get = stac9460_dac_vol_get,
452 .put = stac9460_dac_vol_put,
453 },
454 {
455 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
456 .name = "ADC Switch",
457 .count = 2,
458 .info = stac9460_adc_mute_info,
459 .get = stac9460_adc_mute_get,
460 .put = stac9460_adc_mute_put,
461 },
462 {
463 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
464 .name = "ADC Volume",
465 .count = 2,
466 .info = stac9460_adc_vol_info,
467 .get = stac9460_adc_vol_get,
468 .put = stac9460_adc_vol_put,
469
470 }
471};
472
473
474
475/*INIT*/
476static int __devinit wtm_add_controls(struct snd_ice1712 *ice)
477{
478 unsigned int i;
479 int err;
480
481 for (i = 0; i < ARRAY_SIZE(stac9640_controls); i++) {
482 err = snd_ctl_add(ice->card,
483 snd_ctl_new1(&stac9640_controls[i], ice));
484 if (err < 0)
485 return err;
486 }
487 return 0;
488}
489
490static int __devinit wtm_init(struct snd_ice1712 *ice)
491{
492 static unsigned short stac_inits_prodigy[] = {
493 STAC946X_RESET, 0,
494 (unsigned short)-1
495 };
496 unsigned short *p;
497
498 /*WTM 192M*/
499 ice->num_total_dacs = 8;
500 ice->num_total_adcs = 4;
501 ice->force_rdma1 = 1;
502
503 /*initialize codec*/
504 p = stac_inits_prodigy;
505 for (; *p != (unsigned short)-1; p += 2) {
506 stac9460_put(ice, p[0], p[1]);
507 stac9460_2_put(ice, p[0], p[1]);
508 }
509 return 0;
510}
511
512
513static unsigned char wtm_eeprom[] __devinitdata = {
514 0x47, /*SYSCONF: clock 192KHz, 4ADC, 8DAC */
515 0x80, /* ACLINK : I2S */
516 0xf8, /* I2S: vol; 96k, 24bit, 192k */
517 0xc1 /*SPDIF: out-en, spidf ext out*/,
518 0x9f, /* GPIO_DIR */
519 0xff, /* GPIO_DIR1 */
520 0x7f, /* GPIO_DIR2 */
521 0x9f, /* GPIO_MASK */
522 0xff, /* GPIO_MASK1 */
523 0x7f, /* GPIO_MASK2 */
524 0x16, /* GPIO_STATE */
525 0x80, /* GPIO_STATE1 */
526 0x00, /* GPIO_STATE2 */
527};
528
529
530/*entry point*/
531struct snd_ice1712_card_info snd_vt1724_wtm_cards[] __devinitdata = {
532 {
533 .subvendor = VT1724_SUBDEVICE_WTM,
534 .name = "ESI Waveterminal 192M",
535 .model = "WT192M",
536 .chip_init = wtm_init,
537 .build_controls = wtm_add_controls,
538 .eeprom_size = sizeof(wtm_eeprom),
539 .eeprom_data = wtm_eeprom,
540 },
541 {} /*terminator*/
542};
diff --git a/sound/pci/ice1712/wtm.h b/sound/pci/ice1712/wtm.h
new file mode 100644
index 000000000000..03a394e442f1
--- /dev/null
+++ b/sound/pci/ice1712/wtm.h
@@ -0,0 +1,20 @@
1#ifndef __SOUND_WTM_H
2#define __SOUND_WTM_H
3
4/* ID */
5#define WTM_DEVICE_DESC "{EGO SYS INC,WaveTerminal 192M},"
6#define VT1724_SUBDEVICE_WTM 0x36495345 /* WT192M ver1.0 */
7
8/*
9 *chip addresses on I2C bus
10 */
11
12#define AK4114_ADDR 0x20 /*S/PDIF receiver*/
13#define STAC9460_I2C_ADDR 0x54 /* ADC*2 | DAC*6 */
14#define STAC9460_2_I2C_ADDR 0x56 /* ADC|DAC *2 */
15
16
17extern struct snd_ice1712_card_info snd_vt1724_wtm_cards[];
18
19#endif /* __SOUND_WTM_H */
20
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 30aaa6092a84..a289abfc7172 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -71,6 +71,7 @@ static char *ac97_quirk;
71static int buggy_semaphore; 71static int buggy_semaphore;
72static int buggy_irq = -1; /* auto-check */ 72static int buggy_irq = -1; /* auto-check */
73static int xbox; 73static int xbox;
74static int spdif_aclink = -1;
74 75
75module_param(index, int, 0444); 76module_param(index, int, 0444);
76MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); 77MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard.");
@@ -86,6 +87,8 @@ module_param(buggy_irq, bool, 0444);
86MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards."); 87MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
87module_param(xbox, bool, 0444); 88module_param(xbox, bool, 0444);
88MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection."); 89MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection.");
90module_param(spdif_aclink, int, 0444);
91MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
89 92
90/* just for backward compatibility */ 93/* just for backward compatibility */
91static int enable; 94static int enable;
@@ -368,12 +371,8 @@ struct intel8x0 {
368 371
369 int irq; 372 int irq;
370 373
371 unsigned int mmio; 374 void __iomem *addr;
372 unsigned long addr; 375 void __iomem *bmaddr;
373 void __iomem *remap_addr;
374 unsigned int bm_mmio;
375 unsigned long bmaddr;
376 void __iomem *remap_bmaddr;
377 376
378 struct pci_dev *pci; 377 struct pci_dev *pci;
379 struct snd_card *card; 378 struct snd_card *card;
@@ -446,72 +445,48 @@ MODULE_DEVICE_TABLE(pci, snd_intel8x0_ids);
446 * Lowlevel I/O - busmaster 445 * Lowlevel I/O - busmaster
447 */ 446 */
448 447
449static u8 igetbyte(struct intel8x0 *chip, u32 offset) 448static inline u8 igetbyte(struct intel8x0 *chip, u32 offset)
450{ 449{
451 if (chip->bm_mmio) 450 return ioread8(chip->bmaddr + offset);
452 return readb(chip->remap_bmaddr + offset);
453 else
454 return inb(chip->bmaddr + offset);
455} 451}
456 452
457static u16 igetword(struct intel8x0 *chip, u32 offset) 453static inline u16 igetword(struct intel8x0 *chip, u32 offset)
458{ 454{
459 if (chip->bm_mmio) 455 return ioread16(chip->bmaddr + offset);
460 return readw(chip->remap_bmaddr + offset);
461 else
462 return inw(chip->bmaddr + offset);
463} 456}
464 457
465static u32 igetdword(struct intel8x0 *chip, u32 offset) 458static inline u32 igetdword(struct intel8x0 *chip, u32 offset)
466{ 459{
467 if (chip->bm_mmio) 460 return ioread32(chip->bmaddr + offset);
468 return readl(chip->remap_bmaddr + offset);
469 else
470 return inl(chip->bmaddr + offset);
471} 461}
472 462
473static void iputbyte(struct intel8x0 *chip, u32 offset, u8 val) 463static inline void iputbyte(struct intel8x0 *chip, u32 offset, u8 val)
474{ 464{
475 if (chip->bm_mmio) 465 iowrite8(val, chip->bmaddr + offset);
476 writeb(val, chip->remap_bmaddr + offset);
477 else
478 outb(val, chip->bmaddr + offset);
479} 466}
480 467
481static void iputword(struct intel8x0 *chip, u32 offset, u16 val) 468static inline void iputword(struct intel8x0 *chip, u32 offset, u16 val)
482{ 469{
483 if (chip->bm_mmio) 470 iowrite16(val, chip->bmaddr + offset);
484 writew(val, chip->remap_bmaddr + offset);
485 else
486 outw(val, chip->bmaddr + offset);
487} 471}
488 472
489static void iputdword(struct intel8x0 *chip, u32 offset, u32 val) 473static inline void iputdword(struct intel8x0 *chip, u32 offset, u32 val)
490{ 474{
491 if (chip->bm_mmio) 475 iowrite32(val, chip->bmaddr + offset);
492 writel(val, chip->remap_bmaddr + offset);
493 else
494 outl(val, chip->bmaddr + offset);
495} 476}
496 477
497/* 478/*
498 * Lowlevel I/O - AC'97 registers 479 * Lowlevel I/O - AC'97 registers
499 */ 480 */
500 481
501static u16 iagetword(struct intel8x0 *chip, u32 offset) 482static inline u16 iagetword(struct intel8x0 *chip, u32 offset)
502{ 483{
503 if (chip->mmio) 484 return ioread16(chip->addr + offset);
504 return readw(chip->remap_addr + offset);
505 else
506 return inw(chip->addr + offset);
507} 485}
508 486
509static void iaputword(struct intel8x0 *chip, u32 offset, u16 val) 487static inline void iaputword(struct intel8x0 *chip, u32 offset, u16 val)
510{ 488{
511 if (chip->mmio) 489 iowrite16(val, chip->addr + offset);
512 writew(val, chip->remap_addr + offset);
513 else
514 outw(val, chip->addr + offset);
515} 490}
516 491
517/* 492/*
@@ -1606,10 +1581,14 @@ static int __devinit snd_intel8x0_pcm(struct intel8x0 *chip)
1606 case DEVICE_INTEL_ICH4: 1581 case DEVICE_INTEL_ICH4:
1607 tbl = intel_pcms; 1582 tbl = intel_pcms;
1608 tblsize = ARRAY_SIZE(intel_pcms); 1583 tblsize = ARRAY_SIZE(intel_pcms);
1584 if (spdif_aclink)
1585 tblsize--;
1609 break; 1586 break;
1610 case DEVICE_NFORCE: 1587 case DEVICE_NFORCE:
1611 tbl = nforce_pcms; 1588 tbl = nforce_pcms;
1612 tblsize = ARRAY_SIZE(nforce_pcms); 1589 tblsize = ARRAY_SIZE(nforce_pcms);
1590 if (spdif_aclink)
1591 tblsize--;
1613 break; 1592 break;
1614 case DEVICE_ALI: 1593 case DEVICE_ALI:
1615 tbl = ali_pcms; 1594 tbl = ali_pcms;
@@ -2068,24 +2047,26 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
2068 }; 2047 };
2069 2048
2070 chip->spdif_idx = -1; /* use PCMOUT (or disabled) */ 2049 chip->spdif_idx = -1; /* use PCMOUT (or disabled) */
2071 switch (chip->device_type) { 2050 if (!spdif_aclink) {
2072 case DEVICE_NFORCE: 2051 switch (chip->device_type) {
2073 chip->spdif_idx = NVD_SPBAR; 2052 case DEVICE_NFORCE:
2074 break; 2053 chip->spdif_idx = NVD_SPBAR;
2075 case DEVICE_ALI: 2054 break;
2076 chip->spdif_idx = ALID_AC97SPDIFOUT; 2055 case DEVICE_ALI:
2077 break; 2056 chip->spdif_idx = ALID_AC97SPDIFOUT;
2078 case DEVICE_INTEL_ICH4: 2057 break;
2079 chip->spdif_idx = ICHD_SPBAR; 2058 case DEVICE_INTEL_ICH4:
2080 break; 2059 chip->spdif_idx = ICHD_SPBAR;
2081 }; 2060 break;
2061 };
2062 }
2082 2063
2083 chip->in_ac97_init = 1; 2064 chip->in_ac97_init = 1;
2084 2065
2085 memset(&ac97, 0, sizeof(ac97)); 2066 memset(&ac97, 0, sizeof(ac97));
2086 ac97.private_data = chip; 2067 ac97.private_data = chip;
2087 ac97.private_free = snd_intel8x0_mixer_free_ac97; 2068 ac97.private_free = snd_intel8x0_mixer_free_ac97;
2088 ac97.scaps = AC97_SCAP_SKIP_MODEM; 2069 ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
2089 if (chip->xbox) 2070 if (chip->xbox)
2090 ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR; 2071 ac97.scaps |= AC97_SCAP_DETECT_BY_VENDOR;
2091 if (chip->device_type != DEVICE_ALI) { 2072 if (chip->device_type != DEVICE_ALI) {
@@ -2201,11 +2182,11 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock,
2201 if ((igetdword(chip, ICHREG(GLOB_STA)) & ICH_SAMPLE_CAP) == ICH_SAMPLE_16_20) 2182 if ((igetdword(chip, ICHREG(GLOB_STA)) & ICH_SAMPLE_CAP) == ICH_SAMPLE_16_20)
2202 chip->smp20bit = 1; 2183 chip->smp20bit = 1;
2203 } 2184 }
2204 if (chip->device_type == DEVICE_NFORCE) { 2185 if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) {
2205 /* 48kHz only */ 2186 /* 48kHz only */
2206 chip->ichd[chip->spdif_idx].pcm->rates = SNDRV_PCM_RATE_48000; 2187 chip->ichd[chip->spdif_idx].pcm->rates = SNDRV_PCM_RATE_48000;
2207 } 2188 }
2208 if (chip->device_type == DEVICE_INTEL_ICH4) { 2189 if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) {
2209 /* use slot 10/11 for SPDIF */ 2190 /* use slot 10/11 for SPDIF */
2210 u32 val; 2191 u32 val;
2211 val = igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK; 2192 val = igetdword(chip, ICHREG(GLOB_CNT)) & ~ICH_PCM_SPDIF_MASK;
@@ -2333,7 +2314,7 @@ static int snd_intel8x0_ich_chip_init(struct intel8x0 *chip, int probing)
2333 /* unmute the output on SIS7012 */ 2314 /* unmute the output on SIS7012 */
2334 iputword(chip, 0x4c, igetword(chip, 0x4c) | 1); 2315 iputword(chip, 0x4c, igetword(chip, 0x4c) | 1);
2335 } 2316 }
2336 if (chip->device_type == DEVICE_NFORCE) { 2317 if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) {
2337 /* enable SPDIF interrupt */ 2318 /* enable SPDIF interrupt */
2338 unsigned int val; 2319 unsigned int val;
2339 pci_read_config_dword(chip->pci, 0x4c, &val); 2320 pci_read_config_dword(chip->pci, 0x4c, &val);
@@ -2426,7 +2407,7 @@ static int snd_intel8x0_free(struct intel8x0 *chip)
2426 /* reset channels */ 2407 /* reset channels */
2427 for (i = 0; i < chip->bdbars_count; i++) 2408 for (i = 0; i < chip->bdbars_count; i++)
2428 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS); 2409 iputbyte(chip, ICH_REG_OFF_CR + chip->ichd[i].reg_offset, ICH_RESETREGS);
2429 if (chip->device_type == DEVICE_NFORCE) { 2410 if (chip->device_type == DEVICE_NFORCE && !spdif_aclink) {
2430 /* stop the spdif interrupt */ 2411 /* stop the spdif interrupt */
2431 unsigned int val; 2412 unsigned int val;
2432 pci_read_config_dword(chip->pci, 0x4c, &val); 2413 pci_read_config_dword(chip->pci, 0x4c, &val);
@@ -2443,10 +2424,10 @@ static int snd_intel8x0_free(struct intel8x0 *chip)
2443 fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 0); 2424 fill_nocache(chip->bdbars.area, chip->bdbars.bytes, 0);
2444 snd_dma_free_pages(&chip->bdbars); 2425 snd_dma_free_pages(&chip->bdbars);
2445 } 2426 }
2446 if (chip->remap_addr) 2427 if (chip->addr)
2447 iounmap(chip->remap_addr); 2428 pci_iounmap(chip->pci, chip->addr);
2448 if (chip->remap_bmaddr) 2429 if (chip->bmaddr)
2449 iounmap(chip->remap_bmaddr); 2430 pci_iounmap(chip->pci, chip->bmaddr);
2450 pci_release_regions(chip->pci); 2431 pci_release_regions(chip->pci);
2451 pci_disable_device(chip->pci); 2432 pci_disable_device(chip->pci);
2452 kfree(chip); 2433 kfree(chip);
@@ -2520,7 +2501,7 @@ static int intel8x0_resume(struct pci_dev *pci)
2520 snd_intel8x0_chip_init(chip, 0); 2501 snd_intel8x0_chip_init(chip, 0);
2521 2502
2522 /* re-initialize mixer stuff */ 2503 /* re-initialize mixer stuff */
2523 if (chip->device_type == DEVICE_INTEL_ICH4) { 2504 if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) {
2524 /* enable separate SDINs for ICH4 */ 2505 /* enable separate SDINs for ICH4 */
2525 iputbyte(chip, ICHREG(SDM), chip->sdm_saved); 2506 iputbyte(chip, ICHREG(SDM), chip->sdm_saved);
2526 /* use slot 10/11 for SPDIF */ 2507 /* use slot 10/11 for SPDIF */
@@ -2793,35 +2774,27 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
2793 2774
2794 if (device_type == DEVICE_ALI) { 2775 if (device_type == DEVICE_ALI) {
2795 /* ALI5455 has no ac97 region */ 2776 /* ALI5455 has no ac97 region */
2796 chip->bmaddr = pci_resource_start(pci, 0); 2777 chip->bmaddr = pci_iomap(pci, 0, 0);
2797 goto port_inited; 2778 goto port_inited;
2798 } 2779 }
2799 2780
2800 if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) { /* ICH4 and Nforce */ 2781 if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) /* ICH4 and Nforce */
2801 chip->mmio = 1; 2782 chip->addr = pci_iomap(pci, 2, 0);
2802 chip->addr = pci_resource_start(pci, 2); 2783 else
2803 chip->remap_addr = ioremap_nocache(chip->addr, 2784 chip->addr = pci_iomap(pci, 0, 0);
2804 pci_resource_len(pci, 2)); 2785 if (!chip->addr) {
2805 if (chip->remap_addr == NULL) { 2786 snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
2806 snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); 2787 snd_intel8x0_free(chip);
2807 snd_intel8x0_free(chip); 2788 return -EIO;
2808 return -EIO; 2789 }
2809 } 2790 if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */
2810 } else { 2791 chip->bmaddr = pci_iomap(pci, 3, 0);
2811 chip->addr = pci_resource_start(pci, 0); 2792 else
2812 } 2793 chip->bmaddr = pci_iomap(pci, 1, 0);
2813 if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) { /* ICH4 */ 2794 if (!chip->bmaddr) {
2814 chip->bm_mmio = 1; 2795 snd_printk(KERN_ERR "Controller space ioremap problem\n");
2815 chip->bmaddr = pci_resource_start(pci, 3); 2796 snd_intel8x0_free(chip);
2816 chip->remap_bmaddr = ioremap_nocache(chip->bmaddr, 2797 return -EIO;
2817 pci_resource_len(pci, 3));
2818 if (chip->remap_bmaddr == NULL) {
2819 snd_printk(KERN_ERR "Controller space ioremap problem\n");
2820 snd_intel8x0_free(chip);
2821 return -EIO;
2822 }
2823 } else {
2824 chip->bmaddr = pci_resource_start(pci, 1);
2825 } 2798 }
2826 2799
2827 port_inited: 2800 port_inited:
@@ -2964,6 +2937,29 @@ static struct shortname_table {
2964 { 0, NULL }, 2937 { 0, NULL },
2965}; 2938};
2966 2939
2940static struct snd_pci_quirk spdif_aclink_defaults[] __devinitdata = {
2941 SND_PCI_QUIRK(0x147b, 0x1c1a, "ASUS KN8", 1),
2942 { } /* end */
2943};
2944
2945/* look up white/black list for SPDIF over ac-link */
2946static int __devinit check_default_spdif_aclink(struct pci_dev *pci)
2947{
2948 const struct snd_pci_quirk *w;
2949
2950 w = snd_pci_quirk_lookup(pci, spdif_aclink_defaults);
2951 if (w) {
2952 if (w->value)
2953 snd_printdd(KERN_INFO "intel8x0: Using SPDIF over "
2954 "AC-Link for %s\n", w->name);
2955 else
2956 snd_printdd(KERN_INFO "intel8x0: Using integrated "
2957 "SPDIF DMA for %s\n", w->name);
2958 return w->value;
2959 }
2960 return 0;
2961}
2962
2967static int __devinit snd_intel8x0_probe(struct pci_dev *pci, 2963static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
2968 const struct pci_device_id *pci_id) 2964 const struct pci_device_id *pci_id)
2969{ 2965{
@@ -2976,16 +2972,18 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
2976 if (card == NULL) 2972 if (card == NULL)
2977 return -ENOMEM; 2973 return -ENOMEM;
2978 2974
2979 switch (pci_id->driver_data) { 2975 if (spdif_aclink < 0)
2980 case DEVICE_NFORCE: 2976 spdif_aclink = check_default_spdif_aclink(pci);
2981 strcpy(card->driver, "NFORCE"); 2977
2982 break; 2978 strcpy(card->driver, "ICH");
2983 case DEVICE_INTEL_ICH4: 2979 if (!spdif_aclink) {
2984 strcpy(card->driver, "ICH4"); 2980 switch (pci_id->driver_data) {
2985 break; 2981 case DEVICE_NFORCE:
2986 default: 2982 strcpy(card->driver, "NFORCE");
2987 strcpy(card->driver, "ICH"); 2983 break;
2988 break; 2984 case DEVICE_INTEL_ICH4:
2985 strcpy(card->driver, "ICH4");
2986 }
2989 } 2987 }
2990 2988
2991 strcpy(card->shortname, "Intel ICH"); 2989 strcpy(card->shortname, "Intel ICH");
@@ -3025,8 +3023,8 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci,
3025 snd_intel8x0_proc_init(chip); 3023 snd_intel8x0_proc_init(chip);
3026 3024
3027 snprintf(card->longname, sizeof(card->longname), 3025 snprintf(card->longname, sizeof(card->longname),
3028 "%s with %s at %#lx, irq %i", card->shortname, 3026 "%s with %s at irq %i", card->shortname,
3029 snd_ac97_get_short_name(chip->ac97[0]), chip->addr, chip->irq); 3027 snd_ac97_get_short_name(chip->ac97[0]), chip->irq);
3030 3028
3031 if (! ac97_clock) 3029 if (! ac97_clock)
3032 intel8x0_measure_ac97_clock(chip); 3030 intel8x0_measure_ac97_clock(chip);
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index 09dcf923b547..c155e1f3a0e5 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -196,12 +196,8 @@ struct intel8x0m {
196 196
197 int irq; 197 int irq;
198 198
199 unsigned int mmio; 199 void __iomem *addr;
200 unsigned long addr; 200 void __iomem *bmaddr;
201 void __iomem *remap_addr;
202 unsigned int bm_mmio;
203 unsigned long bmaddr;
204 void __iomem *remap_bmaddr;
205 201
206 struct pci_dev *pci; 202 struct pci_dev *pci;
207 struct snd_card *card; 203 struct snd_card *card;
@@ -253,72 +249,48 @@ MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
253 * Lowlevel I/O - busmaster 249 * Lowlevel I/O - busmaster
254 */ 250 */
255 251
256static u8 igetbyte(struct intel8x0m *chip, u32 offset) 252static inline u8 igetbyte(struct intel8x0m *chip, u32 offset)
257{ 253{
258 if (chip->bm_mmio) 254 return ioread8(chip->bmaddr + offset);
259 return readb(chip->remap_bmaddr + offset);
260 else
261 return inb(chip->bmaddr + offset);
262} 255}
263 256
264static u16 igetword(struct intel8x0m *chip, u32 offset) 257static inline u16 igetword(struct intel8x0m *chip, u32 offset)
265{ 258{
266 if (chip->bm_mmio) 259 return ioread16(chip->bmaddr + offset);
267 return readw(chip->remap_bmaddr + offset);
268 else
269 return inw(chip->bmaddr + offset);
270} 260}
271 261
272static u32 igetdword(struct intel8x0m *chip, u32 offset) 262static inline u32 igetdword(struct intel8x0m *chip, u32 offset)
273{ 263{
274 if (chip->bm_mmio) 264 return ioread32(chip->bmaddr + offset);
275 return readl(chip->remap_bmaddr + offset);
276 else
277 return inl(chip->bmaddr + offset);
278} 265}
279 266
280static void iputbyte(struct intel8x0m *chip, u32 offset, u8 val) 267static inline void iputbyte(struct intel8x0m *chip, u32 offset, u8 val)
281{ 268{
282 if (chip->bm_mmio) 269 iowrite8(val, chip->bmaddr + offset);
283 writeb(val, chip->remap_bmaddr + offset);
284 else
285 outb(val, chip->bmaddr + offset);
286} 270}
287 271
288static void iputword(struct intel8x0m *chip, u32 offset, u16 val) 272static inline void iputword(struct intel8x0m *chip, u32 offset, u16 val)
289{ 273{
290 if (chip->bm_mmio) 274 iowrite16(val, chip->bmaddr + offset);
291 writew(val, chip->remap_bmaddr + offset);
292 else
293 outw(val, chip->bmaddr + offset);
294} 275}
295 276
296static void iputdword(struct intel8x0m *chip, u32 offset, u32 val) 277static inline void iputdword(struct intel8x0m *chip, u32 offset, u32 val)
297{ 278{
298 if (chip->bm_mmio) 279 iowrite32(val, chip->bmaddr + offset);
299 writel(val, chip->remap_bmaddr + offset);
300 else
301 outl(val, chip->bmaddr + offset);
302} 280}
303 281
304/* 282/*
305 * Lowlevel I/O - AC'97 registers 283 * Lowlevel I/O - AC'97 registers
306 */ 284 */
307 285
308static u16 iagetword(struct intel8x0m *chip, u32 offset) 286static inline u16 iagetword(struct intel8x0m *chip, u32 offset)
309{ 287{
310 if (chip->mmio) 288 return ioread16(chip->addr + offset);
311 return readw(chip->remap_addr + offset);
312 else
313 return inw(chip->addr + offset);
314} 289}
315 290
316static void iaputword(struct intel8x0m *chip, u32 offset, u16 val) 291static inline void iaputword(struct intel8x0m *chip, u32 offset, u16 val)
317{ 292{
318 if (chip->mmio) 293 iowrite16(val, chip->addr + offset);
319 writew(val, chip->remap_addr + offset);
320 else
321 outw(val, chip->addr + offset);
322} 294}
323 295
324/* 296/*
@@ -858,7 +830,7 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0m *chip, int ac97_clock)
858 memset(&ac97, 0, sizeof(ac97)); 830 memset(&ac97, 0, sizeof(ac97));
859 ac97.private_data = chip; 831 ac97.private_data = chip;
860 ac97.private_free = snd_intel8x0_mixer_free_ac97; 832 ac97.private_free = snd_intel8x0_mixer_free_ac97;
861 ac97.scaps = AC97_SCAP_SKIP_AUDIO; 833 ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
862 834
863 glob_sta = igetdword(chip, ICHREG(GLOB_STA)); 835 glob_sta = igetdword(chip, ICHREG(GLOB_STA));
864 836
@@ -1019,10 +991,10 @@ static int snd_intel8x0_free(struct intel8x0m *chip)
1019 __hw_end: 991 __hw_end:
1020 if (chip->bdbars.area) 992 if (chip->bdbars.area)
1021 snd_dma_free_pages(&chip->bdbars); 993 snd_dma_free_pages(&chip->bdbars);
1022 if (chip->remap_addr) 994 if (chip->addr)
1023 iounmap(chip->remap_addr); 995 pci_iounmap(chip->pci, chip->addr);
1024 if (chip->remap_bmaddr) 996 if (chip->bmaddr)
1025 iounmap(chip->remap_bmaddr); 997 pci_iounmap(chip->pci, chip->bmaddr);
1026 if (chip->irq >= 0) 998 if (chip->irq >= 0)
1027 free_irq(chip->irq, chip); 999 free_irq(chip->irq, chip);
1028 pci_release_regions(chip->pci); 1000 pci_release_regions(chip->pci);
@@ -1173,35 +1145,27 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
1173 1145
1174 if (device_type == DEVICE_ALI) { 1146 if (device_type == DEVICE_ALI) {
1175 /* ALI5455 has no ac97 region */ 1147 /* ALI5455 has no ac97 region */
1176 chip->bmaddr = pci_resource_start(pci, 0); 1148 chip->bmaddr = pci_iomap(pci, 0, 0);
1177 goto port_inited; 1149 goto port_inited;
1178 } 1150 }
1179 1151
1180 if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) { /* ICH4 and Nforce */ 1152 if (pci_resource_flags(pci, 2) & IORESOURCE_MEM) /* ICH4 and Nforce */
1181 chip->mmio = 1; 1153 chip->addr = pci_iomap(pci, 2, 0);
1182 chip->addr = pci_resource_start(pci, 2); 1154 else
1183 chip->remap_addr = ioremap_nocache(chip->addr, 1155 chip->addr = pci_iomap(pci, 0, 0);
1184 pci_resource_len(pci, 2)); 1156 if (!chip->addr) {
1185 if (chip->remap_addr == NULL) { 1157 snd_printk(KERN_ERR "AC'97 space ioremap problem\n");
1186 snd_printk(KERN_ERR "AC'97 space ioremap problem\n"); 1158 snd_intel8x0_free(chip);
1187 snd_intel8x0_free(chip); 1159 return -EIO;
1188 return -EIO;
1189 }
1190 } else {
1191 chip->addr = pci_resource_start(pci, 0);
1192 } 1160 }
1193 if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) { /* ICH4 */ 1161 if (pci_resource_flags(pci, 3) & IORESOURCE_MEM) /* ICH4 */
1194 chip->bm_mmio = 1; 1162 chip->bmaddr = pci_iomap(pci, 3, 0);
1195 chip->bmaddr = pci_resource_start(pci, 3); 1163 else
1196 chip->remap_bmaddr = ioremap_nocache(chip->bmaddr, 1164 chip->bmaddr = pci_iomap(pci, 1, 0);
1197 pci_resource_len(pci, 3)); 1165 if (!chip->bmaddr) {
1198 if (chip->remap_bmaddr == NULL) { 1166 snd_printk(KERN_ERR "Controller space ioremap problem\n");
1199 snd_printk(KERN_ERR "Controller space ioremap problem\n"); 1167 snd_intel8x0_free(chip);
1200 snd_intel8x0_free(chip); 1168 return -EIO;
1201 return -EIO;
1202 }
1203 } else {
1204 chip->bmaddr = pci_resource_start(pci, 1);
1205 } 1169 }
1206 1170
1207 port_inited: 1171 port_inited:
@@ -1339,8 +1303,8 @@ static int __devinit snd_intel8x0m_probe(struct pci_dev *pci,
1339 1303
1340 snd_intel8x0m_proc_init(chip); 1304 snd_intel8x0m_proc_init(chip);
1341 1305
1342 sprintf(card->longname, "%s at 0x%lx, irq %i", 1306 sprintf(card->longname, "%s at irq %i",
1343 card->shortname, chip->addr, chip->irq); 1307 card->shortname, chip->irq);
1344 1308
1345 if ((err = snd_card_register(card)) < 0) { 1309 if ((err = snd_card_register(card)) < 0) {
1346 snd_card_free(card); 1310 snd_card_free(card);
diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c
index 345eefeedb39..21d0899ac382 100644
--- a/sound/pci/korg1212/korg1212.c
+++ b/sound/pci/korg1212/korg1212.c
@@ -28,6 +28,7 @@
28#include <linux/wait.h> 28#include <linux/wait.h>
29#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
30#include <linux/mutex.h> 30#include <linux/mutex.h>
31#include <linux/firmware.h>
31 32
32#include <sound/core.h> 33#include <sound/core.h>
33#include <sound/info.h> 34#include <sound/info.h>
@@ -263,7 +264,15 @@ enum MonitorModeSelector {
263#define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement 264#define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement
264 // from the card after sending a command. 265 // from the card after sending a command.
265 266
267#define FIRMWARE_IN_THE_KERNEL
268
269#ifdef FIRMWARE_IN_THE_KERNEL
266#include "korg1212-firmware.h" 270#include "korg1212-firmware.h"
271static const struct firmware static_dsp_code = {
272 .data = (u8 *)dspCode,
273 .size = sizeof dspCode
274};
275#endif
267 276
268enum ClockSourceIndex { 277enum ClockSourceIndex {
269 K1212_CLKIDX_AdatAt44_1K = 0, // selects source as ADAT at 44.1 kHz 278 K1212_CLKIDX_AdatAt44_1K = 0, // selects source as ADAT at 44.1 kHz
@@ -345,8 +354,6 @@ struct snd_korg1212 {
345 struct snd_dma_buffer dma_rec; 354 struct snd_dma_buffer dma_rec;
346 struct snd_dma_buffer dma_shared; 355 struct snd_dma_buffer dma_shared;
347 356
348 u32 dspCodeSize;
349
350 u32 DataBufsSize; 357 u32 DataBufsSize;
351 358
352 struct KorgAudioBuffer * playDataBufsPtr; 359 struct KorgAudioBuffer * playDataBufsPtr;
@@ -1223,8 +1230,6 @@ static int snd_korg1212_downloadDSPCode(struct snd_korg1212 *korg1212)
1223 1230
1224 snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_IN_PROCESS); 1231 snd_korg1212_setCardState(korg1212, K1212_STATE_DSP_IN_PROCESS);
1225 1232
1226 memcpy(korg1212->dma_dsp.area, dspCode, korg1212->dspCodeSize);
1227
1228 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_StartDSPDownload, 1233 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_StartDSPDownload,
1229 UpperWordSwap(korg1212->dma_dsp.addr), 1234 UpperWordSwap(korg1212->dma_dsp.addr),
1230 0, 0, 0); 1235 0, 0, 0);
@@ -2156,6 +2161,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
2156 unsigned int i; 2161 unsigned int i;
2157 unsigned ioport_size, iomem_size, iomem2_size; 2162 unsigned ioport_size, iomem_size, iomem2_size;
2158 struct snd_korg1212 * korg1212; 2163 struct snd_korg1212 * korg1212;
2164 const struct firmware *dsp_code;
2159 2165
2160 static struct snd_device_ops ops = { 2166 static struct snd_device_ops ops = {
2161 .dev_free = snd_korg1212_dev_free, 2167 .dev_free = snd_korg1212_dev_free,
@@ -2329,8 +2335,6 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
2329 2335
2330#endif // K1212_LARGEALLOC 2336#endif // K1212_LARGEALLOC
2331 2337
2332 korg1212->dspCodeSize = sizeof (dspCode);
2333
2334 korg1212->VolumeTablePhy = korg1212->sharedBufferPhy + 2338 korg1212->VolumeTablePhy = korg1212->sharedBufferPhy +
2335 offsetof(struct KorgSharedBuffer, volumeData); 2339 offsetof(struct KorgSharedBuffer, volumeData);
2336 korg1212->RoutingTablePhy = korg1212->sharedBufferPhy + 2340 korg1212->RoutingTablePhy = korg1212->sharedBufferPhy +
@@ -2338,17 +2342,40 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
2338 korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy + 2342 korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy +
2339 offsetof(struct KorgSharedBuffer, AdatTimeCode); 2343 offsetof(struct KorgSharedBuffer, AdatTimeCode);
2340 2344
2345 err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev);
2346 if (err < 0) {
2347 release_firmware(dsp_code);
2348#ifdef FIRMWARE_IN_THE_KERNEL
2349 dsp_code = &static_dsp_code;
2350#else
2351 snd_printk(KERN_ERR "firmware not available\n");
2352 snd_korg1212_free(korg1212);
2353 return err;
2354#endif
2355 }
2356
2341 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), 2357 if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci),
2342 korg1212->dspCodeSize, &korg1212->dma_dsp) < 0) { 2358 dsp_code->size, &korg1212->dma_dsp) < 0) {
2343 snd_printk(KERN_ERR "korg1212: can not allocate dsp code memory (%d bytes)\n", korg1212->dspCodeSize); 2359 snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size);
2344 snd_korg1212_free(korg1212); 2360 snd_korg1212_free(korg1212);
2361#ifdef FIRMWARE_IN_THE_KERNEL
2362 if (dsp_code != &static_dsp_code)
2363#endif
2364 release_firmware(dsp_code);
2345 return -ENOMEM; 2365 return -ENOMEM;
2346 } 2366 }
2347 2367
2348 K1212_DEBUG_PRINTK("K1212_DEBUG: DSP Code area = 0x%p (0x%08x) %d bytes [%s]\n", 2368 K1212_DEBUG_PRINTK("K1212_DEBUG: DSP Code area = 0x%p (0x%08x) %d bytes [%s]\n",
2349 korg1212->dma_dsp.area, korg1212->dma_dsp.addr, korg1212->dspCodeSize, 2369 korg1212->dma_dsp.area, korg1212->dma_dsp.addr, dsp_code->size,
2350 stateName[korg1212->cardState]); 2370 stateName[korg1212->cardState]);
2351 2371
2372 memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size);
2373
2374#ifdef FIRMWARE_IN_THE_KERNEL
2375 if (dsp_code != &static_dsp_code)
2376#endif
2377 release_firmware(dsp_code);
2378
2352 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0); 2379 rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0);
2353 2380
2354 if (rc) 2381 if (rc)
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 6efe6d5ade1e..4526904e3f86 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -41,6 +41,7 @@
41#include <linux/slab.h> 41#include <linux/slab.h>
42#include <linux/vmalloc.h> 42#include <linux/vmalloc.h>
43#include <linux/moduleparam.h> 43#include <linux/moduleparam.h>
44#include <linux/firmware.h>
44#include <sound/core.h> 45#include <sound/core.h>
45#include <sound/info.h> 46#include <sound/info.h>
46#include <sound/control.h> 47#include <sound/control.h>
@@ -48,6 +49,7 @@
48#include <sound/mpu401.h> 49#include <sound/mpu401.h>
49#include <sound/ac97_codec.h> 50#include <sound/ac97_codec.h>
50#include <sound/initval.h> 51#include <sound/initval.h>
52#include <asm/byteorder.h>
51 53
52MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Takashi Iwai <tiwai@suse.de>"); 54MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Takashi Iwai <tiwai@suse.de>");
53MODULE_DESCRIPTION("ESS Maestro3 PCI"); 55MODULE_DESCRIPTION("ESS Maestro3 PCI");
@@ -768,21 +770,6 @@ MODULE_PARM_DESC(amp_gpio, "GPIO pin number for external amp. (default = -1)");
768/* 770/*
769 */ 771 */
770 772
771/* quirk lists */
772struct m3_quirk {
773 const char *name; /* device name */
774 u16 vendor, device; /* subsystem ids */
775 int amp_gpio; /* gpio pin # for external amp, -1 = default */
776 int irda_workaround; /* non-zero if avoid to touch 0x10 on GPIO_DIRECTION
777 (e.g. for IrDA on Dell Inspirons) */
778};
779
780struct m3_hv_quirk {
781 u16 vendor, device, subsystem_vendor, subsystem_device;
782 u32 config; /* ALLEGRO_CONFIG hardware volume bits */
783 int is_omnibook; /* Do HP OmniBook GPIO magic? */
784};
785
786struct m3_list { 773struct m3_list {
787 int curlen; 774 int curlen;
788 int mem_addr; 775 int mem_addr;
@@ -830,8 +817,6 @@ struct snd_m3 {
830 struct snd_pcm *pcm; 817 struct snd_pcm *pcm;
831 818
832 struct pci_dev *pci; 819 struct pci_dev *pci;
833 const struct m3_quirk *quirk;
834 const struct m3_hv_quirk *hv_quirk;
835 820
836 int dacs_active; 821 int dacs_active;
837 int timer_users; 822 int timer_users;
@@ -845,7 +830,11 @@ struct snd_m3 {
845 u8 reset_state; 830 u8 reset_state;
846 831
847 int external_amp; 832 int external_amp;
848 int amp_gpio; 833 int amp_gpio; /* gpio pin # for external amp, -1 = default */
834 unsigned int hv_config; /* hardware-volume config bits */
835 unsigned irda_workaround :1; /* avoid to touch 0x10 on GPIO_DIRECTION
836 (e.g. for IrDA on Dell Inspirons) */
837 unsigned is_omnibook :1; /* Do HP OmniBook GPIO magic? */
849 838
850 /* midi */ 839 /* midi */
851 struct snd_rawmidi *rmidi; 840 struct snd_rawmidi *rmidi;
@@ -864,6 +853,9 @@ struct snd_m3 {
864#ifdef CONFIG_PM 853#ifdef CONFIG_PM
865 u16 *suspend_mem; 854 u16 *suspend_mem;
866#endif 855#endif
856
857 const struct firmware *assp_kernel_image;
858 const struct firmware *assp_minisrc_image;
867}; 859};
868 860
869/* 861/*
@@ -891,127 +883,104 @@ static struct pci_device_id snd_m3_ids[] = {
891 883
892MODULE_DEVICE_TABLE(pci, snd_m3_ids); 884MODULE_DEVICE_TABLE(pci, snd_m3_ids);
893 885
894static const struct m3_quirk m3_quirk_list[] = { 886static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = {
895 /* panasonic CF-28 "toughbook" */ 887 SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d),
896 { 888 SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d),
897 .name = "Panasonic CF-28", 889 SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03),
898 .vendor = 0x10f7, 890 SND_PCI_QUIRK(0x1509, 0x1740, "LEGEND ZhaoYang 3100CF", 0x03),
899 .device = 0x833e, 891 { } /* END */
900 .amp_gpio = 0x0d,
901 },
902 /* panasonic CF-72 "toughbook" */
903 {
904 .name = "Panasonic CF-72",
905 .vendor = 0x10f7,
906 .device = 0x833d,
907 .amp_gpio = 0x0d,
908 },
909 /* Dell Inspiron 4000 */
910 {
911 .name = "Dell Inspiron 4000",
912 .vendor = 0x1028,
913 .device = 0x00b0,
914 .amp_gpio = -1,
915 .irda_workaround = 1,
916 },
917 /* Dell Inspiron 8000 */
918 {
919 .name = "Dell Inspiron 8000",
920 .vendor = 0x1028,
921 .device = 0x00a4,
922 .amp_gpio = -1,
923 .irda_workaround = 1,
924 },
925 /* Dell Inspiron 8100 */
926 {
927 .name = "Dell Inspiron 8100",
928 .vendor = 0x1028,
929 .device = 0x00e6,
930 .amp_gpio = -1,
931 .irda_workaround = 1,
932 },
933 /* NEC LM800J/7 */
934 {
935 .name = "NEC LM800J/7",
936 .vendor = 0x1033,
937 .device = 0x80f1,
938 .amp_gpio = 0x03,
939 },
940 /* LEGEND ZhaoYang 3100CF */
941 {
942 .name = "LEGEND ZhaoYang 3100CF",
943 .vendor = 0x1509,
944 .device = 0x1740,
945 .amp_gpio = 0x03,
946 },
947 /* END */
948 { NULL }
949}; 892};
950 893
951/* These values came from the Windows driver. */ 894static struct snd_pci_quirk m3_irda_quirk_list[] __devinitdata = {
952static const struct m3_hv_quirk m3_hv_quirk_list[] = { 895 SND_PCI_QUIRK(0x1028, 0x00b0, "Dell Inspiron 4000", 1),
896 SND_PCI_QUIRK(0x1028, 0x00a4, "Dell Inspiron 8000", 1),
897 SND_PCI_QUIRK(0x1028, 0x00e6, "Dell Inspiron 8100", 1),
898 { } /* END */
899};
900
901/* hardware volume quirks */
902static struct snd_pci_quirk m3_hv_quirk_list[] __devinitdata = {
953 /* Allegro chips */ 903 /* Allegro chips */
954 { 0x125D, 0x1988, 0x0E11, 0x002E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 904 SND_PCI_QUIRK(0x0E11, 0x002E, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
955 { 0x125D, 0x1988, 0x0E11, 0x0094, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 905 SND_PCI_QUIRK(0x0E11, 0x0094, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
956 { 0x125D, 0x1988, 0x0E11, 0xB112, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 906 SND_PCI_QUIRK(0x0E11, 0xB112, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
957 { 0x125D, 0x1988, 0x0E11, 0xB114, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 907 SND_PCI_QUIRK(0x0E11, 0xB114, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
958 { 0x125D, 0x1988, 0x103C, 0x0012, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 908 SND_PCI_QUIRK(0x103C, 0x0012, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
959 { 0x125D, 0x1988, 0x103C, 0x0018, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 909 SND_PCI_QUIRK(0x103C, 0x0018, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
960 { 0x125D, 0x1988, 0x103C, 0x001C, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 910 SND_PCI_QUIRK(0x103C, 0x001C, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
961 { 0x125D, 0x1988, 0x103C, 0x001D, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 911 SND_PCI_QUIRK(0x103C, 0x001D, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
962 { 0x125D, 0x1988, 0x103C, 0x001E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 912 SND_PCI_QUIRK(0x103C, 0x001E, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
963 { 0x125D, 0x1988, 0x107B, 0x3350, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 913 SND_PCI_QUIRK(0x107B, 0x3350, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
964 { 0x125D, 0x1988, 0x10F7, 0x8338, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 914 SND_PCI_QUIRK(0x10F7, 0x8338, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
965 { 0x125D, 0x1988, 0x10F7, 0x833C, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 915 SND_PCI_QUIRK(0x10F7, 0x833C, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
966 { 0x125D, 0x1988, 0x10F7, 0x833D, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 916 SND_PCI_QUIRK(0x10F7, 0x833D, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
967 { 0x125D, 0x1988, 0x10F7, 0x833E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 917 SND_PCI_QUIRK(0x10F7, 0x833E, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
968 { 0x125D, 0x1988, 0x10F7, 0x833F, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 918 SND_PCI_QUIRK(0x10F7, 0x833F, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
969 { 0x125D, 0x1988, 0x13BD, 0x1018, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 919 SND_PCI_QUIRK(0x13BD, 0x1018, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
970 { 0x125D, 0x1988, 0x13BD, 0x1019, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 920 SND_PCI_QUIRK(0x13BD, 0x1019, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
971 { 0x125D, 0x1988, 0x13BD, 0x101A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 921 SND_PCI_QUIRK(0x13BD, 0x101A, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
972 { 0x125D, 0x1988, 0x14FF, 0x0F03, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 922 SND_PCI_QUIRK(0x14FF, 0x0F03, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
973 { 0x125D, 0x1988, 0x14FF, 0x0F04, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 923 SND_PCI_QUIRK(0x14FF, 0x0F04, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
974 { 0x125D, 0x1988, 0x14FF, 0x0F05, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 924 SND_PCI_QUIRK(0x14FF, 0x0F05, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
975 { 0x125D, 0x1988, 0x156D, 0xB400, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 925 SND_PCI_QUIRK(0x156D, 0xB400, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
976 { 0x125D, 0x1988, 0x156D, 0xB795, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 926 SND_PCI_QUIRK(0x156D, 0xB795, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
977 { 0x125D, 0x1988, 0x156D, 0xB797, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 927 SND_PCI_QUIRK(0x156D, 0xB797, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
978 { 0x125D, 0x1988, 0x156D, 0xC700, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 928 SND_PCI_QUIRK(0x156D, 0xC700, NULL, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD),
979 { 0x125D, 0x1988, 0x1033, 0x80F1, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, 929 SND_PCI_QUIRK(0x1033, 0x80F1, NULL,
980 { 0x125D, 0x1988, 0x103C, 0x001A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, /* HP OmniBook 6100 */ 930 HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
981 { 0x125D, 0x1988, 0x107B, 0x340A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, 931 SND_PCI_QUIRK(0x103C, 0x001A, NULL, /* HP OmniBook 6100 */
982 { 0x125D, 0x1988, 0x107B, 0x3450, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, 932 HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
983 { 0x125D, 0x1988, 0x109F, 0x3134, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, 933 SND_PCI_QUIRK(0x107B, 0x340A, NULL,
984 { 0x125D, 0x1988, 0x109F, 0x3161, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, 934 HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
985 { 0x125D, 0x1988, 0x144D, 0x3280, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, 935 SND_PCI_QUIRK(0x107B, 0x3450, NULL,
986 { 0x125D, 0x1988, 0x144D, 0x3281, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, 936 HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
987 { 0x125D, 0x1988, 0x144D, 0xC002, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, 937 SND_PCI_QUIRK(0x109F, 0x3134, NULL,
988 { 0x125D, 0x1988, 0x144D, 0xC003, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, 938 HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
989 { 0x125D, 0x1988, 0x1509, 0x1740, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, 939 SND_PCI_QUIRK(0x109F, 0x3161, NULL,
990 { 0x125D, 0x1988, 0x1610, 0x0010, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, 940 HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
991 { 0x125D, 0x1988, 0x1042, 0x1042, HV_CTRL_ENABLE, 0 }, 941 SND_PCI_QUIRK(0x144D, 0x3280, NULL,
992 { 0x125D, 0x1988, 0x107B, 0x9500, HV_CTRL_ENABLE, 0 }, 942 HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
993 { 0x125D, 0x1988, 0x14FF, 0x0F06, HV_CTRL_ENABLE, 0 }, 943 SND_PCI_QUIRK(0x144D, 0x3281, NULL,
994 { 0x125D, 0x1988, 0x1558, 0x8586, HV_CTRL_ENABLE, 0 }, 944 HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
995 { 0x125D, 0x1988, 0x161F, 0x2011, HV_CTRL_ENABLE, 0 }, 945 SND_PCI_QUIRK(0x144D, 0xC002, NULL,
946 HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
947 SND_PCI_QUIRK(0x144D, 0xC003, NULL,
948 HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
949 SND_PCI_QUIRK(0x1509, 0x1740, NULL,
950 HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
951 SND_PCI_QUIRK(0x1610, 0x0010, NULL,
952 HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE),
953 SND_PCI_QUIRK(0x1042, 0x1042, NULL, HV_CTRL_ENABLE),
954 SND_PCI_QUIRK(0x107B, 0x9500, NULL, HV_CTRL_ENABLE),
955 SND_PCI_QUIRK(0x14FF, 0x0F06, NULL, HV_CTRL_ENABLE),
956 SND_PCI_QUIRK(0x1558, 0x8586, NULL, HV_CTRL_ENABLE),
957 SND_PCI_QUIRK(0x161F, 0x2011, NULL, HV_CTRL_ENABLE),
996 /* Maestro3 chips */ 958 /* Maestro3 chips */
997 { 0x125D, 0x1998, 0x103C, 0x000E, HV_CTRL_ENABLE, 0 }, 959 SND_PCI_QUIRK(0x103C, 0x000E, NULL, HV_CTRL_ENABLE),
998 { 0x125D, 0x1998, 0x103C, 0x0010, HV_CTRL_ENABLE, 1 }, /* HP OmniBook 6000 */ 960 SND_PCI_QUIRK(0x103C, 0x0010, NULL, HV_CTRL_ENABLE),
999 { 0x125D, 0x1998, 0x103C, 0x0011, HV_CTRL_ENABLE, 1 }, /* HP OmniBook 500 */ 961 SND_PCI_QUIRK(0x103C, 0x0011, NULL, HV_CTRL_ENABLE),
1000 { 0x125D, 0x1998, 0x103C, 0x001B, HV_CTRL_ENABLE, 0 }, 962 SND_PCI_QUIRK(0x103C, 0x001B, NULL, HV_CTRL_ENABLE),
1001 { 0x125D, 0x1998, 0x104D, 0x80A6, HV_CTRL_ENABLE, 0 }, 963 SND_PCI_QUIRK(0x104D, 0x80A6, NULL, HV_CTRL_ENABLE),
1002 { 0x125D, 0x1998, 0x104D, 0x80AA, HV_CTRL_ENABLE, 0 }, 964 SND_PCI_QUIRK(0x104D, 0x80AA, NULL, HV_CTRL_ENABLE),
1003 { 0x125D, 0x1998, 0x107B, 0x5300, HV_CTRL_ENABLE, 0 }, 965 SND_PCI_QUIRK(0x107B, 0x5300, NULL, HV_CTRL_ENABLE),
1004 { 0x125D, 0x1998, 0x110A, 0x1998, HV_CTRL_ENABLE, 0 }, 966 SND_PCI_QUIRK(0x110A, 0x1998, NULL, HV_CTRL_ENABLE),
1005 { 0x125D, 0x1998, 0x13BD, 0x1015, HV_CTRL_ENABLE, 0 }, 967 SND_PCI_QUIRK(0x13BD, 0x1015, NULL, HV_CTRL_ENABLE),
1006 { 0x125D, 0x1998, 0x13BD, 0x101C, HV_CTRL_ENABLE, 0 }, 968 SND_PCI_QUIRK(0x13BD, 0x101C, NULL, HV_CTRL_ENABLE),
1007 { 0x125D, 0x1998, 0x13BD, 0x1802, HV_CTRL_ENABLE, 0 }, 969 SND_PCI_QUIRK(0x13BD, 0x1802, NULL, HV_CTRL_ENABLE),
1008 { 0x125D, 0x1998, 0x1599, 0x0715, HV_CTRL_ENABLE, 0 }, 970 SND_PCI_QUIRK(0x1599, 0x0715, NULL, HV_CTRL_ENABLE),
1009 { 0x125D, 0x1998, 0x5643, 0x5643, HV_CTRL_ENABLE, 0 }, 971 SND_PCI_QUIRK(0x5643, 0x5643, NULL, HV_CTRL_ENABLE),
1010 { 0x125D, 0x199A, 0x144D, 0x3260, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 }, 972 SND_PCI_QUIRK(0x144D, 0x3260, NULL, HV_CTRL_ENABLE | REDUCED_DEBOUNCE),
1011 { 0x125D, 0x199A, 0x144D, 0x3261, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 }, 973 SND_PCI_QUIRK(0x144D, 0x3261, NULL, HV_CTRL_ENABLE | REDUCED_DEBOUNCE),
1012 { 0x125D, 0x199A, 0x144D, 0xC000, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 }, 974 SND_PCI_QUIRK(0x144D, 0xC000, NULL, HV_CTRL_ENABLE | REDUCED_DEBOUNCE),
1013 { 0x125D, 0x199A, 0x144D, 0xC001, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 }, 975 SND_PCI_QUIRK(0x144D, 0xC001, NULL, HV_CTRL_ENABLE | REDUCED_DEBOUNCE),
1014 { 0 } 976 { } /* END */
977};
978
979/* HP Omnibook quirks */
980static struct snd_pci_quirk m3_omnibook_quirk_list[] __devinitdata = {
981 SND_PCI_QUIRK_ID(0x103c, 0x0010), /* HP OmniBook 6000 */
982 SND_PCI_QUIRK_ID(0x103c, 0x0011), /* HP OmniBook 500 */
983 { } /* END */
1015}; 984};
1016 985
1017/* 986/*
@@ -2050,7 +2019,7 @@ static void snd_m3_ac97_reset(struct snd_m3 *chip)
2050 2019
2051 for (i = 0; i < 5; i++) { 2020 for (i = 0; i < 5; i++) {
2052 dir = inw(io + GPIO_DIRECTION); 2021 dir = inw(io + GPIO_DIRECTION);
2053 if (! chip->quirk || ! chip->quirk->irda_workaround) 2022 if (!chip->irda_workaround)
2054 dir |= 0x10; /* assuming pci bus master? */ 2023 dir |= 0x10; /* assuming pci bus master? */
2055 2024
2056 snd_m3_remote_codec_config(io, 0); 2025 snd_m3_remote_codec_config(io, 0);
@@ -2132,6 +2101,10 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2132} 2101}
2133 2102
2134 2103
2104#define FIRMWARE_IN_THE_KERNEL
2105
2106#ifdef FIRMWARE_IN_THE_KERNEL
2107
2135/* 2108/*
2136 * DSP Code images 2109 * DSP Code images
2137 */ 2110 */
@@ -2260,6 +2233,30 @@ static const u16 assp_minisrc_image[] = {
2260 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 2233 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
2261}; 2234};
2262 2235
2236static const struct firmware assp_kernel = {
2237 .data = (u8 *)assp_kernel_image,
2238 .size = sizeof assp_kernel_image
2239};
2240static const struct firmware assp_minisrc = {
2241 .data = (u8 *)assp_minisrc_image,
2242 .size = sizeof assp_minisrc_image
2243};
2244
2245#endif /* FIRMWARE_IN_THE_KERNEL */
2246
2247#ifdef __LITTLE_ENDIAN
2248static inline void snd_m3_convert_from_le(const struct firmware *fw) { }
2249#else
2250static void snd_m3_convert_from_le(const struct firmware *fw)
2251{
2252 int i;
2253 u16 *data = (u16 *)fw->data;
2254
2255 for (i = 0; i < fw->size / 2; ++i)
2256 le16_to_cpus(&data[i]);
2257}
2258#endif
2259
2263 2260
2264/* 2261/*
2265 * initialize ASSP 2262 * initialize ASSP
@@ -2274,6 +2271,7 @@ static const u16 minisrc_lpf[MINISRC_LPF_LEN] = {
2274static void snd_m3_assp_init(struct snd_m3 *chip) 2271static void snd_m3_assp_init(struct snd_m3 *chip)
2275{ 2272{
2276 unsigned int i; 2273 unsigned int i;
2274 u16 *data;
2277 2275
2278 /* zero kernel data */ 2276 /* zero kernel data */
2279 for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++) 2277 for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
@@ -2291,10 +2289,10 @@ static void snd_m3_assp_init(struct snd_m3 *chip)
2291 KDATA_DMA_XFER0); 2289 KDATA_DMA_XFER0);
2292 2290
2293 /* write kernel into code memory.. */ 2291 /* write kernel into code memory.. */
2294 for (i = 0 ; i < ARRAY_SIZE(assp_kernel_image); i++) { 2292 data = (u16 *)chip->assp_kernel_image->data;
2293 for (i = 0 ; i * 2 < chip->assp_kernel_image->size; i++) {
2295 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, 2294 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
2296 REV_B_CODE_MEMORY_BEGIN + i, 2295 REV_B_CODE_MEMORY_BEGIN + i, data[i]);
2297 assp_kernel_image[i]);
2298 } 2296 }
2299 2297
2300 /* 2298 /*
@@ -2303,10 +2301,10 @@ static void snd_m3_assp_init(struct snd_m3 *chip)
2303 * drop it there. It seems that the minisrc doesn't 2301 * drop it there. It seems that the minisrc doesn't
2304 * need vectors, so we won't bother with them.. 2302 * need vectors, so we won't bother with them..
2305 */ 2303 */
2306 for (i = 0; i < ARRAY_SIZE(assp_minisrc_image); i++) { 2304 data = (u16 *)chip->assp_minisrc_image->data;
2305 for (i = 0; i * 2 < chip->assp_minisrc_image->size; i++) {
2307 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE, 2306 snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
2308 0x400 + i, 2307 0x400 + i, data[i]);
2309 assp_minisrc_image[i]);
2310 } 2308 }
2311 2309
2312 /* 2310 /*
@@ -2444,7 +2442,7 @@ snd_m3_chip_init(struct snd_m3 *chip)
2444 DISABLE_LEGACY); 2442 DISABLE_LEGACY);
2445 pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w); 2443 pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w);
2446 2444
2447 if (chip->hv_quirk && chip->hv_quirk->is_omnibook) { 2445 if (chip->is_omnibook) {
2448 /* 2446 /*
2449 * Volume buttons on some HP OmniBook laptops don't work 2447 * Volume buttons on some HP OmniBook laptops don't work
2450 * correctly. This makes them work for the most part. 2448 * correctly. This makes them work for the most part.
@@ -2461,8 +2459,7 @@ snd_m3_chip_init(struct snd_m3 *chip)
2461 } 2459 }
2462 pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n); 2460 pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
2463 n &= ~(HV_CTRL_ENABLE | REDUCED_DEBOUNCE | HV_BUTTON_FROM_GD); 2461 n &= ~(HV_CTRL_ENABLE | REDUCED_DEBOUNCE | HV_BUTTON_FROM_GD);
2464 if (chip->hv_quirk) 2462 n |= chip->hv_config;
2465 n |= chip->hv_quirk->config;
2466 /* For some reason we must always use reduced debounce. */ 2463 /* For some reason we must always use reduced debounce. */
2467 n |= REDUCED_DEBOUNCE; 2464 n |= REDUCED_DEBOUNCE;
2468 n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING; 2465 n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING;
@@ -2510,7 +2507,7 @@ snd_m3_enable_ints(struct snd_m3 *chip)
2510 2507
2511 /* TODO: MPU401 not supported yet */ 2508 /* TODO: MPU401 not supported yet */
2512 val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/; 2509 val = ASSP_INT_ENABLE /*| MPU401_INT_ENABLE*/;
2513 if (chip->hv_quirk && (chip->hv_quirk->config & HV_CTRL_ENABLE)) 2510 if (chip->hv_config & HV_CTRL_ENABLE)
2514 val |= HV_INT_ENABLE; 2511 val |= HV_INT_ENABLE;
2515 outw(val, io + HOST_INT_CTRL); 2512 outw(val, io + HOST_INT_CTRL);
2516 outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE, 2513 outb(inb(io + ASSP_CONTROL_C) | ASSP_HOST_INT_ENABLE,
@@ -2553,6 +2550,15 @@ static int snd_m3_free(struct snd_m3 *chip)
2553 if (chip->iobase) 2550 if (chip->iobase)
2554 pci_release_regions(chip->pci); 2551 pci_release_regions(chip->pci);
2555 2552
2553#ifdef FIRMWARE_IN_THE_KERNEL
2554 if (chip->assp_kernel_image != &assp_kernel)
2555#endif
2556 release_firmware(chip->assp_kernel_image);
2557#ifdef FIRMWARE_IN_THE_KERNEL
2558 if (chip->assp_minisrc_image != &assp_minisrc)
2559#endif
2560 release_firmware(chip->assp_minisrc_image);
2561
2556 pci_disable_device(chip->pci); 2562 pci_disable_device(chip->pci);
2557 kfree(chip); 2563 kfree(chip);
2558 return 0; 2564 return 0;
@@ -2665,8 +2671,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2665{ 2671{
2666 struct snd_m3 *chip; 2672 struct snd_m3 *chip;
2667 int i, err; 2673 int i, err;
2668 const struct m3_quirk *quirk; 2674 const struct snd_pci_quirk *quirk;
2669 const struct m3_hv_quirk *hv_quirk;
2670 static struct snd_device_ops ops = { 2675 static struct snd_device_ops ops = {
2671 .dev_free = snd_m3_dev_free, 2676 .dev_free = snd_m3_dev_free,
2672 }; 2677 };
@@ -2706,34 +2711,32 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2706 chip->pci = pci; 2711 chip->pci = pci;
2707 chip->irq = -1; 2712 chip->irq = -1;
2708 2713
2709 for (quirk = m3_quirk_list; quirk->vendor; quirk++) {
2710 if (pci->subsystem_vendor == quirk->vendor &&
2711 pci->subsystem_device == quirk->device) {
2712 printk(KERN_INFO "maestro3: enabled hack for '%s'\n", quirk->name);
2713 chip->quirk = quirk;
2714 break;
2715 }
2716 }
2717
2718 for (hv_quirk = m3_hv_quirk_list; hv_quirk->vendor; hv_quirk++) {
2719 if (pci->vendor == hv_quirk->vendor &&
2720 pci->device == hv_quirk->device &&
2721 pci->subsystem_vendor == hv_quirk->subsystem_vendor &&
2722 pci->subsystem_device == hv_quirk->subsystem_device) {
2723 chip->hv_quirk = hv_quirk;
2724 break;
2725 }
2726 }
2727
2728 chip->external_amp = enable_amp; 2714 chip->external_amp = enable_amp;
2729 if (amp_gpio >= 0 && amp_gpio <= 0x0f) 2715 if (amp_gpio >= 0 && amp_gpio <= 0x0f)
2730 chip->amp_gpio = amp_gpio; 2716 chip->amp_gpio = amp_gpio;
2731 else if (chip->quirk && chip->quirk->amp_gpio >= 0) 2717 else {
2732 chip->amp_gpio = chip->quirk->amp_gpio; 2718 quirk = snd_pci_quirk_lookup(pci, m3_amp_quirk_list);
2733 else if (chip->allegro_flag) 2719 if (quirk) {
2734 chip->amp_gpio = GPO_EXT_AMP_ALLEGRO; 2720 snd_printdd(KERN_INFO "maestro3: set amp-gpio "
2735 else /* presumably this is for all 'maestro3's.. */ 2721 "for '%s'\n", quirk->name);
2736 chip->amp_gpio = GPO_EXT_AMP_M3; 2722 chip->amp_gpio = quirk->value;
2723 } else if (chip->allegro_flag)
2724 chip->amp_gpio = GPO_EXT_AMP_ALLEGRO;
2725 else /* presumably this is for all 'maestro3's.. */
2726 chip->amp_gpio = GPO_EXT_AMP_M3;
2727 }
2728
2729 quirk = snd_pci_quirk_lookup(pci, m3_irda_quirk_list);
2730 if (quirk) {
2731 snd_printdd(KERN_INFO "maestro3: enabled irda workaround "
2732 "for '%s'\n", quirk->name);
2733 chip->irda_workaround = 1;
2734 }
2735 quirk = snd_pci_quirk_lookup(pci, m3_hv_quirk_list);
2736 if (quirk)
2737 chip->hv_config = quirk->value;
2738 if (snd_pci_quirk_lookup(pci, m3_omnibook_quirk_list))
2739 chip->is_omnibook = 1;
2737 2740
2738 chip->num_substreams = NR_DSPS; 2741 chip->num_substreams = NR_DSPS;
2739 chip->substreams = kcalloc(chip->num_substreams, sizeof(struct m3_dma), 2742 chip->substreams = kcalloc(chip->num_substreams, sizeof(struct m3_dma),
@@ -2744,6 +2747,30 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2744 return -ENOMEM; 2747 return -ENOMEM;
2745 } 2748 }
2746 2749
2750 err = request_firmware(&chip->assp_kernel_image,
2751 "ess/maestro3_assp_kernel.fw", &pci->dev);
2752 if (err < 0) {
2753#ifdef FIRMWARE_IN_THE_KERNEL
2754 chip->assp_kernel_image = &assp_kernel;
2755#else
2756 snd_m3_free(chip);
2757 return err;
2758#endif
2759 } else
2760 snd_m3_convert_from_le(chip->assp_kernel_image);
2761
2762 err = request_firmware(&chip->assp_minisrc_image,
2763 "ess/maestro3_assp_minisrc.fw", &pci->dev);
2764 if (err < 0) {
2765#ifdef FIRMWARE_IN_THE_KERNEL
2766 chip->assp_minisrc_image = &assp_minisrc;
2767#else
2768 snd_m3_free(chip);
2769 return err;
2770#endif
2771 } else
2772 snd_m3_convert_from_le(chip->assp_minisrc_image);
2773
2747 if ((err = pci_request_regions(pci, card->driver)) < 0) { 2774 if ((err = pci_request_regions(pci, card->driver)) < 0) {
2748 snd_m3_free(chip); 2775 snd_m3_free(chip);
2749 return err; 2776 return err;
diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c
index 13de0f71d4b7..d7d15c036e02 100644
--- a/sound/pci/mixart/mixart_mixer.c
+++ b/sound/pci/mixart/mixart_mixer.c
@@ -389,7 +389,7 @@ static int mixart_analog_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
389 return changed; 389 return changed;
390} 390}
391 391
392static DECLARE_TLV_DB_SCALE(db_scale_analog, -9600, 50, 0); 392static const DECLARE_TLV_DB_SCALE(db_scale_analog, -9600, 50, 0);
393 393
394static struct snd_kcontrol_new mixart_control_analog_level = { 394static struct snd_kcontrol_new mixart_control_analog_level = {
395 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 395 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -872,7 +872,7 @@ static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem
872 return changed; 872 return changed;
873} 873}
874 874
875static DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0); 875static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0);
876 876
877static struct snd_kcontrol_new snd_mixart_pcm_vol = 877static struct snd_kcontrol_new snd_mixart_pcm_vol =
878{ 878{
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 879e31a9f9c6..03b3a4792f73 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1628,23 +1628,15 @@ __error:
1628} 1628}
1629 1629
1630 1630
1631struct nm256_quirk {
1632 unsigned short vendor;
1633 unsigned short device;
1634 int type;
1635};
1636
1637enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 }; 1631enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 };
1638 1632
1639static struct nm256_quirk nm256_quirks[] __devinitdata = { 1633static struct snd_pci_quirk nm256_quirks[] __devinitdata = {
1640 /* HP omnibook 4150 has cs4232 codec internally */ 1634 /* HP omnibook 4150 has cs4232 codec internally */
1641 { .vendor = 0x103c, .device = 0x0007, .type = NM_BLACKLISTED }, 1635 SND_PCI_QUIRK(0x103c, 0x0007, "HP omnibook 4150", NM_BLACKLISTED),
1642 /* Sony PCG-F305 */ 1636 /* Reset workarounds to avoid lock-ups */
1643 { .vendor = 0x104d, .device = 0x8041, .type = NM_RESET_WORKAROUND }, 1637 SND_PCI_QUIRK(0x104d, 0x8041, "Sony PCG-F305", NM_RESET_WORKAROUND),
1644 /* Dell Latitude LS */ 1638 SND_PCI_QUIRK(0x1028, 0x0080, "Dell Latitude LS", NM_RESET_WORKAROUND),
1645 { .vendor = 0x1028, .device = 0x0080, .type = NM_RESET_WORKAROUND }, 1639 SND_PCI_QUIRK(0x1028, 0x0091, "Dell Latitude CSx", NM_RESET_WORKAROUND_2),
1646 /* Dell Latitude CSx */
1647 { .vendor = 0x1028, .device = 0x0091, .type = NM_RESET_WORKAROUND_2 },
1648 { } /* terminator */ 1640 { } /* terminator */
1649}; 1641};
1650 1642
@@ -1655,26 +1647,22 @@ static int __devinit snd_nm256_probe(struct pci_dev *pci,
1655 struct snd_card *card; 1647 struct snd_card *card;
1656 struct nm256 *chip; 1648 struct nm256 *chip;
1657 int err; 1649 int err;
1658 struct nm256_quirk *q; 1650 const struct snd_pci_quirk *q;
1659 u16 subsystem_vendor, subsystem_device; 1651
1660 1652 q = snd_pci_quirk_lookup(pci, nm256_quirks);
1661 pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); 1653 if (q) {
1662 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device); 1654 snd_printdd(KERN_INFO "nm256: Enabled quirk for %s.\n", q->name);
1663 1655 switch (q->value) {
1664 for (q = nm256_quirks; q->vendor; q++) { 1656 case NM_BLACKLISTED:
1665 if (q->vendor == subsystem_vendor && q->device == subsystem_device) { 1657 printk(KERN_INFO "nm256: The device is blacklisted. "
1666 switch (q->type) { 1658 "Loading stopped\n");
1667 case NM_BLACKLISTED: 1659 return -ENODEV;
1668 printk(KERN_INFO "nm256: The device is blacklisted. " 1660 case NM_RESET_WORKAROUND_2:
1669 "Loading stopped\n"); 1661 reset_workaround_2 = 1;
1670 return -ENODEV; 1662 /* Fall-through */
1671 case NM_RESET_WORKAROUND_2: 1663 case NM_RESET_WORKAROUND:
1672 reset_workaround_2 = 1; 1664 reset_workaround = 1;
1673 /* Fall-through */ 1665 break;
1674 case NM_RESET_WORKAROUND:
1675 reset_workaround = 1;
1676 break;
1677 }
1678 } 1666 }
1679 } 1667 }
1680 1668
diff --git a/sound/pci/pcxhr/pcxhr_mixer.c b/sound/pci/pcxhr/pcxhr_mixer.c
index b133ad9e095e..d9cc8d2beb6d 100644
--- a/sound/pci/pcxhr/pcxhr_mixer.c
+++ b/sound/pci/pcxhr/pcxhr_mixer.c
@@ -44,8 +44,8 @@
44#define PCXHR_ANALOG_PLAYBACK_LEVEL_MAX 128 /* 0.0 dB */ 44#define PCXHR_ANALOG_PLAYBACK_LEVEL_MAX 128 /* 0.0 dB */
45#define PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL 104 /* -24.0 dB ( 0.0 dB - fix level +24.0 dB ) */ 45#define PCXHR_ANALOG_PLAYBACK_ZERO_LEVEL 104 /* -24.0 dB ( 0.0 dB - fix level +24.0 dB ) */
46 46
47static DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 0); 47static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 0);
48static DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -12800, 100, 0); 48static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -12800, 100, 0);
49 49
50static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel) 50static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel)
51{ 51{
@@ -195,7 +195,7 @@ static struct snd_kcontrol_new pcxhr_control_output_switch = {
195#define PCXHR_DIGITAL_LEVEL_MAX 0x1ff /* +18 dB */ 195#define PCXHR_DIGITAL_LEVEL_MAX 0x1ff /* +18 dB */
196#define PCXHR_DIGITAL_ZERO_LEVEL 0x1b7 /* 0 dB */ 196#define PCXHR_DIGITAL_ZERO_LEVEL 0x1b7 /* 0 dB */
197 197
198static DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0); 198static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0);
199 199
200#define MORE_THAN_ONE_STREAM_LEVEL 0x000001 200#define MORE_THAN_ONE_STREAM_LEVEL 0x000001
201#define VALID_STREAM_PAN_LEVEL_MASK 0x800000 201#define VALID_STREAM_PAN_LEVEL_MASK 0x800000
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 6383987b460e..89b3c7ff5037 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -80,6 +80,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
80/* Write registers. These are defined as byte-offsets from the iobase value. 80/* Write registers. These are defined as byte-offsets from the iobase value.
81 */ 81 */
82#define HDSP_resetPointer 0 82#define HDSP_resetPointer 0
83#define HDSP_freqReg 0
83#define HDSP_outputBufferAddress 32 84#define HDSP_outputBufferAddress 32
84#define HDSP_inputBufferAddress 36 85#define HDSP_inputBufferAddress 36
85#define HDSP_controlRegister 64 86#define HDSP_controlRegister 64
@@ -469,6 +470,7 @@ struct hdsp {
469 struct pci_dev *pci; 470 struct pci_dev *pci;
470 struct snd_kcontrol *spdif_ctl; 471 struct snd_kcontrol *spdif_ctl;
471 unsigned short mixer_matrix[HDSP_MATRIX_MIXER_SIZE]; 472 unsigned short mixer_matrix[HDSP_MATRIX_MIXER_SIZE];
473 unsigned int dds_value; /* last value written to freq register */
472}; 474};
473 475
474/* These tables map the ALSA channels 1..N to the channels that we 476/* These tables map the ALSA channels 1..N to the channels that we
@@ -598,6 +600,7 @@ static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out)
598 return (64 * out) + (32 + (in)); 600 return (64 * out) + (32 + (in));
599 case 0x96: 601 case 0x96:
600 case 0x97: 602 case 0x97:
603 case 0x98:
601 return (32 * out) + (16 + (in)); 604 return (32 * out) + (16 + (in));
602 default: 605 default:
603 return (52 * out) + (26 + (in)); 606 return (52 * out) + (26 + (in));
@@ -611,6 +614,7 @@ static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out)
611 return (64 * out) + in; 614 return (64 * out) + in;
612 case 0x96: 615 case 0x96:
613 case 0x97: 616 case 0x97:
617 case 0x98:
614 return (32 * out) + in; 618 return (32 * out) + in;
615 default: 619 default:
616 return (52 * out) + in; 620 return (52 * out) + in;
@@ -938,6 +942,11 @@ static snd_pcm_uframes_t hdsp_hw_pointer(struct hdsp *hdsp)
938static void hdsp_reset_hw_pointer(struct hdsp *hdsp) 942static void hdsp_reset_hw_pointer(struct hdsp *hdsp)
939{ 943{
940 hdsp_write (hdsp, HDSP_resetPointer, 0); 944 hdsp_write (hdsp, HDSP_resetPointer, 0);
945 if (hdsp->io_type == H9632 && hdsp->firmware_rev >= 152)
946 /* HDSP_resetPointer = HDSP_freqReg, which is strange and
947 * requires (?) to write again DDS value after a reset pointer
948 * (at least, it works like this) */
949 hdsp_write (hdsp, HDSP_freqReg, hdsp->dds_value);
941} 950}
942 951
943static void hdsp_start_audio(struct hdsp *s) 952static void hdsp_start_audio(struct hdsp *s)
@@ -982,6 +991,30 @@ static int hdsp_set_interrupt_interval(struct hdsp *s, unsigned int frames)
982 return 0; 991 return 0;
983} 992}
984 993
994static void hdsp_set_dds_value(struct hdsp *hdsp, int rate)
995{
996 u64 n;
997 u32 r;
998
999 if (rate >= 112000)
1000 rate /= 4;
1001 else if (rate >= 56000)
1002 rate /= 2;
1003
1004 /* RME says n = 104857600000000, but in the windows MADI driver, I see:
1005// return 104857600000000 / rate; // 100 MHz
1006 return 110100480000000 / rate; // 105 MHz
1007 */
1008 n = 104857600000000ULL; /* = 2^20 * 10^8 */
1009 div64_32(&n, rate, &r);
1010 /* n should be less than 2^32 for being written to FREQ register */
1011 snd_assert((n >> 32) == 0);
1012 /* HDSP_freqReg and HDSP_resetPointer are the same, so keep the DDS
1013 value to write it after a reset */
1014 hdsp->dds_value = n;
1015 hdsp_write(hdsp, HDSP_freqReg, hdsp->dds_value);
1016}
1017
985static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally) 1018static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally)
986{ 1019{
987 int reject_if_open = 0; 1020 int reject_if_open = 0;
@@ -1090,6 +1123,10 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally)
1090 hdsp->control_register |= rate_bits; 1123 hdsp->control_register |= rate_bits;
1091 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); 1124 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
1092 1125
1126 /* For HDSP9632 rev 152, need to set DDS value in FREQ register */
1127 if (hdsp->io_type == H9632 && hdsp->firmware_rev >= 152)
1128 hdsp_set_dds_value(hdsp, rate);
1129
1093 if (rate >= 128000) { 1130 if (rate >= 128000) {
1094 hdsp->channel_map = channel_map_H9632_qs; 1131 hdsp->channel_map = channel_map_H9632_qs;
1095 } else if (rate > 48000) { 1132 } else if (rate > 48000) {
@@ -4943,6 +4980,7 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
4943 hdsp->irq = pci->irq; 4980 hdsp->irq = pci->irq;
4944 hdsp->precise_ptr = 0; 4981 hdsp->precise_ptr = 0;
4945 hdsp->use_midi_tasklet = 1; 4982 hdsp->use_midi_tasklet = 1;
4983 hdsp->dds_value = 0;
4946 4984
4947 if ((err = snd_hdsp_initialize_memory(hdsp)) < 0) 4985 if ((err = snd_hdsp_initialize_memory(hdsp)) < 0)
4948 return err; 4986 return err;
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 0547f6f04bdc..e0215aca1193 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -6,6 +6,8 @@
6 * code based on hdsp.c Paul Davis 6 * code based on hdsp.c Paul Davis
7 * Marcus Andersson 7 * Marcus Andersson
8 * Thomas Charbonnel 8 * Thomas Charbonnel
9 * Modified 2006-06-01 for AES32 support by Remy Bruno
10 * <remy.bruno@trinnov.com>
9 * 11 *
10 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
@@ -77,7 +79,8 @@ MODULE_PARM_DESC(enable_monitor,
77 79
78MODULE_AUTHOR 80MODULE_AUTHOR
79 ("Winfried Ritsch <ritsch_AT_iem.at>, Paul Davis <paul@linuxaudiosystems.com>, " 81 ("Winfried Ritsch <ritsch_AT_iem.at>, Paul Davis <paul@linuxaudiosystems.com>, "
80 "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>"); 82 "Marcus Andersson, Thomas Charbonnel <thomas@undata.org>, "
83 "Remy Bruno <remy.bruno@trinnov.com>");
81MODULE_DESCRIPTION("RME HDSPM"); 84MODULE_DESCRIPTION("RME HDSPM");
82MODULE_LICENSE("GPL"); 85MODULE_LICENSE("GPL");
83MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); 86MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
@@ -107,7 +110,12 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
107/* --- Read registers. --- 110/* --- Read registers. ---
108 These are defined as byte-offsets from the iobase value */ 111 These are defined as byte-offsets from the iobase value */
109#define HDSPM_statusRegister 0 112#define HDSPM_statusRegister 0
110#define HDSPM_statusRegister2 96 113/*#define HDSPM_statusRegister2 96 */
114/* after RME Windows driver sources, status2 is 4-byte word # 48 = word at
115 * offset 192, for AES32 *and* MADI
116 * => need to check that offset 192 is working on MADI */
117#define HDSPM_statusRegister2 192
118#define HDSPM_timecodeRegister 128
111 119
112#define HDSPM_midiDataIn0 360 120#define HDSPM_midiDataIn0 360
113#define HDSPM_midiDataIn1 364 121#define HDSPM_midiDataIn1 364
@@ -140,37 +148,50 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
140#define HDSPM_Frequency0 (1<<6) /* 0=44.1kHz/88.2kHz 1=48kHz/96kHz */ 148#define HDSPM_Frequency0 (1<<6) /* 0=44.1kHz/88.2kHz 1=48kHz/96kHz */
141#define HDSPM_Frequency1 (1<<7) /* 0=32kHz/64kHz */ 149#define HDSPM_Frequency1 (1<<7) /* 0=32kHz/64kHz */
142#define HDSPM_DoubleSpeed (1<<8) /* 0=normal speed, 1=double speed */ 150#define HDSPM_DoubleSpeed (1<<8) /* 0=normal speed, 1=double speed */
143#define HDSPM_QuadSpeed (1<<31) /* quad speed bit, not implemented now */ 151#define HDSPM_QuadSpeed (1<<31) /* quad speed bit */
144 152
153#define HDSPM_Professional (1<<9) /* Professional */ /* AES32 ONLY */
145#define HDSPM_TX_64ch (1<<10) /* Output 64channel MODE=1, 154#define HDSPM_TX_64ch (1<<10) /* Output 64channel MODE=1,
146 56channelMODE=0 */ 155 56channelMODE=0 */ /* MADI ONLY*/
156#define HDSPM_Emphasis (1<<10) /* Emphasis */ /* AES32 ONLY */
147 157
148#define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode, 158#define HDSPM_AutoInp (1<<11) /* Auto Input (takeover) == Safe Mode,
149 0=off, 1=on */ 159 0=off, 1=on */ /* MADI ONLY */
160#define HDSPM_Dolby (1<<11) /* Dolby = "NonAudio" ?? */ /* AES32 ONLY */
150 161
151#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax */ 162#define HDSPM_InputSelect0 (1<<14) /* Input select 0= optical, 1=coax */ /* MADI ONLY*/
152#define HDSPM_InputSelect1 (1<<15) /* should be 0 */ 163#define HDSPM_InputSelect1 (1<<15) /* should be 0 */
153 164
154#define HDSPM_SyncRef0 (1<<16) /* 0=WOrd, 1=MADI */ 165#define HDSPM_SyncRef0 (1<<16) /* 0=WOrd, 1=MADI */
155#define HDSPM_SyncRef1 (1<<17) /* should be 0 */ 166#define HDSPM_SyncRef1 (1<<17) /* for AES32: SyncRefN codes the AES # */
167#define HDSPM_SyncRef2 (1<<13)
168#define HDSPM_SyncRef3 (1<<25)
156 169
170#define HDSPM_SMUX (1<<18) /* Frame ??? */ /* MADI ONY */
157#define HDSPM_clr_tms (1<<19) /* clear track marker, do not use 171#define HDSPM_clr_tms (1<<19) /* clear track marker, do not use
158 AES additional bits in 172 AES additional bits in
159 lower 5 Audiodatabits ??? */ 173 lower 5 Audiodatabits ??? */
174#define HDSPM_taxi_reset (1<<20) /* ??? */ /* MADI ONLY ? */
175#define HDSPM_WCK48 (1<<20) /* Frame ??? = HDSPM_SMUX */ /* AES32 ONLY */
160 176
161#define HDSPM_Midi0InterruptEnable (1<<22) 177#define HDSPM_Midi0InterruptEnable (1<<22)
162#define HDSPM_Midi1InterruptEnable (1<<23) 178#define HDSPM_Midi1InterruptEnable (1<<23)
163 179
164#define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */ 180#define HDSPM_LineOut (1<<24) /* Analog Out on channel 63/64 on=1, mute=0 */
165 181
182#define HDSPM_DS_DoubleWire (1<<26) /* AES32 ONLY */
183#define HDSPM_QS_DoubleWire (1<<27) /* AES32 ONLY */
184#define HDSPM_QS_QuadWire (1<<28) /* AES32 ONLY */
185
186#define HDSPM_wclk_sel (1<<30)
166 187
167/* --- bit helper defines */ 188/* --- bit helper defines */
168#define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2) 189#define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2)
169#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1) 190#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|HDSPM_DoubleSpeed|HDSPM_QuadSpeed)
170#define HDSPM_InputMask (HDSPM_InputSelect0|HDSPM_InputSelect1) 191#define HDSPM_InputMask (HDSPM_InputSelect0|HDSPM_InputSelect1)
171#define HDSPM_InputOptical 0 192#define HDSPM_InputOptical 0
172#define HDSPM_InputCoaxial (HDSPM_InputSelect0) 193#define HDSPM_InputCoaxial (HDSPM_InputSelect0)
173#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1) 194#define HDSPM_SyncRefMask (HDSPM_SyncRef0|HDSPM_SyncRef1|HDSPM_SyncRef2|HDSPM_SyncRef3)
174#define HDSPM_SyncRef_Word 0 195#define HDSPM_SyncRef_Word 0
175#define HDSPM_SyncRef_MADI (HDSPM_SyncRef0) 196#define HDSPM_SyncRef_MADI (HDSPM_SyncRef0)
176 197
@@ -183,6 +204,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
183#define HDSPM_Frequency64KHz (HDSPM_DoubleSpeed|HDSPM_Frequency0) 204#define HDSPM_Frequency64KHz (HDSPM_DoubleSpeed|HDSPM_Frequency0)
184#define HDSPM_Frequency88_2KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1) 205#define HDSPM_Frequency88_2KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1)
185#define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|HDSPM_Frequency0) 206#define HDSPM_Frequency96KHz (HDSPM_DoubleSpeed|HDSPM_Frequency1|HDSPM_Frequency0)
207#define HDSPM_Frequency128KHz (HDSPM_QuadSpeed|HDSPM_Frequency0)
208#define HDSPM_Frequency176_4KHz (HDSPM_QuadSpeed|HDSPM_Frequency1)
209#define HDSPM_Frequency192KHz (HDSPM_QuadSpeed|HDSPM_Frequency1|HDSPM_Frequency0)
186 210
187/* --- for internal discrimination */ 211/* --- for internal discrimination */
188#define HDSPM_CLOCK_SOURCE_AUTOSYNC 0 /* Sample Clock Sources */ 212#define HDSPM_CLOCK_SOURCE_AUTOSYNC 0 /* Sample Clock Sources */
@@ -229,7 +253,8 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
229#define HDSPM_BIGENDIAN_MODE (1<<9) 253#define HDSPM_BIGENDIAN_MODE (1<<9)
230#define HDSPM_RD_MULTIPLE (1<<10) 254#define HDSPM_RD_MULTIPLE (1<<10)
231 255
232/* --- Status Register bits --- */ 256/* --- Status Register bits --- */ /* MADI ONLY */ /* Bits defined here and
257 that do not conflict with specific bits for AES32 seem to be valid also for the AES32 */
233#define HDSPM_audioIRQPending (1<<0) /* IRQ is high and pending */ 258#define HDSPM_audioIRQPending (1<<0) /* IRQ is high and pending */
234#define HDSPM_RX_64ch (1<<1) /* Input 64chan. MODE=1, 56chn. MODE=0 */ 259#define HDSPM_RX_64ch (1<<1) /* Input 64chan. MODE=1, 56chn. MODE=0 */
235#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1 (like inp0) */ 260#define HDSPM_AB_int (1<<2) /* InputChannel Opt=0, Coax=1 (like inp0) */
@@ -263,7 +288,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
263#define HDSPM_madiFreq176_4 (HDSPM_madiFreq3) 288#define HDSPM_madiFreq176_4 (HDSPM_madiFreq3)
264#define HDSPM_madiFreq192 (HDSPM_madiFreq3|HDSPM_madiFreq0) 289#define HDSPM_madiFreq192 (HDSPM_madiFreq3|HDSPM_madiFreq0)
265 290
266/* Status2 Register bits */ 291/* Status2 Register bits */ /* MADI ONLY */
267 292
268#define HDSPM_version0 (1<<0) /* not realy defined but I guess */ 293#define HDSPM_version0 (1<<0) /* not realy defined but I guess */
269#define HDSPM_version1 (1<<1) /* in former cards it was ??? */ 294#define HDSPM_version1 (1<<1) /* in former cards it was ??? */
@@ -297,6 +322,56 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
297#define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0) 322#define HDSPM_SelSyncRef_MADI (HDSPM_SelSyncRef0)
298#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2) 323#define HDSPM_SelSyncRef_NVALID (HDSPM_SelSyncRef0|HDSPM_SelSyncRef1|HDSPM_SelSyncRef2)
299 324
325/*
326 For AES32, bits for status, status2 and timecode are different
327*/
328/* status */
329#define HDSPM_AES32_wcLock 0x0200000
330#define HDSPM_AES32_wcFreq_bit 22
331/* (status >> HDSPM_AES32_wcFreq_bit) & 0xF gives WC frequency (cf function
332 HDSPM_bit2freq */
333#define HDSPM_AES32_syncref_bit 16
334/* (status >> HDSPM_AES32_syncref_bit) & 0xF gives sync source */
335
336#define HDSPM_AES32_AUTOSYNC_FROM_WORD 0
337#define HDSPM_AES32_AUTOSYNC_FROM_AES1 1
338#define HDSPM_AES32_AUTOSYNC_FROM_AES2 2
339#define HDSPM_AES32_AUTOSYNC_FROM_AES3 3
340#define HDSPM_AES32_AUTOSYNC_FROM_AES4 4
341#define HDSPM_AES32_AUTOSYNC_FROM_AES5 5
342#define HDSPM_AES32_AUTOSYNC_FROM_AES6 6
343#define HDSPM_AES32_AUTOSYNC_FROM_AES7 7
344#define HDSPM_AES32_AUTOSYNC_FROM_AES8 8
345#define HDSPM_AES32_AUTOSYNC_FROM_NONE -1
346
347/* status2 */
348/* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */
349#define HDSPM_LockAES 0x80
350#define HDSPM_LockAES1 0x80
351#define HDSPM_LockAES2 0x40
352#define HDSPM_LockAES3 0x20
353#define HDSPM_LockAES4 0x10
354#define HDSPM_LockAES5 0x8
355#define HDSPM_LockAES6 0x4
356#define HDSPM_LockAES7 0x2
357#define HDSPM_LockAES8 0x1
358/*
359 Timecode
360 After windows driver sources, bits 4*i to 4*i+3 give the input frequency on
361 AES i+1
362 bits 3210
363 0001 32kHz
364 0010 44.1kHz
365 0011 48kHz
366 0100 64kHz
367 0101 88.2kHz
368 0110 96kHz
369 0111 128kHz
370 1000 176.4kHz
371 1001 192kHz
372 NB: Timecode register doesn't seem to work on AES32 card revision 230
373*/
374
300/* Mixer Values */ 375/* Mixer Values */
301#define UNITY_GAIN 32768 /* = 65536/2 */ 376#define UNITY_GAIN 32768 /* = 65536/2 */
302#define MINUS_INFINITY_GAIN 0 377#define MINUS_INFINITY_GAIN 0
@@ -314,10 +389,14 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
314 size is the same regardless of the number of channels, and 389 size is the same regardless of the number of channels, and
315 also the latency to use. 390 also the latency to use.
316 for one direction !!! 391 for one direction !!!
392 => need to mupltiply by 2!!
317*/ 393*/
318#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) 394#define HDSPM_DMA_AREA_BYTES (2 * HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES)
319#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) 395#define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024)
320 396
397/* revisions >= 230 indicate AES32 card */
398#define HDSPM_AESREVISION 230
399
321struct hdspm_midi { 400struct hdspm_midi {
322 struct hdspm *hdspm; 401 struct hdspm *hdspm;
323 int id; 402 int id;
@@ -336,7 +415,9 @@ struct hdspm {
336 struct snd_pcm_substream *playback_substream; /* and/or capture stream */ 415 struct snd_pcm_substream *playback_substream; /* and/or capture stream */
337 416
338 char *card_name; /* for procinfo */ 417 char *card_name; /* for procinfo */
339 unsigned short firmware_rev; /* dont know if relevant */ 418 unsigned short firmware_rev; /* dont know if relevant (yes if AES32)*/
419
420 unsigned char is_aes32; /* indicates if card is AES32 */
340 421
341 int precise_ptr; /* use precise pointers, to be tested */ 422 int precise_ptr; /* use precise pointers, to be tested */
342 int monitor_outs; /* set up monitoring outs init flag */ 423 int monitor_outs; /* set up monitoring outs init flag */
@@ -453,6 +534,15 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm);
453static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf, 534static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf,
454 unsigned int reg, int channels); 535 unsigned int reg, int channels);
455 536
537static inline int HDSPM_bit2freq(int n)
538{
539 static int bit2freq_tab[] = { 0, 32000, 44100, 48000, 64000, 88200,
540 96000, 128000, 176400, 192000 };
541 if (n < 1 || n > 9)
542 return 0;
543 return bit2freq_tab[n];
544}
545
456/* Write/read to/from HDSPM with Adresses in Bytes 546/* Write/read to/from HDSPM with Adresses in Bytes
457 not words but only 32Bit writes are allowed */ 547 not words but only 32Bit writes are allowed */
458 548
@@ -544,86 +634,105 @@ static inline int snd_hdspm_use_is_exclusive(struct hdspm * hdspm)
544/* check for external sample rate */ 634/* check for external sample rate */
545static inline int hdspm_external_sample_rate(struct hdspm * hdspm) 635static inline int hdspm_external_sample_rate(struct hdspm * hdspm)
546{ 636{
547 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 637 if (hdspm->is_aes32) {
548 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); 638 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
549 unsigned int rate_bits; 639 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
550 int rate = 0; 640 unsigned int timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
641
642 int syncref = hdspm_autosync_ref(hdspm);
643
644 if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD &&
645 status & HDSPM_AES32_wcLock)
646 return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF);
647 if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 &&
648 syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 &&
649 status2 & (HDSPM_LockAES >>
650 (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1)))
651 return HDSPM_bit2freq((timecode >>
652 (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF);
653 return 0;
654 } else {
655 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
656 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
657 unsigned int rate_bits;
658 int rate = 0;
551 659
552 /* if wordclock has synced freq and wordclock is valid */ 660 /* if wordclock has synced freq and wordclock is valid */
553 if ((status2 & HDSPM_wcLock) != 0 && 661 if ((status2 & HDSPM_wcLock) != 0 &&
554 (status & HDSPM_SelSyncRef0) == 0) { 662 (status & HDSPM_SelSyncRef0) == 0) {
555 663
556 rate_bits = status2 & HDSPM_wcFreqMask; 664 rate_bits = status2 & HDSPM_wcFreqMask;
557 665
558 switch (rate_bits) { 666 switch (rate_bits) {
559 case HDSPM_wcFreq32: 667 case HDSPM_wcFreq32:
560 rate = 32000; 668 rate = 32000;
561 break; 669 break;
562 case HDSPM_wcFreq44_1: 670 case HDSPM_wcFreq44_1:
563 rate = 44100; 671 rate = 44100;
564 break; 672 break;
565 case HDSPM_wcFreq48: 673 case HDSPM_wcFreq48:
566 rate = 48000; 674 rate = 48000;
567 break; 675 break;
568 case HDSPM_wcFreq64: 676 case HDSPM_wcFreq64:
569 rate = 64000; 677 rate = 64000;
570 break; 678 break;
571 case HDSPM_wcFreq88_2: 679 case HDSPM_wcFreq88_2:
572 rate = 88200; 680 rate = 88200;
573 break; 681 break;
574 case HDSPM_wcFreq96: 682 case HDSPM_wcFreq96:
575 rate = 96000; 683 rate = 96000;
576 break; 684 break;
577 /* Quadspeed Bit missing ???? */ 685 /* Quadspeed Bit missing ???? */
578 default: 686 default:
579 rate = 0; 687 rate = 0;
580 break; 688 break;
689 }
581 } 690 }
582 }
583 691
584 /* if rate detected and Syncref is Word than have it, word has priority to MADI */ 692 /* if rate detected and Syncref is Word than have it, word has priority to MADI */
585 if (rate != 0 693 if (rate != 0 &&
586 && (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD) 694 (status2 & HDSPM_SelSyncRefMask) == HDSPM_SelSyncRef_WORD)
587 return rate; 695 return rate;
588 696
589 /* maby a madi input (which is taken if sel sync is madi) */ 697 /* maby a madi input (which is taken if sel sync is madi) */
590 if (status & HDSPM_madiLock) { 698 if (status & HDSPM_madiLock) {
591 rate_bits = status & HDSPM_madiFreqMask; 699 rate_bits = status & HDSPM_madiFreqMask;
592 700
593 switch (rate_bits) { 701 switch (rate_bits) {
594 case HDSPM_madiFreq32: 702 case HDSPM_madiFreq32:
595 rate = 32000; 703 rate = 32000;
596 break; 704 break;
597 case HDSPM_madiFreq44_1: 705 case HDSPM_madiFreq44_1:
598 rate = 44100; 706 rate = 44100;
599 break; 707 break;
600 case HDSPM_madiFreq48: 708 case HDSPM_madiFreq48:
601 rate = 48000; 709 rate = 48000;
602 break; 710 break;
603 case HDSPM_madiFreq64: 711 case HDSPM_madiFreq64:
604 rate = 64000; 712 rate = 64000;
605 break; 713 break;
606 case HDSPM_madiFreq88_2: 714 case HDSPM_madiFreq88_2:
607 rate = 88200; 715 rate = 88200;
608 break; 716 break;
609 case HDSPM_madiFreq96: 717 case HDSPM_madiFreq96:
610 rate = 96000; 718 rate = 96000;
611 break; 719 break;
612 case HDSPM_madiFreq128: 720 case HDSPM_madiFreq128:
613 rate = 128000; 721 rate = 128000;
614 break; 722 break;
615 case HDSPM_madiFreq176_4: 723 case HDSPM_madiFreq176_4:
616 rate = 176400; 724 rate = 176400;
617 break; 725 break;
618 case HDSPM_madiFreq192: 726 case HDSPM_madiFreq192:
619 rate = 192000; 727 rate = 192000;
620 break; 728 break;
621 default: 729 default:
622 rate = 0; 730 rate = 0;
623 break; 731 break;
732 }
624 } 733 }
734 return rate;
625 } 735 }
626 return rate;
627} 736}
628 737
629/* Latency function */ 738/* Latency function */
@@ -676,7 +785,8 @@ static inline void hdspm_silence_playback(struct hdspm * hdspm)
676 int n = hdspm->period_bytes; 785 int n = hdspm->period_bytes;
677 void *buf = hdspm->playback_buffer; 786 void *buf = hdspm->playback_buffer;
678 787
679 snd_assert(buf != NULL, return); 788 if (buf == NULL)
789 return;
680 790
681 for (i = 0; i < HDSPM_MAX_CHANNELS; i++) { 791 for (i = 0; i < HDSPM_MAX_CHANNELS; i++) {
682 memset(buf, 0, n); 792 memset(buf, 0, n);
@@ -716,6 +826,7 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
716 int current_rate; 826 int current_rate;
717 int rate_bits; 827 int rate_bits;
718 int not_set = 0; 828 int not_set = 0;
829 int is_single, is_double, is_quad;
719 830
720 /* ASSUMPTION: hdspm->lock is either set, or there is no need for 831 /* ASSUMPTION: hdspm->lock is either set, or there is no need for
721 it (e.g. during module initialization). 832 it (e.g. during module initialization).
@@ -766,43 +877,56 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
766 changes in the read/write routines. 877 changes in the read/write routines.
767 */ 878 */
768 879
880 is_single = (current_rate <= 48000);
881 is_double = (current_rate > 48000 && current_rate <= 96000);
882 is_quad = (current_rate > 96000);
883
769 switch (rate) { 884 switch (rate) {
770 case 32000: 885 case 32000:
771 if (current_rate > 48000) { 886 if (!is_single)
772 reject_if_open = 1; 887 reject_if_open = 1;
773 }
774 rate_bits = HDSPM_Frequency32KHz; 888 rate_bits = HDSPM_Frequency32KHz;
775 break; 889 break;
776 case 44100: 890 case 44100:
777 if (current_rate > 48000) { 891 if (!is_single)
778 reject_if_open = 1; 892 reject_if_open = 1;
779 }
780 rate_bits = HDSPM_Frequency44_1KHz; 893 rate_bits = HDSPM_Frequency44_1KHz;
781 break; 894 break;
782 case 48000: 895 case 48000:
783 if (current_rate > 48000) { 896 if (!is_single)
784 reject_if_open = 1; 897 reject_if_open = 1;
785 }
786 rate_bits = HDSPM_Frequency48KHz; 898 rate_bits = HDSPM_Frequency48KHz;
787 break; 899 break;
788 case 64000: 900 case 64000:
789 if (current_rate <= 48000) { 901 if (!is_double)
790 reject_if_open = 1; 902 reject_if_open = 1;
791 }
792 rate_bits = HDSPM_Frequency64KHz; 903 rate_bits = HDSPM_Frequency64KHz;
793 break; 904 break;
794 case 88200: 905 case 88200:
795 if (current_rate <= 48000) { 906 if (!is_double)
796 reject_if_open = 1; 907 reject_if_open = 1;
797 }
798 rate_bits = HDSPM_Frequency88_2KHz; 908 rate_bits = HDSPM_Frequency88_2KHz;
799 break; 909 break;
800 case 96000: 910 case 96000:
801 if (current_rate <= 48000) { 911 if (!is_double)
802 reject_if_open = 1; 912 reject_if_open = 1;
803 }
804 rate_bits = HDSPM_Frequency96KHz; 913 rate_bits = HDSPM_Frequency96KHz;
805 break; 914 break;
915 case 128000:
916 if (!is_quad)
917 reject_if_open = 1;
918 rate_bits = HDSPM_Frequency128KHz;
919 break;
920 case 176400:
921 if (!is_quad)
922 reject_if_open = 1;
923 rate_bits = HDSPM_Frequency176_4KHz;
924 break;
925 case 192000:
926 if (!is_quad)
927 reject_if_open = 1;
928 rate_bits = HDSPM_Frequency192KHz;
929 break;
806 default: 930 default:
807 return -EINVAL; 931 return -EINVAL;
808 } 932 }
@@ -819,7 +943,7 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally)
819 hdspm->control_register |= rate_bits; 943 hdspm->control_register |= rate_bits;
820 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 944 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
821 945
822 if (rate > 64000) 946 if (rate > 96000 /* 64000*/)
823 hdspm->channel_map = channel_map_madi_qs; 947 hdspm->channel_map = channel_map_madi_qs;
824 else if (rate > 48000) 948 else if (rate > 48000)
825 hdspm->channel_map = channel_map_madi_ds; 949 hdspm->channel_map = channel_map_madi_ds;
@@ -1455,11 +1579,27 @@ static int hdspm_pref_sync_ref(struct hdspm * hdspm)
1455 /* Notice that this looks at the requested sync source, 1579 /* Notice that this looks at the requested sync source,
1456 not the one actually in use. 1580 not the one actually in use.
1457 */ 1581 */
1458 switch (hdspm->control_register & HDSPM_SyncRefMask) { 1582 if (hdspm->is_aes32) {
1459 case HDSPM_SyncRef_Word: 1583 switch (hdspm->control_register & HDSPM_SyncRefMask) {
1460 return HDSPM_SYNC_FROM_WORD; 1584 /* number gives AES index, except for 0 which
1461 case HDSPM_SyncRef_MADI: 1585 corresponds to WordClock */
1462 return HDSPM_SYNC_FROM_MADI; 1586 case 0: return 0;
1587 case HDSPM_SyncRef0: return 1;
1588 case HDSPM_SyncRef1: return 2;
1589 case HDSPM_SyncRef1+HDSPM_SyncRef0: return 3;
1590 case HDSPM_SyncRef2: return 4;
1591 case HDSPM_SyncRef2+HDSPM_SyncRef0: return 5;
1592 case HDSPM_SyncRef2+HDSPM_SyncRef1: return 6;
1593 case HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0: return 7;
1594 case HDSPM_SyncRef3: return 8;
1595 }
1596 } else {
1597 switch (hdspm->control_register & HDSPM_SyncRefMask) {
1598 case HDSPM_SyncRef_Word:
1599 return HDSPM_SYNC_FROM_WORD;
1600 case HDSPM_SyncRef_MADI:
1601 return HDSPM_SYNC_FROM_MADI;
1602 }
1463 } 1603 }
1464 1604
1465 return HDSPM_SYNC_FROM_WORD; 1605 return HDSPM_SYNC_FROM_WORD;
@@ -1469,15 +1609,49 @@ static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref)
1469{ 1609{
1470 hdspm->control_register &= ~HDSPM_SyncRefMask; 1610 hdspm->control_register &= ~HDSPM_SyncRefMask;
1471 1611
1472 switch (pref) { 1612 if (hdspm->is_aes32) {
1473 case HDSPM_SYNC_FROM_MADI: 1613 switch (pref) {
1474 hdspm->control_register |= HDSPM_SyncRef_MADI; 1614 case 0:
1475 break; 1615 hdspm->control_register |= 0;
1476 case HDSPM_SYNC_FROM_WORD: 1616 break;
1477 hdspm->control_register |= HDSPM_SyncRef_Word; 1617 case 1:
1478 break; 1618 hdspm->control_register |= HDSPM_SyncRef0;
1479 default: 1619 break;
1480 return -1; 1620 case 2:
1621 hdspm->control_register |= HDSPM_SyncRef1;
1622 break;
1623 case 3:
1624 hdspm->control_register |= HDSPM_SyncRef1+HDSPM_SyncRef0;
1625 break;
1626 case 4:
1627 hdspm->control_register |= HDSPM_SyncRef2;
1628 break;
1629 case 5:
1630 hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef0;
1631 break;
1632 case 6:
1633 hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1;
1634 break;
1635 case 7:
1636 hdspm->control_register |= HDSPM_SyncRef2+HDSPM_SyncRef1+HDSPM_SyncRef0;
1637 break;
1638 case 8:
1639 hdspm->control_register |= HDSPM_SyncRef3;
1640 break;
1641 default:
1642 return -1;
1643 }
1644 } else {
1645 switch (pref) {
1646 case HDSPM_SYNC_FROM_MADI:
1647 hdspm->control_register |= HDSPM_SyncRef_MADI;
1648 break;
1649 case HDSPM_SYNC_FROM_WORD:
1650 hdspm->control_register |= HDSPM_SyncRef_Word;
1651 break;
1652 default:
1653 return -1;
1654 }
1481 } 1655 }
1482 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 1656 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
1483 return 0; 1657 return 0;
@@ -1486,18 +1660,36 @@ static int hdspm_set_pref_sync_ref(struct hdspm * hdspm, int pref)
1486static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol, 1660static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol,
1487 struct snd_ctl_elem_info *uinfo) 1661 struct snd_ctl_elem_info *uinfo)
1488{ 1662{
1489 static char *texts[] = { "Word", "MADI" }; 1663 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1490 1664
1491 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1665 if (hdspm->is_aes32) {
1492 uinfo->count = 1; 1666 static char *texts[] = { "Word", "AES1", "AES2", "AES3",
1667 "AES4", "AES5", "AES6", "AES7", "AES8" };
1493 1668
1494 uinfo->value.enumerated.items = 2; 1669 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1670 uinfo->count = 1;
1495 1671
1496 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 1672 uinfo->value.enumerated.items = 9;
1497 uinfo->value.enumerated.item = 1673
1498 uinfo->value.enumerated.items - 1; 1674 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1499 strcpy(uinfo->value.enumerated.name, 1675 uinfo->value.enumerated.item =
1500 texts[uinfo->value.enumerated.item]); 1676 uinfo->value.enumerated.items - 1;
1677 strcpy(uinfo->value.enumerated.name,
1678 texts[uinfo->value.enumerated.item]);
1679 } else {
1680 static char *texts[] = { "Word", "MADI" };
1681
1682 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1683 uinfo->count = 1;
1684
1685 uinfo->value.enumerated.items = 2;
1686
1687 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1688 uinfo->value.enumerated.item =
1689 uinfo->value.enumerated.items - 1;
1690 strcpy(uinfo->value.enumerated.name,
1691 texts[uinfo->value.enumerated.item]);
1692 }
1501 return 0; 1693 return 0;
1502} 1694}
1503 1695
@@ -1517,7 +1709,7 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
1517 int change, max; 1709 int change, max;
1518 unsigned int val; 1710 unsigned int val;
1519 1711
1520 max = 2; 1712 max = hdspm->is_aes32 ? 9 : 2;
1521 1713
1522 if (!snd_hdspm_use_is_exclusive(hdspm)) 1714 if (!snd_hdspm_use_is_exclusive(hdspm))
1523 return -EBUSY; 1715 return -EBUSY;
@@ -1542,40 +1734,64 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
1542 1734
1543static int hdspm_autosync_ref(struct hdspm * hdspm) 1735static int hdspm_autosync_ref(struct hdspm * hdspm)
1544{ 1736{
1545 /* This looks at the autosync selected sync reference */ 1737 if (hdspm->is_aes32) {
1546 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 1738 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
1547 1739 unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 0xF;
1548 switch (status2 & HDSPM_SelSyncRefMask) { 1740 if (syncref == 0)
1549 1741 return HDSPM_AES32_AUTOSYNC_FROM_WORD;
1550 case HDSPM_SelSyncRef_WORD: 1742 if (syncref <= 8)
1551 return HDSPM_AUTOSYNC_FROM_WORD; 1743 return syncref;
1552 1744 return HDSPM_AES32_AUTOSYNC_FROM_NONE;
1553 case HDSPM_SelSyncRef_MADI: 1745 } else {
1554 return HDSPM_AUTOSYNC_FROM_MADI; 1746 /* This looks at the autosync selected sync reference */
1555 1747 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
1556 case HDSPM_SelSyncRef_NVALID: 1748
1557 return HDSPM_AUTOSYNC_FROM_NONE; 1749 switch (status2 & HDSPM_SelSyncRefMask) {
1750 case HDSPM_SelSyncRef_WORD:
1751 return HDSPM_AUTOSYNC_FROM_WORD;
1752 case HDSPM_SelSyncRef_MADI:
1753 return HDSPM_AUTOSYNC_FROM_MADI;
1754 case HDSPM_SelSyncRef_NVALID:
1755 return HDSPM_AUTOSYNC_FROM_NONE;
1756 default:
1757 return 0;
1758 }
1558 1759
1559 default:
1560 return 0; 1760 return 0;
1561 } 1761 }
1562
1563 return 0;
1564} 1762}
1565 1763
1566static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol, 1764static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
1567 struct snd_ctl_elem_info *uinfo) 1765 struct snd_ctl_elem_info *uinfo)
1568{ 1766{
1569 static char *texts[] = { "WordClock", "MADI", "None" }; 1767 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
1570 1768
1571 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1769 if (hdspm->is_aes32) {
1572 uinfo->count = 1; 1770 static char *texts[] = { "WordClock", "AES1", "AES2", "AES3",
1573 uinfo->value.enumerated.items = 3; 1771 "AES4", "AES5", "AES6", "AES7", "AES8", "None"};
1574 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 1772
1575 uinfo->value.enumerated.item = 1773 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1576 uinfo->value.enumerated.items - 1; 1774 uinfo->count = 1;
1577 strcpy(uinfo->value.enumerated.name, 1775 uinfo->value.enumerated.items = 10;
1578 texts[uinfo->value.enumerated.item]); 1776 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1777 uinfo->value.enumerated.item =
1778 uinfo->value.enumerated.items - 1;
1779 strcpy(uinfo->value.enumerated.name,
1780 texts[uinfo->value.enumerated.item]);
1781 }
1782 else
1783 {
1784 static char *texts[] = { "WordClock", "MADI", "None" };
1785
1786 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1787 uinfo->count = 1;
1788 uinfo->value.enumerated.items = 3;
1789 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1790 uinfo->value.enumerated.item =
1791 uinfo->value.enumerated.items - 1;
1792 strcpy(uinfo->value.enumerated.name,
1793 texts[uinfo->value.enumerated.item]);
1794 }
1579 return 0; 1795 return 0;
1580} 1796}
1581 1797
@@ -1841,6 +2057,195 @@ static int snd_hdspm_put_safe_mode(struct snd_kcontrol *kcontrol,
1841 return change; 2057 return change;
1842} 2058}
1843 2059
2060#define HDSPM_EMPHASIS(xname, xindex) \
2061{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2062 .name = xname, \
2063 .index = xindex, \
2064 .info = snd_hdspm_info_emphasis, \
2065 .get = snd_hdspm_get_emphasis, \
2066 .put = snd_hdspm_put_emphasis \
2067}
2068
2069static int hdspm_emphasis(struct hdspm * hdspm)
2070{
2071 return (hdspm->control_register & HDSPM_Emphasis) ? 1 : 0;
2072}
2073
2074static int hdspm_set_emphasis(struct hdspm * hdspm, int emp)
2075{
2076 if (emp)
2077 hdspm->control_register |= HDSPM_Emphasis;
2078 else
2079 hdspm->control_register &= ~HDSPM_Emphasis;
2080 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
2081
2082 return 0;
2083}
2084
2085static int snd_hdspm_info_emphasis(struct snd_kcontrol *kcontrol,
2086 struct snd_ctl_elem_info *uinfo)
2087{
2088 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2089 uinfo->count = 1;
2090 uinfo->value.integer.min = 0;
2091 uinfo->value.integer.max = 1;
2092 return 0;
2093}
2094
2095static int snd_hdspm_get_emphasis(struct snd_kcontrol *kcontrol,
2096 struct snd_ctl_elem_value *ucontrol)
2097{
2098 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2099
2100 spin_lock_irq(&hdspm->lock);
2101 ucontrol->value.enumerated.item[0] = hdspm_emphasis(hdspm);
2102 spin_unlock_irq(&hdspm->lock);
2103 return 0;
2104}
2105
2106static int snd_hdspm_put_emphasis(struct snd_kcontrol *kcontrol,
2107 struct snd_ctl_elem_value *ucontrol)
2108{
2109 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2110 int change;
2111 unsigned int val;
2112
2113 if (!snd_hdspm_use_is_exclusive(hdspm))
2114 return -EBUSY;
2115 val = ucontrol->value.integer.value[0] & 1;
2116 spin_lock_irq(&hdspm->lock);
2117 change = (int) val != hdspm_emphasis(hdspm);
2118 hdspm_set_emphasis(hdspm, val);
2119 spin_unlock_irq(&hdspm->lock);
2120 return change;
2121}
2122
2123#define HDSPM_DOLBY(xname, xindex) \
2124{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2125 .name = xname, \
2126 .index = xindex, \
2127 .info = snd_hdspm_info_dolby, \
2128 .get = snd_hdspm_get_dolby, \
2129 .put = snd_hdspm_put_dolby \
2130}
2131
2132static int hdspm_dolby(struct hdspm * hdspm)
2133{
2134 return (hdspm->control_register & HDSPM_Dolby) ? 1 : 0;
2135}
2136
2137static int hdspm_set_dolby(struct hdspm * hdspm, int dol)
2138{
2139 if (dol)
2140 hdspm->control_register |= HDSPM_Dolby;
2141 else
2142 hdspm->control_register &= ~HDSPM_Dolby;
2143 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
2144
2145 return 0;
2146}
2147
2148static int snd_hdspm_info_dolby(struct snd_kcontrol *kcontrol,
2149 struct snd_ctl_elem_info *uinfo)
2150{
2151 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2152 uinfo->count = 1;
2153 uinfo->value.integer.min = 0;
2154 uinfo->value.integer.max = 1;
2155 return 0;
2156}
2157
2158static int snd_hdspm_get_dolby(struct snd_kcontrol *kcontrol,
2159 struct snd_ctl_elem_value *ucontrol)
2160{
2161 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2162
2163 spin_lock_irq(&hdspm->lock);
2164 ucontrol->value.enumerated.item[0] = hdspm_dolby(hdspm);
2165 spin_unlock_irq(&hdspm->lock);
2166 return 0;
2167}
2168
2169static int snd_hdspm_put_dolby(struct snd_kcontrol *kcontrol,
2170 struct snd_ctl_elem_value *ucontrol)
2171{
2172 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2173 int change;
2174 unsigned int val;
2175
2176 if (!snd_hdspm_use_is_exclusive(hdspm))
2177 return -EBUSY;
2178 val = ucontrol->value.integer.value[0] & 1;
2179 spin_lock_irq(&hdspm->lock);
2180 change = (int) val != hdspm_dolby(hdspm);
2181 hdspm_set_dolby(hdspm, val);
2182 spin_unlock_irq(&hdspm->lock);
2183 return change;
2184}
2185
2186#define HDSPM_PROFESSIONAL(xname, xindex) \
2187{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2188 .name = xname, \
2189 .index = xindex, \
2190 .info = snd_hdspm_info_professional, \
2191 .get = snd_hdspm_get_professional, \
2192 .put = snd_hdspm_put_professional \
2193}
2194
2195static int hdspm_professional(struct hdspm * hdspm)
2196{
2197 return (hdspm->control_register & HDSPM_Professional) ? 1 : 0;
2198}
2199
2200static int hdspm_set_professional(struct hdspm * hdspm, int dol)
2201{
2202 if (dol)
2203 hdspm->control_register |= HDSPM_Professional;
2204 else
2205 hdspm->control_register &= ~HDSPM_Professional;
2206 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
2207
2208 return 0;
2209}
2210
2211static int snd_hdspm_info_professional(struct snd_kcontrol *kcontrol,
2212 struct snd_ctl_elem_info *uinfo)
2213{
2214 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2215 uinfo->count = 1;
2216 uinfo->value.integer.min = 0;
2217 uinfo->value.integer.max = 1;
2218 return 0;
2219}
2220
2221static int snd_hdspm_get_professional(struct snd_kcontrol *kcontrol,
2222 struct snd_ctl_elem_value *ucontrol)
2223{
2224 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2225
2226 spin_lock_irq(&hdspm->lock);
2227 ucontrol->value.enumerated.item[0] = hdspm_professional(hdspm);
2228 spin_unlock_irq(&hdspm->lock);
2229 return 0;
2230}
2231
2232static int snd_hdspm_put_professional(struct snd_kcontrol *kcontrol,
2233 struct snd_ctl_elem_value *ucontrol)
2234{
2235 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2236 int change;
2237 unsigned int val;
2238
2239 if (!snd_hdspm_use_is_exclusive(hdspm))
2240 return -EBUSY;
2241 val = ucontrol->value.integer.value[0] & 1;
2242 spin_lock_irq(&hdspm->lock);
2243 change = (int) val != hdspm_professional(hdspm);
2244 hdspm_set_professional(hdspm, val);
2245 spin_unlock_irq(&hdspm->lock);
2246 return change;
2247}
2248
1844#define HDSPM_INPUT_SELECT(xname, xindex) \ 2249#define HDSPM_INPUT_SELECT(xname, xindex) \
1845{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 2250{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
1846 .name = xname, \ 2251 .name = xname, \
@@ -1912,6 +2317,163 @@ static int snd_hdspm_put_input_select(struct snd_kcontrol *kcontrol,
1912 return change; 2317 return change;
1913} 2318}
1914 2319
2320#define HDSPM_DS_WIRE(xname, xindex) \
2321{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2322 .name = xname, \
2323 .index = xindex, \
2324 .info = snd_hdspm_info_ds_wire, \
2325 .get = snd_hdspm_get_ds_wire, \
2326 .put = snd_hdspm_put_ds_wire \
2327}
2328
2329static int hdspm_ds_wire(struct hdspm * hdspm)
2330{
2331 return (hdspm->control_register & HDSPM_DS_DoubleWire) ? 1 : 0;
2332}
2333
2334static int hdspm_set_ds_wire(struct hdspm * hdspm, int ds)
2335{
2336 if (ds)
2337 hdspm->control_register |= HDSPM_DS_DoubleWire;
2338 else
2339 hdspm->control_register &= ~HDSPM_DS_DoubleWire;
2340 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
2341
2342 return 0;
2343}
2344
2345static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol,
2346 struct snd_ctl_elem_info *uinfo)
2347{
2348 static char *texts[] = { "Single", "Double" };
2349
2350 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2351 uinfo->count = 1;
2352 uinfo->value.enumerated.items = 2;
2353
2354 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2355 uinfo->value.enumerated.item =
2356 uinfo->value.enumerated.items - 1;
2357 strcpy(uinfo->value.enumerated.name,
2358 texts[uinfo->value.enumerated.item]);
2359
2360 return 0;
2361}
2362
2363static int snd_hdspm_get_ds_wire(struct snd_kcontrol *kcontrol,
2364 struct snd_ctl_elem_value *ucontrol)
2365{
2366 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2367
2368 spin_lock_irq(&hdspm->lock);
2369 ucontrol->value.enumerated.item[0] = hdspm_ds_wire(hdspm);
2370 spin_unlock_irq(&hdspm->lock);
2371 return 0;
2372}
2373
2374static int snd_hdspm_put_ds_wire(struct snd_kcontrol *kcontrol,
2375 struct snd_ctl_elem_value *ucontrol)
2376{
2377 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2378 int change;
2379 unsigned int val;
2380
2381 if (!snd_hdspm_use_is_exclusive(hdspm))
2382 return -EBUSY;
2383 val = ucontrol->value.integer.value[0] & 1;
2384 spin_lock_irq(&hdspm->lock);
2385 change = (int) val != hdspm_ds_wire(hdspm);
2386 hdspm_set_ds_wire(hdspm, val);
2387 spin_unlock_irq(&hdspm->lock);
2388 return change;
2389}
2390
2391#define HDSPM_QS_WIRE(xname, xindex) \
2392{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2393 .name = xname, \
2394 .index = xindex, \
2395 .info = snd_hdspm_info_qs_wire, \
2396 .get = snd_hdspm_get_qs_wire, \
2397 .put = snd_hdspm_put_qs_wire \
2398}
2399
2400static int hdspm_qs_wire(struct hdspm * hdspm)
2401{
2402 if (hdspm->control_register & HDSPM_QS_DoubleWire)
2403 return 1;
2404 if (hdspm->control_register & HDSPM_QS_QuadWire)
2405 return 2;
2406 return 0;
2407}
2408
2409static int hdspm_set_qs_wire(struct hdspm * hdspm, int mode)
2410{
2411 hdspm->control_register &= ~(HDSPM_QS_DoubleWire | HDSPM_QS_QuadWire);
2412 switch (mode) {
2413 case 0:
2414 break;
2415 case 1:
2416 hdspm->control_register |= HDSPM_QS_DoubleWire;
2417 break;
2418 case 2:
2419 hdspm->control_register |= HDSPM_QS_QuadWire;
2420 break;
2421 }
2422 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register);
2423
2424 return 0;
2425}
2426
2427static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol,
2428 struct snd_ctl_elem_info *uinfo)
2429{
2430 static char *texts[] = { "Single", "Double", "Quad" };
2431
2432 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2433 uinfo->count = 1;
2434 uinfo->value.enumerated.items = 3;
2435
2436 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2437 uinfo->value.enumerated.item =
2438 uinfo->value.enumerated.items - 1;
2439 strcpy(uinfo->value.enumerated.name,
2440 texts[uinfo->value.enumerated.item]);
2441
2442 return 0;
2443}
2444
2445static int snd_hdspm_get_qs_wire(struct snd_kcontrol *kcontrol,
2446 struct snd_ctl_elem_value *ucontrol)
2447{
2448 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2449
2450 spin_lock_irq(&hdspm->lock);
2451 ucontrol->value.enumerated.item[0] = hdspm_qs_wire(hdspm);
2452 spin_unlock_irq(&hdspm->lock);
2453 return 0;
2454}
2455
2456static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
2457 struct snd_ctl_elem_value *ucontrol)
2458{
2459 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2460 int change;
2461 int val;
2462
2463 if (!snd_hdspm_use_is_exclusive(hdspm))
2464 return -EBUSY;
2465 val = ucontrol->value.integer.value[0];
2466 if (val < 0)
2467 val = 0;
2468 if (val > 2)
2469 val = 2;
2470 spin_lock_irq(&hdspm->lock);
2471 change = (int) val != hdspm_qs_wire(hdspm);
2472 hdspm_set_qs_wire(hdspm, val);
2473 spin_unlock_irq(&hdspm->lock);
2474 return change;
2475}
2476
1915/* Simple Mixer 2477/* Simple Mixer
1916 deprecated since to much faders ??? 2478 deprecated since to much faders ???
1917 MIXER interface says output (source, destination, value) 2479 MIXER interface says output (source, destination, value)
@@ -2135,14 +2697,24 @@ static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
2135 2697
2136static int hdspm_wc_sync_check(struct hdspm * hdspm) 2698static int hdspm_wc_sync_check(struct hdspm * hdspm)
2137{ 2699{
2138 int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 2700 if (hdspm->is_aes32) {
2139 if (status2 & HDSPM_wcLock) { 2701 int status = hdspm_read(hdspm, HDSPM_statusRegister);
2140 if (status2 & HDSPM_wcSync) 2702 if (status & HDSPM_AES32_wcLock) {
2703 /* I don't know how to differenciate sync from lock.
2704 Doing as if sync for now */
2141 return 2; 2705 return 2;
2142 else 2706 }
2143 return 1; 2707 return 0;
2708 } else {
2709 int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2710 if (status2 & HDSPM_wcLock) {
2711 if (status2 & HDSPM_wcSync)
2712 return 2;
2713 else
2714 return 1;
2715 }
2716 return 0;
2144 } 2717 }
2145 return 0;
2146} 2718}
2147 2719
2148static int snd_hdspm_get_wc_sync_check(struct snd_kcontrol *kcontrol, 2720static int snd_hdspm_get_wc_sync_check(struct snd_kcontrol *kcontrol,
@@ -2188,9 +2760,43 @@ static int snd_hdspm_get_madisync_sync_check(struct snd_kcontrol *kcontrol,
2188} 2760}
2189 2761
2190 2762
2763#define HDSPM_AES_SYNC_CHECK(xname, xindex) \
2764{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2765 .name = xname, \
2766 .index = xindex, \
2767 .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, \
2768 .info = snd_hdspm_info_sync_check, \
2769 .get = snd_hdspm_get_aes_sync_check \
2770}
2771
2772static int hdspm_aes_sync_check(struct hdspm * hdspm, int idx)
2773{
2774 int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2775 if (status2 & (HDSPM_LockAES >> idx)) {
2776 /* I don't know how to differenciate sync from lock.
2777 Doing as if sync for now */
2778 return 2;
2779 }
2780 return 0;
2781}
2782
2783static int snd_hdspm_get_aes_sync_check(struct snd_kcontrol *kcontrol,
2784 struct snd_ctl_elem_value *ucontrol)
2785{
2786 int offset;
2787 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2788
2789 offset = ucontrol->id.index - 1;
2790 if (offset < 0 || offset >= 8)
2791 return -EINVAL;
2792
2793 ucontrol->value.enumerated.item[0] =
2794 hdspm_aes_sync_check(hdspm, offset);
2795 return 0;
2796}
2191 2797
2192 2798
2193static struct snd_kcontrol_new snd_hdspm_controls[] = { 2799static struct snd_kcontrol_new snd_hdspm_controls_madi[] = {
2194 2800
2195 HDSPM_MIXER("Mixer", 0), 2801 HDSPM_MIXER("Mixer", 0),
2196/* 'Sample Clock Source' complies with the alsa control naming scheme */ 2802/* 'Sample Clock Source' complies with the alsa control naming scheme */
@@ -2211,6 +2817,29 @@ static struct snd_kcontrol_new snd_hdspm_controls[] = {
2211 HDSPM_INPUT_SELECT("Input Select", 0), 2817 HDSPM_INPUT_SELECT("Input Select", 0),
2212}; 2818};
2213 2819
2820static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
2821
2822 HDSPM_MIXER("Mixer", 0),
2823/* 'Sample Clock Source' complies with the alsa control naming scheme */
2824 HDSPM_CLOCK_SOURCE("Sample Clock Source", 0),
2825
2826 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
2827 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
2828 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
2829 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
2830/* 'External Rate' complies with the alsa control naming scheme */
2831 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
2832 HDSPM_WC_SYNC_CHECK("Word Clock Lock Status", 0),
2833/* HDSPM_AES_SYNC_CHECK("AES Lock Status", 0),*/ /* created in snd_hdspm_create_controls() */
2834 HDSPM_LINE_OUT("Line Out", 0),
2835 HDSPM_EMPHASIS("Emphasis", 0),
2836 HDSPM_DOLBY("Non Audio", 0),
2837 HDSPM_PROFESSIONAL("Professional", 0),
2838 HDSPM_C_TMS("Clear Track Marker", 0),
2839 HDSPM_DS_WIRE("Double Speed Wire Mode", 0),
2840 HDSPM_QS_WIRE("Quad Speed Wire Mode", 0),
2841};
2842
2214static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER; 2843static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER;
2215 2844
2216 2845
@@ -2245,20 +2874,40 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm
2245 struct snd_kcontrol *kctl; 2874 struct snd_kcontrol *kctl;
2246 2875
2247 /* add control list first */ 2876 /* add control list first */
2248 2877 if (hdspm->is_aes32) {
2249 for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls); idx++) { 2878 struct snd_kcontrol_new aes_sync_ctl =
2250 if ((err = 2879 HDSPM_AES_SYNC_CHECK("AES Lock Status", 0);
2251 snd_ctl_add(card, kctl = 2880
2252 snd_ctl_new1(&snd_hdspm_controls[idx], 2881 for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls_aes32);
2253 hdspm))) < 0) { 2882 idx++) {
2254 return err; 2883 err = snd_ctl_add(card,
2884 snd_ctl_new1(&snd_hdspm_controls_aes32[idx],
2885 hdspm));
2886 if (err < 0)
2887 return err;
2888 }
2889 for (idx = 1; idx <= 8; idx++) {
2890 aes_sync_ctl.index = idx;
2891 err = snd_ctl_add(card,
2892 snd_ctl_new1(&aes_sync_ctl, hdspm));
2893 if (err < 0)
2894 return err;
2895 }
2896 } else {
2897 for (idx = 0; idx < ARRAY_SIZE(snd_hdspm_controls_madi);
2898 idx++) {
2899 err = snd_ctl_add(card,
2900 snd_ctl_new1(&snd_hdspm_controls_madi[idx],
2901 hdspm));
2902 if (err < 0)
2903 return err;
2255 } 2904 }
2256 } 2905 }
2257 2906
2258 /* Channel playback mixer as default control 2907 /* Channel playback mixer as default control
2259 Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats too big for any alsamixer 2908Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, thats too big for any alsamixer
2260 they are accesible via special IOCTL on hwdep 2909they are accesible via special IOCTL on hwdep
2261 and the mixer 2dimensional mixer control */ 2910and the mixer 2dimensional mixer control */
2262 2911
2263 snd_hdspm_playback_mixer.name = "Chn"; 2912 snd_hdspm_playback_mixer.name = "Chn";
2264 limit = HDSPM_MAX_CHANNELS; 2913 limit = HDSPM_MAX_CHANNELS;
@@ -2289,7 +2938,8 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm
2289 ------------------------------------------------------------*/ 2938 ------------------------------------------------------------*/
2290 2939
2291static void 2940static void
2292snd_hdspm_proc_read(struct snd_info_entry * entry, struct snd_info_buffer *buffer) 2941snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
2942 struct snd_info_buffer *buffer)
2293{ 2943{
2294 struct hdspm *hdspm = (struct hdspm *) entry->private_data; 2944 struct hdspm *hdspm = (struct hdspm *) entry->private_data;
2295 unsigned int status; 2945 unsigned int status;
@@ -2420,11 +3070,10 @@ snd_hdspm_proc_read(struct snd_info_entry * entry, struct snd_info_buffer *buffe
2420 clock_source = "Error"; 3070 clock_source = "Error";
2421 } 3071 }
2422 snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source); 3072 snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source);
2423 if (!(hdspm->control_register & HDSPM_ClockModeMaster)) { 3073 if (!(hdspm->control_register & HDSPM_ClockModeMaster))
2424 system_clock_mode = "Slave"; 3074 system_clock_mode = "Slave";
2425 } else { 3075 else
2426 system_clock_mode = "Master"; 3076 system_clock_mode = "Master";
2427 }
2428 snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode); 3077 snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode);
2429 3078
2430 switch (hdspm_pref_sync_ref(hdspm)) { 3079 switch (hdspm_pref_sync_ref(hdspm)) {
@@ -2484,13 +3133,213 @@ snd_hdspm_proc_read(struct snd_info_entry * entry, struct snd_info_buffer *buffe
2484 snd_iprintf(buffer, "\n"); 3133 snd_iprintf(buffer, "\n");
2485} 3134}
2486 3135
3136static void
3137snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
3138 struct snd_info_buffer *buffer)
3139{
3140 struct hdspm *hdspm = (struct hdspm *) entry->private_data;
3141 unsigned int status;
3142 unsigned int status2;
3143 unsigned int timecode;
3144 int pref_syncref;
3145 char *autosync_ref;
3146 char *system_clock_mode;
3147 char *clock_source;
3148 int x;
3149
3150 status = hdspm_read(hdspm, HDSPM_statusRegister);
3151 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
3152 timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
3153
3154 snd_iprintf(buffer, "%s (Card #%d) Rev.%x\n",
3155 hdspm->card_name, hdspm->card->number + 1,
3156 hdspm->firmware_rev);
3157
3158 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
3159 hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
3160
3161 snd_iprintf(buffer, "--- System ---\n");
3162
3163 snd_iprintf(buffer,
3164 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
3165 status & HDSPM_audioIRQPending,
3166 (status & HDSPM_midi0IRQPending) ? 1 : 0,
3167 (status & HDSPM_midi1IRQPending) ? 1 : 0,
3168 hdspm->irq_count);
3169 snd_iprintf(buffer,
3170 "HW pointer: id = %d, rawptr = %d (%d->%d) estimated= %ld (bytes)\n",
3171 ((status & HDSPM_BufferID) ? 1 : 0),
3172 (status & HDSPM_BufferPositionMask),
3173 (status & HDSPM_BufferPositionMask) % (2 *
3174 (int)hdspm->
3175 period_bytes),
3176 ((status & HDSPM_BufferPositionMask) -
3177 64) % (2 * (int)hdspm->period_bytes),
3178 (long) hdspm_hw_pointer(hdspm) * 4);
3179
3180 snd_iprintf(buffer,
3181 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
3182 hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
3183 hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
3184 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
3185 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
3186 snd_iprintf(buffer,
3187 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n",
3188 hdspm->control_register, hdspm->control2_register,
3189 status, status2, timecode);
3190
3191 snd_iprintf(buffer, "--- Settings ---\n");
3192
3193 x = 1 << (6 +
3194 hdspm_decode_latency(hdspm->
3195 control_register &
3196 HDSPM_LatencyMask));
3197
3198 snd_iprintf(buffer,
3199 "Size (Latency): %d samples (2 periods of %lu bytes)\n",
3200 x, (unsigned long) hdspm->period_bytes);
3201
3202 snd_iprintf(buffer, "Line out: %s, Precise Pointer: %s\n",
3203 (hdspm->
3204 control_register & HDSPM_LineOut) ? "on " : "off",
3205 (hdspm->precise_ptr) ? "on" : "off");
3206
3207 snd_iprintf(buffer,
3208 "ClearTrackMarker %s, Emphasis %s, Dolby %s\n",
3209 (hdspm->
3210 control_register & HDSPM_clr_tms) ? "on" : "off",
3211 (hdspm->
3212 control_register & HDSPM_Emphasis) ? "on" : "off",
3213 (hdspm->
3214 control_register & HDSPM_Dolby) ? "on" : "off");
3215
3216 switch (hdspm_clock_source(hdspm)) {
3217 case HDSPM_CLOCK_SOURCE_AUTOSYNC:
3218 clock_source = "AutoSync";
3219 break;
3220 case HDSPM_CLOCK_SOURCE_INTERNAL_32KHZ:
3221 clock_source = "Internal 32 kHz";
3222 break;
3223 case HDSPM_CLOCK_SOURCE_INTERNAL_44_1KHZ:
3224 clock_source = "Internal 44.1 kHz";
3225 break;
3226 case HDSPM_CLOCK_SOURCE_INTERNAL_48KHZ:
3227 clock_source = "Internal 48 kHz";
3228 break;
3229 case HDSPM_CLOCK_SOURCE_INTERNAL_64KHZ:
3230 clock_source = "Internal 64 kHz";
3231 break;
3232 case HDSPM_CLOCK_SOURCE_INTERNAL_88_2KHZ:
3233 clock_source = "Internal 88.2 kHz";
3234 break;
3235 case HDSPM_CLOCK_SOURCE_INTERNAL_96KHZ:
3236 clock_source = "Internal 96 kHz";
3237 break;
3238 case HDSPM_CLOCK_SOURCE_INTERNAL_128KHZ:
3239 clock_source = "Internal 128 kHz";
3240 break;
3241 case HDSPM_CLOCK_SOURCE_INTERNAL_176_4KHZ:
3242 clock_source = "Internal 176.4 kHz";
3243 break;
3244 case HDSPM_CLOCK_SOURCE_INTERNAL_192KHZ:
3245 clock_source = "Internal 192 kHz";
3246 break;
3247 default:
3248 clock_source = "Error";
3249 }
3250 snd_iprintf(buffer, "Sample Clock Source: %s\n", clock_source);
3251 if (!(hdspm->control_register & HDSPM_ClockModeMaster))
3252 system_clock_mode = "Slave";
3253 else
3254 system_clock_mode = "Master";
3255 snd_iprintf(buffer, "System Clock Mode: %s\n", system_clock_mode);
3256
3257 pref_syncref = hdspm_pref_sync_ref(hdspm);
3258 if (pref_syncref == 0)
3259 snd_iprintf(buffer, "Preferred Sync Reference: Word Clock\n");
3260 else
3261 snd_iprintf(buffer, "Preferred Sync Reference: AES%d\n",
3262 pref_syncref);
3263
3264 snd_iprintf(buffer, "System Clock Frequency: %d\n",
3265 hdspm->system_sample_rate);
3266
3267 snd_iprintf(buffer, "Double speed: %s\n",
3268 hdspm->control_register & HDSPM_DS_DoubleWire?
3269 "Double wire" : "Single wire");
3270 snd_iprintf(buffer, "Quad speed: %s\n",
3271 hdspm->control_register & HDSPM_QS_DoubleWire?
3272 "Double wire" :
3273 hdspm->control_register & HDSPM_QS_QuadWire?
3274 "Quad wire" : "Single wire");
3275
3276 snd_iprintf(buffer, "--- Status:\n");
3277
3278 snd_iprintf(buffer, "Word: %s Frequency: %d\n",
3279 (status & HDSPM_AES32_wcLock)? "Sync " : "No Lock",
3280 HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF));
3281
3282 for (x = 0; x < 8; x++) {
3283 snd_iprintf(buffer, "AES%d: %s Frequency: %d\n",
3284 x+1,
3285 (status2 & (HDSPM_LockAES >> x))? "Sync ": "No Lock",
3286 HDSPM_bit2freq((timecode >> (4*x)) & 0xF));
3287 }
3288
3289 switch (hdspm_autosync_ref(hdspm)) {
3290 case HDSPM_AES32_AUTOSYNC_FROM_NONE: autosync_ref="None"; break;
3291 case HDSPM_AES32_AUTOSYNC_FROM_WORD: autosync_ref="Word Clock"; break;
3292 case HDSPM_AES32_AUTOSYNC_FROM_AES1: autosync_ref="AES1"; break;
3293 case HDSPM_AES32_AUTOSYNC_FROM_AES2: autosync_ref="AES2"; break;
3294 case HDSPM_AES32_AUTOSYNC_FROM_AES3: autosync_ref="AES3"; break;
3295 case HDSPM_AES32_AUTOSYNC_FROM_AES4: autosync_ref="AES4"; break;
3296 case HDSPM_AES32_AUTOSYNC_FROM_AES5: autosync_ref="AES5"; break;
3297 case HDSPM_AES32_AUTOSYNC_FROM_AES6: autosync_ref="AES6"; break;
3298 case HDSPM_AES32_AUTOSYNC_FROM_AES7: autosync_ref="AES7"; break;
3299 case HDSPM_AES32_AUTOSYNC_FROM_AES8: autosync_ref="AES8"; break;
3300 default: autosync_ref = "---"; break;
3301 }
3302 snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref);
3303
3304 snd_iprintf(buffer, "\n");
3305}
3306
3307#ifdef CONFIG_SND_DEBUG
3308static void
3309snd_hdspm_proc_read_debug(struct snd_info_entry * entry,
3310 struct snd_info_buffer *buffer)
3311{
3312 struct hdspm *hdspm = (struct hdspm *)entry->private_data;
3313
3314 int j,i;
3315
3316 for (i = 0; i < 256 /* 1024*64 */; i += j)
3317 {
3318 snd_iprintf(buffer, "0x%08X: ", i);
3319 for (j = 0; j < 16; j += 4)
3320 snd_iprintf(buffer, "%08X ", hdspm_read(hdspm, i + j));
3321 snd_iprintf(buffer, "\n");
3322 }
3323}
3324#endif
3325
3326
3327
2487static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm) 3328static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm)
2488{ 3329{
2489 struct snd_info_entry *entry; 3330 struct snd_info_entry *entry;
2490 3331
2491 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry)) 3332 if (!snd_card_proc_new(hdspm->card, "hdspm", &entry))
2492 snd_info_set_text_ops(entry, hdspm, 3333 snd_info_set_text_ops(entry, hdspm,
2493 snd_hdspm_proc_read); 3334 hdspm->is_aes32 ?
3335 snd_hdspm_proc_read_aes32 :
3336 snd_hdspm_proc_read_madi);
3337#ifdef CONFIG_SND_DEBUG
3338 /* debug file to read all hdspm registers */
3339 if (!snd_card_proc_new(hdspm->card, "debug", &entry))
3340 snd_info_set_text_ops(entry, hdspm,
3341 snd_hdspm_proc_read_debug);
3342#endif
2494} 3343}
2495 3344
2496/*------------------------------------------------------------ 3345/*------------------------------------------------------------
@@ -2507,13 +3356,20 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
2507 3356
2508 /* set defaults: */ 3357 /* set defaults: */
2509 3358
2510 hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */ 3359 if (hdspm->is_aes32)
2511 hdspm_encode_latency(7) | /* latency maximum = 8192 samples */ 3360 hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */
2512 HDSPM_InputCoaxial | /* Input Coax not Optical */ 3361 hdspm_encode_latency(7) | /* latency maximum = 8192 samples */
2513 HDSPM_SyncRef_MADI | /* Madi is syncclock */ 3362 HDSPM_SyncRef0 | /* AES1 is syncclock */
2514 HDSPM_LineOut | /* Analog output in */ 3363 HDSPM_LineOut | /* Analog output in */
2515 HDSPM_TX_64ch | /* transmit in 64ch mode */ 3364 HDSPM_Professional; /* Professional mode */
2516 HDSPM_AutoInp; /* AutoInput chossing (takeover) */ 3365 else
3366 hdspm->control_register = HDSPM_ClockModeMaster | /* Master Cloack Mode on */
3367 hdspm_encode_latency(7) | /* latency maximum = 8192 samples */
3368 HDSPM_InputCoaxial | /* Input Coax not Optical */
3369 HDSPM_SyncRef_MADI | /* Madi is syncclock */
3370 HDSPM_LineOut | /* Analog output in */
3371 HDSPM_TX_64ch | /* transmit in 64ch mode */
3372 HDSPM_AutoInp; /* AutoInput chossing (takeover) */
2517 3373
2518 /* ! HDSPM_Frequency0|HDSPM_Frequency1 = 44.1khz */ 3374 /* ! HDSPM_Frequency0|HDSPM_Frequency1 = 44.1khz */
2519 /* ! HDSPM_DoubleSpeed HDSPM_QuadSpeed = normal speed */ 3375 /* ! HDSPM_DoubleSpeed HDSPM_QuadSpeed = normal speed */
@@ -2822,6 +3678,8 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
2822 3678
2823 hdspm->playback_buffer = 3679 hdspm->playback_buffer =
2824 (unsigned char *) substream->runtime->dma_area; 3680 (unsigned char *) substream->runtime->dma_area;
3681 snd_printdd("Allocated sample buffer for playback at %p\n",
3682 hdspm->playback_buffer);
2825 } else { 3683 } else {
2826 hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferIn, 3684 hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferIn,
2827 params_channels(params)); 3685 params_channels(params));
@@ -2831,7 +3689,15 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
2831 3689
2832 hdspm->capture_buffer = 3690 hdspm->capture_buffer =
2833 (unsigned char *) substream->runtime->dma_area; 3691 (unsigned char *) substream->runtime->dma_area;
3692 snd_printdd("Allocated sample buffer for capture at %p\n",
3693 hdspm->capture_buffer);
2834 } 3694 }
3695 /*
3696 snd_printdd("Allocated sample buffer for %s at 0x%08X\n",
3697 substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
3698 "playback" : "capture",
3699 snd_pcm_sgbuf_get_addr(sgbuf, 0));
3700 */
2835 return 0; 3701 return 0;
2836} 3702}
2837 3703
@@ -2982,9 +3848,10 @@ static struct snd_pcm_hardware snd_hdspm_playback_subinfo = {
2982 SNDRV_PCM_RATE_44100 | 3848 SNDRV_PCM_RATE_44100 |
2983 SNDRV_PCM_RATE_48000 | 3849 SNDRV_PCM_RATE_48000 |
2984 SNDRV_PCM_RATE_64000 | 3850 SNDRV_PCM_RATE_64000 |
2985 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000), 3851 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
3852 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000 ),
2986 .rate_min = 32000, 3853 .rate_min = 32000,
2987 .rate_max = 96000, 3854 .rate_max = 192000,
2988 .channels_min = 1, 3855 .channels_min = 1,
2989 .channels_max = HDSPM_MAX_CHANNELS, 3856 .channels_max = HDSPM_MAX_CHANNELS,
2990 .buffer_bytes_max = 3857 .buffer_bytes_max =
@@ -3006,9 +3873,10 @@ static struct snd_pcm_hardware snd_hdspm_capture_subinfo = {
3006 SNDRV_PCM_RATE_44100 | 3873 SNDRV_PCM_RATE_44100 |
3007 SNDRV_PCM_RATE_48000 | 3874 SNDRV_PCM_RATE_48000 |
3008 SNDRV_PCM_RATE_64000 | 3875 SNDRV_PCM_RATE_64000 |
3009 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000), 3876 SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
3877 SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000),
3010 .rate_min = 32000, 3878 .rate_min = 32000,
3011 .rate_max = 96000, 3879 .rate_max = 192000,
3012 .channels_min = 1, 3880 .channels_min = 1,
3013 .channels_max = HDSPM_MAX_CHANNELS, 3881 .channels_max = HDSPM_MAX_CHANNELS,
3014 .buffer_bytes_max = 3882 .buffer_bytes_max =
@@ -3315,7 +4183,8 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm)
3315 4183
3316 pcm = hdspm->pcm; 4184 pcm = hdspm->pcm;
3317 4185
3318 wanted = HDSPM_DMA_AREA_BYTES + 4096; /* dont know why, but it works */ 4186/* wanted = HDSPM_DMA_AREA_BYTES + 4096;*/ /* dont know why, but it works */
4187 wanted = HDSPM_DMA_AREA_BYTES;
3319 4188
3320 if ((err = 4189 if ((err =
3321 snd_pcm_lib_preallocate_pages_for_all(pcm, 4190 snd_pcm_lib_preallocate_pages_for_all(pcm,
@@ -3467,9 +4336,16 @@ static int __devinit snd_hdspm_create(struct snd_card *card, struct hdspm * hdsp
3467 pci_read_config_word(hdspm->pci, 4336 pci_read_config_word(hdspm->pci,
3468 PCI_CLASS_REVISION, &hdspm->firmware_rev); 4337 PCI_CLASS_REVISION, &hdspm->firmware_rev);
3469 4338
3470 strcpy(card->driver, "HDSPM"); 4339 hdspm->is_aes32 = (hdspm->firmware_rev >= HDSPM_AESREVISION);
4340
3471 strcpy(card->mixername, "Xilinx FPGA"); 4341 strcpy(card->mixername, "Xilinx FPGA");
3472 hdspm->card_name = "RME HDSPM MADI"; 4342 if (hdspm->is_aes32) {
4343 strcpy(card->driver, "HDSPAES32");
4344 hdspm->card_name = "RME HDSPM AES32";
4345 } else {
4346 strcpy(card->driver, "HDSPM");
4347 hdspm->card_name = "RME HDSPM MADI";
4348 }
3473 4349
3474 if ((err = pci_enable_device(pci)) < 0) 4350 if ((err = pci_enable_device(pci)) < 0)
3475 return err; 4351 return err;
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 474f2d451ae8..3bff32167f66 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -2627,7 +2627,7 @@ static int snd_trident_vol_control_get(struct snd_kcontrol *kcontrol,
2627 return 0; 2627 return 0;
2628} 2628}
2629 2629
2630static DECLARE_TLV_DB_SCALE(db_scale_gvol, -6375, 25, 0); 2630static const DECLARE_TLV_DB_SCALE(db_scale_gvol, -6375, 25, 0);
2631 2631
2632static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol, 2632static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol,
2633 struct snd_ctl_elem_value *ucontrol) 2633 struct snd_ctl_elem_value *ucontrol)
@@ -2844,7 +2844,7 @@ static int snd_trident_pcm_rvol_control_put(struct snd_kcontrol *kcontrol,
2844 return change; 2844 return change;
2845} 2845}
2846 2846
2847static DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1); 2847static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1);
2848 2848
2849static struct snd_kcontrol_new snd_trident_pcm_rvol_control __devinitdata = 2849static struct snd_kcontrol_new snd_trident_pcm_rvol_control __devinitdata =
2850{ 2850{
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index a572b018807f..a28992269f5e 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -1699,7 +1699,7 @@ static int snd_via8233_pcmdxs_volume_put(struct snd_kcontrol *kcontrol,
1699 return change; 1699 return change;
1700} 1700}
1701 1701
1702static DECLARE_TLV_DB_SCALE(db_scale_dxs, -9450, 150, 1); 1702static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -9450, 150, 1);
1703 1703
1704static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata = { 1704static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata = {
1705 .name = "PCM Playback Volume", 1705 .name = "PCM Playback Volume",
@@ -1823,7 +1823,7 @@ static int __devinit snd_via82xx_mixer_new(struct via82xx *chip, const char *qui
1823 ac97.private_data = chip; 1823 ac97.private_data = chip;
1824 ac97.private_free = snd_via82xx_mixer_free_ac97; 1824 ac97.private_free = snd_via82xx_mixer_free_ac97;
1825 ac97.pci = chip->pci; 1825 ac97.pci = chip->pci;
1826 ac97.scaps = AC97_SCAP_SKIP_MODEM; 1826 ac97.scaps = AC97_SCAP_SKIP_MODEM | AC97_SCAP_POWER_SAVE;
1827 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0) 1827 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
1828 return err; 1828 return err;
1829 1829
@@ -2357,93 +2357,59 @@ static struct via823x_info via823x_cards[] __devinitdata = {
2357/* 2357/*
2358 * auto detection of DXS channel supports. 2358 * auto detection of DXS channel supports.
2359 */ 2359 */
2360struct dxs_whitelist { 2360
2361 unsigned short subvendor; 2361static struct snd_pci_quirk dxs_whitelist[] __devinitdata = {
2362 unsigned short subdevice; 2362 SND_PCI_QUIRK(0x1005, 0x4710, "Avance Logic Mobo", VIA_DXS_ENABLE),
2363 unsigned short mask; 2363 SND_PCI_QUIRK(0x1019, 0x0996, "ESC Mobo", VIA_DXS_48K),
2364 short action; /* new dxs_support value */ 2364 SND_PCI_QUIRK(0x1019, 0x0a81, "ECS K7VTA3 v8.0", VIA_DXS_NO_VRA),
2365 SND_PCI_QUIRK(0x1019, 0x0a85, "ECS L7VMM2", VIA_DXS_NO_VRA),
2366 SND_PCI_QUIRK(0x1019, 0, "ESC K8", VIA_DXS_SRC),
2367 SND_PCI_QUIRK(0x1019, 0xaa01, "ESC K8T890-A", VIA_DXS_SRC),
2368 SND_PCI_QUIRK(0x1025, 0x0033, "Acer Inspire 1353LM", VIA_DXS_NO_VRA),
2369 SND_PCI_QUIRK(0x1025, 0x0046, "Acer Aspire 1524 WLMi", VIA_DXS_SRC),
2370 SND_PCI_QUIRK(0x1043, 0, "ASUS A7/A8", VIA_DXS_NO_VRA),
2371 SND_PCI_QUIRK(0x1071, 0, "Diverse Notebook", VIA_DXS_NO_VRA),
2372 SND_PCI_QUIRK(0x10cf, 0x118e, "FSC Laptop", VIA_DXS_ENABLE),
2373 SND_PCI_QUIRK(0x1106, 0, "ASRock", VIA_DXS_SRC),
2374 SND_PCI_QUIRK(0x1297, 0xa232, "Shuttle", VIA_DXS_ENABLE),
2375 SND_PCI_QUIRK(0x1297, 0xc160, "Shuttle Sk41G", VIA_DXS_ENABLE),
2376 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte GA-7VAXP", VIA_DXS_ENABLE),
2377 SND_PCI_QUIRK(0x1462, 0x3800, "MSI KT266", VIA_DXS_ENABLE),
2378 SND_PCI_QUIRK(0x1462, 0x7120, "MSI KT4V", VIA_DXS_ENABLE),
2379 SND_PCI_QUIRK(0x1462, 0x7142, "MSI K8MM-V", VIA_DXS_ENABLE),
2380 SND_PCI_QUIRK(0x1462, 0, "MSI Mobo", VIA_DXS_SRC),
2381 SND_PCI_QUIRK(0x147b, 0x1401, "ABIT KD7(-RAID)", VIA_DXS_ENABLE),
2382 SND_PCI_QUIRK(0x147b, 0x1411, "ABIT VA-20", VIA_DXS_ENABLE),
2383 SND_PCI_QUIRK(0x147b, 0x1413, "ABIT KV8 Pro", VIA_DXS_ENABLE),
2384 SND_PCI_QUIRK(0x147b, 0x1415, "ABIT AV8", VIA_DXS_NO_VRA),
2385 SND_PCI_QUIRK(0x14ff, 0x0403, "Twinhead mobo", VIA_DXS_ENABLE),
2386 SND_PCI_QUIRK(0x14ff, 0x0408, "Twinhead laptop", VIA_DXS_SRC),
2387 SND_PCI_QUIRK(0x1558, 0x4701, "Clevo D470", VIA_DXS_SRC),
2388 SND_PCI_QUIRK(0x1584, 0x8120, "Diverse Laptop", VIA_DXS_ENABLE),
2389 SND_PCI_QUIRK(0x1584, 0x8123, "Targa/Uniwill", VIA_DXS_NO_VRA),
2390 SND_PCI_QUIRK(0x161f, 0x202b, "Amira Notebook", VIA_DXS_NO_VRA),
2391 SND_PCI_QUIRK(0x161f, 0x2032, "m680x machines", VIA_DXS_48K),
2392 SND_PCI_QUIRK(0x1631, 0xe004, "PB EasyNote 3174", VIA_DXS_ENABLE),
2393 SND_PCI_QUIRK(0x1695, 0x3005, "EPoX EP-8K9A", VIA_DXS_ENABLE),
2394 SND_PCI_QUIRK(0x1695, 0, "EPoX mobo", VIA_DXS_SRC),
2395 SND_PCI_QUIRK(0x16f3, 0, "Jetway K8", VIA_DXS_SRC),
2396 SND_PCI_QUIRK(0x1734, 0, "FSC Laptop", VIA_DXS_SRC),
2397 SND_PCI_QUIRK(0x1849, 0x3059, "ASRock K7VM2", VIA_DXS_NO_VRA),
2398 SND_PCI_QUIRK(0x1849, 0, "ASRock mobo", VIA_DXS_SRC),
2399 SND_PCI_QUIRK(0x1919, 0x200a, "Soltek SL-K8", VIA_DXS_NO_VRA),
2400 SND_PCI_QUIRK(0x4005, 0x4710, "MSI K7T266", VIA_DXS_SRC),
2401 { } /* terminator */
2365}; 2402};
2366 2403
2367static int __devinit check_dxs_list(struct pci_dev *pci, int revision) 2404static int __devinit check_dxs_list(struct pci_dev *pci, int revision)
2368{ 2405{
2369 static struct dxs_whitelist whitelist[] __devinitdata = { 2406 const struct snd_pci_quirk *w;
2370 { .subvendor = 0x1005, .subdevice = 0x4710, .action = VIA_DXS_ENABLE }, /* Avance Logic Mobo */
2371 { .subvendor = 0x1019, .subdevice = 0x0996, .action = VIA_DXS_48K },
2372 { .subvendor = 0x1019, .subdevice = 0x0a81, .action = VIA_DXS_NO_VRA }, /* ECS K7VTA3 v8.0 */
2373 { .subvendor = 0x1019, .subdevice = 0x0a85, .action = VIA_DXS_NO_VRA }, /* ECS L7VMM2 */
2374 { .subvendor = 0x1019, .subdevice = 0xa101, .action = VIA_DXS_SRC },
2375 { .subvendor = 0x1019, .subdevice = 0xaa01, .action = VIA_DXS_SRC }, /* ECS K8T890-A */
2376 { .subvendor = 0x1025, .subdevice = 0x0033, .action = VIA_DXS_NO_VRA }, /* Acer Inspire 1353LM */
2377 { .subvendor = 0x1025, .subdevice = 0x0046, .action = VIA_DXS_SRC }, /* Acer Aspire 1524 WLMi */
2378 { .subvendor = 0x1043, .subdevice = 0x8095, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8X (FIXME: possibly VIA_DXS_ENABLE?)*/
2379 { .subvendor = 0x1043, .subdevice = 0x80a1, .action = VIA_DXS_NO_VRA }, /* ASUS A7V8-X */
2380 { .subvendor = 0x1043, .subdevice = 0x80b0, .action = VIA_DXS_NO_VRA }, /* ASUS A7V600 & K8V*/
2381 { .subvendor = 0x1043, .subdevice = 0x810d, .action = VIA_DXS_SRC }, /* ASUS */
2382 { .subvendor = 0x1043, .subdevice = 0x812a, .action = VIA_DXS_SRC }, /* ASUS A8V Deluxe */
2383 { .subvendor = 0x1043, .subdevice = 0x8174, .action = VIA_DXS_SRC }, /* ASUS */
2384 { .subvendor = 0x1043, .subdevice = 0x81b9, .action = VIA_DXS_SRC }, /* ASUS A8V-MX */
2385 { .subvendor = 0x1071, .subdevice = 0x8375, .action = VIA_DXS_NO_VRA }, /* Vobis/Yakumo/Mitac notebook */
2386 { .subvendor = 0x1071, .subdevice = 0x8399, .action = VIA_DXS_NO_VRA }, /* Umax AB 595T (VIA K8N800A - VT8237) */
2387 { .subvendor = 0x10cf, .subdevice = 0x118e, .action = VIA_DXS_ENABLE }, /* FSC laptop */
2388 { .subvendor = 0x1106, .subdevice = 0x4161, .action = VIA_DXS_NO_VRA }, /* ASRock K7VT2 */
2389 { .subvendor = 0x1106, .subdevice = 0x4552, .action = VIA_DXS_NO_VRA }, /* QDI Kudoz 7X/600-6AL */
2390 { .subvendor = 0x1106, .subdevice = 0xaa01, .action = VIA_DXS_NO_VRA }, /* EPIA MII */
2391 { .subvendor = 0x1106, .subdevice = 0xc001, .action = VIA_DXS_SRC }, /* Insight P4-ITX */
2392 { .subvendor = 0x1297, .subdevice = 0xa232, .action = VIA_DXS_ENABLE }, /* Shuttle ?? */
2393 { .subvendor = 0x1297, .subdevice = 0xc160, .action = VIA_DXS_ENABLE }, /* Shuttle SK41G */
2394 { .subvendor = 0x1458, .subdevice = 0xa002, .action = VIA_DXS_ENABLE }, /* Gigabyte GA-7VAXP */
2395 { .subvendor = 0x1462, .subdevice = 0x0080, .action = VIA_DXS_SRC }, /* MSI K8T Neo-FIS2R */
2396 { .subvendor = 0x1462, .subdevice = 0x0430, .action = VIA_DXS_SRC }, /* MSI 7142 (K8MM-V) */
2397 { .subvendor = 0x1462, .subdevice = 0x0470, .action = VIA_DXS_SRC }, /* MSI KT880 Delta-FSR */
2398 { .subvendor = 0x1462, .subdevice = 0x3800, .action = VIA_DXS_ENABLE }, /* MSI KT266 */
2399 { .subvendor = 0x1462, .subdevice = 0x5901, .action = VIA_DXS_NO_VRA }, /* MSI KT6 Delta-SR */
2400 { .subvendor = 0x1462, .subdevice = 0x7023, .action = VIA_DXS_SRC }, /* MSI K8T Neo2-FI */
2401 { .subvendor = 0x1462, .subdevice = 0x7120, .action = VIA_DXS_ENABLE }, /* MSI KT4V */
2402 { .subvendor = 0x1462, .subdevice = 0x7142, .action = VIA_DXS_ENABLE }, /* MSI K8MM-V */
2403 { .subvendor = 0x1462, .subdevice = 0xb012, .action = VIA_DXS_SRC }, /* P4M800/VIA8237R */
2404 { .subvendor = 0x147b, .subdevice = 0x1401, .action = VIA_DXS_ENABLE }, /* ABIT KD7(-RAID) */
2405 { .subvendor = 0x147b, .subdevice = 0x1411, .action = VIA_DXS_ENABLE }, /* ABIT VA-20 */
2406 { .subvendor = 0x147b, .subdevice = 0x1413, .action = VIA_DXS_ENABLE }, /* ABIT KV8 Pro */
2407 { .subvendor = 0x147b, .subdevice = 0x1415, .action = VIA_DXS_NO_VRA }, /* Abit AV8 */
2408 { .subvendor = 0x14ff, .subdevice = 0x0403, .action = VIA_DXS_ENABLE }, /* Twinhead mobo */
2409 { .subvendor = 0x14ff, .subdevice = 0x0408, .action = VIA_DXS_SRC }, /* Twinhead laptop */
2410 { .subvendor = 0x1558, .subdevice = 0x4701, .action = VIA_DXS_SRC }, /* Clevo D470 */
2411 { .subvendor = 0x1584, .subdevice = 0x8120, .action = VIA_DXS_ENABLE }, /* Gericom/Targa/Vobis/Uniwill laptop */
2412 { .subvendor = 0x1584, .subdevice = 0x8123, .action = VIA_DXS_NO_VRA }, /* Uniwill (Targa Visionary XP-210) */
2413 { .subvendor = 0x161f, .subdevice = 0x202b, .action = VIA_DXS_NO_VRA }, /* Amira Note book */
2414 { .subvendor = 0x161f, .subdevice = 0x2032, .action = VIA_DXS_48K }, /* m680x machines */
2415 { .subvendor = 0x1631, .subdevice = 0xe004, .action = VIA_DXS_ENABLE }, /* Easy Note 3174, Packard Bell */
2416 { .subvendor = 0x1695, .subdevice = 0x3005, .action = VIA_DXS_ENABLE }, /* EPoX EP-8K9A */
2417 { .subvendor = 0x1695, .subdevice = 0x300c, .action = VIA_DXS_SRC }, /* EPoX EP-8KRAI */
2418 { .subvendor = 0x1695, .subdevice = 0x300e, .action = VIA_DXS_SRC }, /* EPoX 9HEAI */
2419 { .subvendor = 0x16f3, .subdevice = 0x6405, .action = VIA_DXS_SRC }, /* Jetway K8M8MS */
2420 { .subvendor = 0x1734, .subdevice = 0x1078, .action = VIA_DXS_SRC }, /* FSC Amilo L7300 */
2421 { .subvendor = 0x1734, .subdevice = 0x1093, .action = VIA_DXS_SRC }, /* FSC */
2422 { .subvendor = 0x1734, .subdevice = 0x10ab, .action = VIA_DXS_SRC }, /* FSC */
2423 { .subvendor = 0x1849, .subdevice = 0x3059, .action = VIA_DXS_NO_VRA }, /* ASRock K7VM2 */
2424 { .subvendor = 0x1849, .subdevice = 0x9739, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */
2425 { .subvendor = 0x1849, .subdevice = 0x9761, .action = VIA_DXS_SRC }, /* ASRock mobo(?) */
2426 { .subvendor = 0x1919, .subdevice = 0x200a, .action = VIA_DXS_NO_VRA }, /* Soltek SL-K8Tpro-939 */
2427 { .subvendor = 0x4005, .subdevice = 0x4710, .action = VIA_DXS_SRC }, /* MSI K7T266 Pro2 (MS-6380 V2.0) BIOS 3.7 */
2428 { } /* terminator */
2429 };
2430 const struct dxs_whitelist *w;
2431 unsigned short subsystem_vendor;
2432 unsigned short subsystem_device;
2433
2434 pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
2435 pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
2436 2407
2437 for (w = whitelist; w->subvendor; w++) { 2408 w = snd_pci_quirk_lookup(pci, dxs_whitelist);
2438 if (w->subvendor != subsystem_vendor) 2409 if (w) {
2439 continue; 2410 snd_printdd(KERN_INFO "via82xx: DXS white list for %s found\n",
2440 if (w->mask) { 2411 w->name);
2441 if ((w->mask & subsystem_device) == w->subdevice) 2412 return w->value;
2442 return w->action;
2443 } else {
2444 if (subsystem_device == w->subdevice)
2445 return w->action;
2446 }
2447 } 2413 }
2448 2414
2449 /* for newer revision, default to DXS_SRC */ 2415 /* for newer revision, default to DXS_SRC */
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 17d6b847585f..b338e15db0d9 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -900,7 +900,7 @@ static int __devinit snd_via82xx_mixer_new(struct via82xx_modem *chip)
900 ac97.private_data = chip; 900 ac97.private_data = chip;
901 ac97.private_free = snd_via82xx_mixer_free_ac97; 901 ac97.private_free = snd_via82xx_mixer_free_ac97;
902 ac97.pci = chip->pci; 902 ac97.pci = chip->pci;
903 ac97.scaps = AC97_SCAP_SKIP_AUDIO; 903 ac97.scaps = AC97_SCAP_SKIP_AUDIO | AC97_SCAP_POWER_SAVE;
904 ac97.num = chip->ac97_secondary; 904 ac97.num = chip->ac97_secondary;
905 905
906 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0) 906 if ((err = snd_ac97_mixer(chip->ac97_bus, &ac97, &chip->ac97)) < 0)
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index 89f58ea180b3..474eac9490ae 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -73,8 +73,8 @@ MODULE_DEVICE_TABLE(pci, snd_vx222_ids);
73/* 73/*
74 */ 74 */
75 75
76static DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0); 76static const DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0);
77static DECLARE_TLV_DB_SCALE(db_scale_akm, -7350, 50, 0); 77static const DECLARE_TLV_DB_SCALE(db_scale_akm, -7350, 50, 0);
78 78
79static struct snd_vx_hardware vx222_old_hw = { 79static struct snd_vx_hardware vx222_old_hw = {
80 80
diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c
index 5e51950e05f9..55558bef7166 100644
--- a/sound/pci/vx222/vx222_ops.c
+++ b/sound/pci/vx222/vx222_ops.c
@@ -846,7 +846,7 @@ static void vx2_set_input_level(struct snd_vx222 *chip)
846 846
847#define MIC_LEVEL_MAX 0xff 847#define MIC_LEVEL_MAX 0xff
848 848
849static DECLARE_TLV_DB_SCALE(db_scale_mic, -6450, 50, 0); 849static const DECLARE_TLV_DB_SCALE(db_scale_mic, -6450, 50, 0);
850 850
851/* 851/*
852 * controls API for input levels 852 * controls API for input levels
diff --git a/sound/pci/ymfpci/ymfpci_image.h b/sound/pci/ymfpci/ymfpci_image.h
index 1b0746991669..112f2fff6c8e 100644
--- a/sound/pci/ymfpci/ymfpci_image.h
+++ b/sound/pci/ymfpci/ymfpci_image.h
@@ -1,7 +1,7 @@
1#ifndef _HWMCODE_ 1#ifndef _HWMCODE_
2#define _HWMCODE_ 2#define _HWMCODE_
3 3
4static unsigned long DspInst[YDSXG_DSPLENGTH / 4] = { 4static u32 DspInst[YDSXG_DSPLENGTH / 4] = {
5 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f, 5 0x00000081, 0x000001a4, 0x0000000a, 0x0000002f,
6 0x00080253, 0x01800317, 0x0000407b, 0x0000843f, 6 0x00080253, 0x01800317, 0x0000407b, 0x0000843f,
7 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c, 7 0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c,
@@ -12,7 +12,7 @@ static unsigned long DspInst[YDSXG_DSPLENGTH / 4] = {
12 0x00000000, 0x00000000, 0x00000000, 0x00000000 12 0x00000000, 0x00000000, 0x00000000, 0x00000000
13}; 13};
14 14
15static unsigned long CntrlInst[YDSXG_CTRLLENGTH / 4] = { 15static u32 CntrlInst[YDSXG_CTRLLENGTH / 4] = {
16 0x000007, 0x240007, 0x0C0007, 0x1C0007, 16 0x000007, 0x240007, 0x0C0007, 0x1C0007,
17 0x060007, 0x700002, 0x000020, 0x030040, 17 0x060007, 0x700002, 0x000020, 0x030040,
18 0x007104, 0x004286, 0x030040, 0x000F0D, 18 0x007104, 0x004286, 0x030040, 0x000F0D,
@@ -791,7 +791,7 @@ static unsigned long CntrlInst[YDSXG_CTRLLENGTH / 4] = {
791// 04/09 creat 791// 04/09 creat
792// 04/12 stop nise fix 792// 04/12 stop nise fix
793// 06/21 WorkingOff timming 793// 06/21 WorkingOff timming
794static unsigned long CntrlInst1E[YDSXG_CTRLLENGTH / 4] = { 794static u32 CntrlInst1E[YDSXG_CTRLLENGTH / 4] = {
795 0x000007, 0x240007, 0x0C0007, 0x1C0007, 795 0x000007, 0x240007, 0x0C0007, 0x1C0007,
796 0x060007, 0x700002, 0x000020, 0x030040, 796 0x060007, 0x700002, 0x000020, 0x030040,
797 0x007104, 0x004286, 0x030040, 0x000F0D, 797 0x007104, 0x004286, 0x030040, 0x000F0D,
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 7881944a1957..fd12674d0394 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -2,12 +2,6 @@
2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz> 2 * Copyright (c) by Jaroslav Kysela <perex@suse.cz>
3 * Routines for control of YMF724/740/744/754 chips 3 * Routines for control of YMF724/740/744/754 chips
4 * 4 *
5 * BUGS:
6 * --
7 *
8 * TODO:
9 * --
10 *
11 * This program is free software; you can redistribute it and/or modify 5 * 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 6 * 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 7 * the Free Software Foundation; either version 2 of the License, or
@@ -26,6 +20,7 @@
26 20
27#include <sound/driver.h> 21#include <sound/driver.h>
28#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/firmware.h>
29#include <linux/init.h> 24#include <linux/init.h>
30#include <linux/interrupt.h> 25#include <linux/interrupt.h>
31#include <linux/pci.h> 26#include <linux/pci.h>
@@ -42,10 +37,7 @@
42#include <sound/mpu401.h> 37#include <sound/mpu401.h>
43 38
44#include <asm/io.h> 39#include <asm/io.h>
45 40#include <asm/byteorder.h>
46/*
47 * constants
48 */
49 41
50/* 42/*
51 * common I/O routines 43 * common I/O routines
@@ -179,6 +171,17 @@ static u32 snd_ymfpci_calc_lpfQ(u32 rate)
179 return val[0]; 171 return val[0];
180} 172}
181 173
174static void snd_ymfpci_pcm_441_volume_set(struct snd_ymfpci_pcm *ypcm)
175{
176 unsigned int value;
177 struct snd_ymfpci_pcm_mixer *mixer;
178
179 mixer = &ypcm->chip->pcm_mixer[ypcm->substream->number];
180 value = min_t(unsigned int, mixer->left, 0x7fff) >> 1;
181 value |= (min_t(unsigned int, mixer->right, 0x7fff) >> 1) << 16;
182 snd_ymfpci_writel(ypcm->chip, YDSXGR_BUF441OUTVOL, value);
183}
184
182/* 185/*
183 * Hardware start management 186 * Hardware start management
184 */ 187 */
@@ -290,6 +293,10 @@ static int snd_ymfpci_voice_free(struct snd_ymfpci *chip, struct snd_ymfpci_voic
290 snd_assert(pvoice != NULL, return -EINVAL); 293 snd_assert(pvoice != NULL, return -EINVAL);
291 snd_ymfpci_hw_stop(chip); 294 snd_ymfpci_hw_stop(chip);
292 spin_lock_irqsave(&chip->voice_lock, flags); 295 spin_lock_irqsave(&chip->voice_lock, flags);
296 if (pvoice->number == chip->src441_used) {
297 chip->src441_used = -1;
298 pvoice->ypcm->use_441_slot = 0;
299 }
293 pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0; 300 pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = 0;
294 pvoice->ypcm = NULL; 301 pvoice->ypcm = NULL;
295 pvoice->interrupt = NULL; 302 pvoice->interrupt = NULL;
@@ -394,7 +401,7 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
394 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 401 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
395 case SNDRV_PCM_TRIGGER_RESUME: 402 case SNDRV_PCM_TRIGGER_RESUME:
396 chip->ctrl_playback[ypcm->voices[0]->number + 1] = cpu_to_le32(ypcm->voices[0]->bank_addr); 403 chip->ctrl_playback[ypcm->voices[0]->number + 1] = cpu_to_le32(ypcm->voices[0]->bank_addr);
397 if (ypcm->voices[1] != NULL) 404 if (ypcm->voices[1] != NULL && !ypcm->use_441_slot)
398 chip->ctrl_playback[ypcm->voices[1]->number + 1] = cpu_to_le32(ypcm->voices[1]->bank_addr); 405 chip->ctrl_playback[ypcm->voices[1]->number + 1] = cpu_to_le32(ypcm->voices[1]->bank_addr);
399 ypcm->running = 1; 406 ypcm->running = 1;
400 break; 407 break;
@@ -402,7 +409,7 @@ static int snd_ymfpci_playback_trigger(struct snd_pcm_substream *substream,
402 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 409 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
403 case SNDRV_PCM_TRIGGER_SUSPEND: 410 case SNDRV_PCM_TRIGGER_SUSPEND:
404 chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0; 411 chip->ctrl_playback[ypcm->voices[0]->number + 1] = 0;
405 if (ypcm->voices[1] != NULL) 412 if (ypcm->voices[1] != NULL && !ypcm->use_441_slot)
406 chip->ctrl_playback[ypcm->voices[1]->number + 1] = 0; 413 chip->ctrl_playback[ypcm->voices[1]->number + 1] = 0;
407 ypcm->running = 0; 414 ypcm->running = 0;
408 break; 415 break;
@@ -489,6 +496,7 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int
489 unsigned int nbank; 496 unsigned int nbank;
490 u32 vol_left, vol_right; 497 u32 vol_left, vol_right;
491 u8 use_left, use_right; 498 u8 use_left, use_right;
499 unsigned long flags;
492 500
493 snd_assert(voice != NULL, return); 501 snd_assert(voice != NULL, return);
494 if (runtime->channels == 1) { 502 if (runtime->channels == 1) {
@@ -507,11 +515,27 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int
507 vol_left = cpu_to_le32(0x40000000); 515 vol_left = cpu_to_le32(0x40000000);
508 vol_right = cpu_to_le32(0x40000000); 516 vol_right = cpu_to_le32(0x40000000);
509 } 517 }
518 spin_lock_irqsave(&ypcm->chip->voice_lock, flags);
510 format = runtime->channels == 2 ? 0x00010000 : 0; 519 format = runtime->channels == 2 ? 0x00010000 : 0;
511 if (snd_pcm_format_width(runtime->format) == 8) 520 if (snd_pcm_format_width(runtime->format) == 8)
512 format |= 0x80000000; 521 format |= 0x80000000;
522 else if (ypcm->chip->device_id == PCI_DEVICE_ID_YAMAHA_754 &&
523 runtime->rate == 44100 && runtime->channels == 2 &&
524 voiceidx == 0 && (ypcm->chip->src441_used == -1 ||
525 ypcm->chip->src441_used == voice->number)) {
526 ypcm->chip->src441_used = voice->number;
527 ypcm->use_441_slot = 1;
528 format |= 0x10000000;
529 snd_ymfpci_pcm_441_volume_set(ypcm);
530 }
531 if (ypcm->chip->src441_used == voice->number &&
532 (format & 0x10000000) == 0) {
533 ypcm->chip->src441_used = -1;
534 ypcm->use_441_slot = 0;
535 }
513 if (runtime->channels == 2 && (voiceidx & 1) != 0) 536 if (runtime->channels == 2 && (voiceidx & 1) != 0)
514 format |= 1; 537 format |= 1;
538 spin_unlock_irqrestore(&ypcm->chip->voice_lock, flags);
515 for (nbank = 0; nbank < 2; nbank++) { 539 for (nbank = 0; nbank < 2; nbank++) {
516 bank = &voice->bank[nbank]; 540 bank = &voice->bank[nbank];
517 memset(bank, 0, sizeof(*bank)); 541 memset(bank, 0, sizeof(*bank));
@@ -1480,7 +1504,7 @@ static int snd_ymfpci_put_single(struct snd_kcontrol *kcontrol,
1480 return change; 1504 return change;
1481} 1505}
1482 1506
1483static DECLARE_TLV_DB_LINEAR(db_scale_native, TLV_DB_GAIN_MUTE, 0); 1507static const DECLARE_TLV_DB_LINEAR(db_scale_native, TLV_DB_GAIN_MUTE, 0);
1484 1508
1485#define YMFPCI_DOUBLE(xname, xindex, reg) \ 1509#define YMFPCI_DOUBLE(xname, xindex, reg) \
1486{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \ 1510{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
@@ -1722,7 +1746,10 @@ static int snd_ymfpci_pcm_vol_put(struct snd_kcontrol *kcontrol,
1722 spin_lock_irqsave(&chip->voice_lock, flags); 1746 spin_lock_irqsave(&chip->voice_lock, flags);
1723 if (substream->runtime && substream->runtime->private_data) { 1747 if (substream->runtime && substream->runtime->private_data) {
1724 struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data; 1748 struct snd_ymfpci_pcm *ypcm = substream->runtime->private_data;
1725 ypcm->update_pcm_vol = 2; 1749 if (!ypcm->use_441_slot)
1750 ypcm->update_pcm_vol = 2;
1751 else
1752 snd_ymfpci_pcm_441_volume_set(ypcm);
1726 } 1753 }
1727 spin_unlock_irqrestore(&chip->voice_lock, flags); 1754 spin_unlock_irqrestore(&chip->voice_lock, flags);
1728 return 1; 1755 return 1;
@@ -1971,13 +1998,94 @@ static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip)
1971 } 1998 }
1972} 1999}
1973 2000
2001#define FIRMWARE_IN_THE_KERNEL
2002
2003#ifdef FIRMWARE_IN_THE_KERNEL
2004
1974#include "ymfpci_image.h" 2005#include "ymfpci_image.h"
1975 2006
2007static struct firmware snd_ymfpci_dsp_microcode = {
2008 .size = YDSXG_DSPLENGTH,
2009 .data = (u8 *)DspInst,
2010};
2011static struct firmware snd_ymfpci_controller_microcode = {
2012 .size = YDSXG_CTRLLENGTH,
2013 .data = (u8 *)CntrlInst,
2014};
2015static struct firmware snd_ymfpci_controller_1e_microcode = {
2016 .size = YDSXG_CTRLLENGTH,
2017 .data = (u8 *)CntrlInst1E,
2018};
2019#endif
2020
2021#ifdef __LITTLE_ENDIAN
2022static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { }
2023#else
2024static void snd_ymfpci_convert_from_le(const struct firmware *fw)
2025{
2026 int i;
2027 u32 *data = (u32 *)fw->data;
2028
2029 for (i = 0; i < fw->size / 4; ++i)
2030 le32_to_cpus(&data[i]);
2031}
2032#endif
2033
2034static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip)
2035{
2036 int err, is_1e;
2037 const char *name;
2038
2039 err = request_firmware(&chip->dsp_microcode, "yamaha/ds1_dsp.fw",
2040 &chip->pci->dev);
2041 if (err >= 0) {
2042 if (chip->dsp_microcode->size == YDSXG_DSPLENGTH)
2043 snd_ymfpci_convert_from_le(chip->dsp_microcode);
2044 else {
2045 snd_printk(KERN_ERR "DSP microcode has wrong size\n");
2046 err = -EINVAL;
2047 }
2048 }
2049 if (err < 0) {
2050#ifdef FIRMWARE_IN_THE_KERNEL
2051 chip->dsp_microcode = &snd_ymfpci_dsp_microcode;
2052#else
2053 return err;
2054#endif
2055 }
2056 is_1e = chip->device_id == PCI_DEVICE_ID_YAMAHA_724F ||
2057 chip->device_id == PCI_DEVICE_ID_YAMAHA_740C ||
2058 chip->device_id == PCI_DEVICE_ID_YAMAHA_744 ||
2059 chip->device_id == PCI_DEVICE_ID_YAMAHA_754;
2060 name = is_1e ? "yamaha/ds1e_ctrl.fw" : "yamaha/ds1_ctrl.fw";
2061 err = request_firmware(&chip->controller_microcode, name,
2062 &chip->pci->dev);
2063 if (err >= 0) {
2064 if (chip->controller_microcode->size == YDSXG_CTRLLENGTH)
2065 snd_ymfpci_convert_from_le(chip->controller_microcode);
2066 else {
2067 snd_printk(KERN_ERR "controller microcode"
2068 " has wrong size\n");
2069 err = -EINVAL;
2070 }
2071 }
2072 if (err < 0) {
2073#ifdef FIRMWARE_IN_THE_KERNEL
2074 chip->controller_microcode =
2075 is_1e ? &snd_ymfpci_controller_1e_microcode
2076 : &snd_ymfpci_controller_microcode;
2077#else
2078 return err;
2079#endif
2080 }
2081 return 0;
2082}
2083
1976static void snd_ymfpci_download_image(struct snd_ymfpci *chip) 2084static void snd_ymfpci_download_image(struct snd_ymfpci *chip)
1977{ 2085{
1978 int i; 2086 int i;
1979 u16 ctrl; 2087 u16 ctrl;
1980 unsigned long *inst; 2088 u32 *inst;
1981 2089
1982 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x00000000); 2090 snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0x00000000);
1983 snd_ymfpci_disable_dsp(chip); 2091 snd_ymfpci_disable_dsp(chip);
@@ -1992,21 +2100,12 @@ static void snd_ymfpci_download_image(struct snd_ymfpci *chip)
1992 snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007); 2100 snd_ymfpci_writew(chip, YDSXGR_GLOBALCTRL, ctrl & ~0x0007);
1993 2101
1994 /* setup DSP instruction code */ 2102 /* setup DSP instruction code */
2103 inst = (u32 *)chip->dsp_microcode->data;
1995 for (i = 0; i < YDSXG_DSPLENGTH / 4; i++) 2104 for (i = 0; i < YDSXG_DSPLENGTH / 4; i++)
1996 snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2), DspInst[i]); 2105 snd_ymfpci_writel(chip, YDSXGR_DSPINSTRAM + (i << 2), inst[i]);
1997 2106
1998 /* setup control instruction code */ 2107 /* setup control instruction code */
1999 switch (chip->device_id) { 2108 inst = (u32 *)chip->controller_microcode->data;
2000 case PCI_DEVICE_ID_YAMAHA_724F:
2001 case PCI_DEVICE_ID_YAMAHA_740C:
2002 case PCI_DEVICE_ID_YAMAHA_744:
2003 case PCI_DEVICE_ID_YAMAHA_754:
2004 inst = CntrlInst1E;
2005 break;
2006 default:
2007 inst = CntrlInst;
2008 break;
2009 }
2010 for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++) 2109 for (i = 0; i < YDSXG_CTRLLENGTH / 4; i++)
2011 snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2), inst[i]); 2110 snd_ymfpci_writel(chip, YDSXGR_CTRLINSTRAM + (i << 2), inst[i]);
2012 2111
@@ -2160,6 +2259,15 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip)
2160 pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl); 2259 pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl);
2161 2260
2162 pci_disable_device(chip->pci); 2261 pci_disable_device(chip->pci);
2262#ifdef FIRMWARE_IN_THE_KERNEL
2263 if (chip->dsp_microcode != &snd_ymfpci_dsp_microcode)
2264#endif
2265 release_firmware(chip->dsp_microcode);
2266#ifdef FIRMWARE_IN_THE_KERNEL
2267 if (chip->controller_microcode != &snd_ymfpci_controller_microcode &&
2268 chip->controller_microcode != &snd_ymfpci_controller_1e_microcode)
2269#endif
2270 release_firmware(chip->controller_microcode);
2163 kfree(chip); 2271 kfree(chip);
2164 return 0; 2272 return 0;
2165} 2273}
@@ -2180,7 +2288,7 @@ static int saved_regs_index[] = {
2180 YDSXGR_PRIADCLOOPVOL, 2288 YDSXGR_PRIADCLOOPVOL,
2181 YDSXGR_NATIVEDACINVOL, 2289 YDSXGR_NATIVEDACINVOL,
2182 YDSXGR_NATIVEDACOUTVOL, 2290 YDSXGR_NATIVEDACOUTVOL,
2183 // YDSXGR_BUF441OUTVOL, 2291 YDSXGR_BUF441OUTVOL,
2184 YDSXGR_NATIVEADCINVOL, 2292 YDSXGR_NATIVEADCINVOL,
2185 YDSXGR_SPDIFLOOPVOL, 2293 YDSXGR_SPDIFLOOPVOL,
2186 YDSXGR_SPDIFOUTVOL, 2294 YDSXGR_SPDIFOUTVOL,
@@ -2295,6 +2403,7 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
2295 chip->reg_area_phys = pci_resource_start(pci, 0); 2403 chip->reg_area_phys = pci_resource_start(pci, 0);
2296 chip->reg_area_virt = ioremap_nocache(chip->reg_area_phys, 0x8000); 2404 chip->reg_area_virt = ioremap_nocache(chip->reg_area_phys, 0x8000);
2297 pci_set_master(pci); 2405 pci_set_master(pci);
2406 chip->src441_used = -1;
2298 2407
2299 if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) { 2408 if ((chip->res_reg_area = request_mem_region(chip->reg_area_phys, 0x8000, "YMFPCI")) == NULL) {
2300 snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1); 2409 snd_printk(KERN_ERR "unable to grab memory region 0x%lx-0x%lx\n", chip->reg_area_phys, chip->reg_area_phys + 0x8000 - 1);
@@ -2315,6 +2424,12 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
2315 return -EIO; 2424 return -EIO;
2316 } 2425 }
2317 2426
2427 err = snd_ymfpci_request_firmware(chip);
2428 if (err < 0) {
2429 snd_printk(KERN_ERR "firmware request failed: %d\n", err);
2430 snd_ymfpci_free(chip);
2431 return err;
2432 }
2318 snd_ymfpci_download_image(chip); 2433 snd_ymfpci_download_image(chip);
2319 2434
2320 udelay(100); /* seems we need a delay after downloading image.. */ 2435 udelay(100); /* seems we need a delay after downloading image.. */