diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-09 11:24:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-09 11:24:04 -0500 |
commit | 6026179519896e7d35b2564e7544487d1c8948e7 (patch) | |
tree | c78c7032abce24d846423572204f1cd4e97d8efc /sound/pci | |
parent | d27146dd5b72ab7d7e641f56f4bee1484dabd0b7 (diff) | |
parent | c2902c8ae06762d941fab64198467f78cab6f8cd (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')
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 | |||
236 | config SND_DARLA20 | 236 | config 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 | |||
247 | config SND_GINA20 | 247 | config 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 | |||
258 | config SND_LAYLA20 | 258 | config 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 | |||
270 | config SND_DARLA24 | 270 | config 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 | |||
281 | config SND_GINA24 | 281 | config 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 | |||
292 | config SND_LAYLA24 | 292 | config 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 | |||
304 | config SND_MONA | 304 | config 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 | |||
316 | config SND_MIA | 316 | config 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 | |||
328 | config SND_ECHO3G | 328 | config 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 | |||
340 | config SND_INDIGO | 340 | config 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 | |||
351 | config SND_INDIGOIO | 351 | config 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 | |||
362 | config SND_INDIGODJ | 362 | config 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 | |||
373 | config SND_EMU10K1 | 373 | config 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 | |||
575 | config SND_KORG1212 | 576 | config 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 | |||
585 | config SND_MAESTRO3 | 587 | config 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 | |||
629 | config SND_RIPTIDE | 632 | config 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 | |||
734 | config SND_YMFPCI | 737 | config 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 | ||
196 | static void update_power_regs(struct snd_ac97 *ac97); | 196 | static 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 | */ |
1187 | static DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0); | 1194 | static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0); |
1188 | static DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0); | 1195 | static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0); |
1189 | static DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); | 1196 | static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0); |
1190 | static DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); | 1197 | static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0); |
1191 | static DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); | 1198 | static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0); |
1192 | 1199 | ||
1193 | static unsigned int *find_db_scale(unsigned int maxval) | 1200 | static 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 | ||
1203 | static void set_tlv_db_scale(struct snd_kcontrol *kctl, unsigned int *tlv) | 1210 | static 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 */ |
56 | static void reset_tlv(struct snd_ac97 *ac97, const char *name, | 56 | static 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 */ | ||
194 | static 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 */ | ||
200 | static 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 */ | ||
193 | static inline int is_shared_linein(struct snd_ac97 *ac97) | 206 | static 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 */ | ||
198 | static inline int is_shared_micin(struct snd_ac97 *ac97) | 212 | static 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 | ||
1555 | static DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max, -8850, 150, 0); | 1572 | static const DECLARE_TLV_DB_SCALE(db_scale_6bit_6db_max, -8850, 150, 0); |
1556 | 1573 | ||
1557 | static int patch_ad1885_specific(struct snd_ac97 * ac97) | 1574 | static 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 | ||
1634 | static int snd_ac97_ad198x_spdif_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1731 | static 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 | ||
2052 | static 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 | |||
2067 | static 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 | |||
2079 | static 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 | |||
1955 | static const struct snd_kcontrol_new snd_ac97_ad1985_controls[] = { | 2095 | static 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 | ||
1959 | static void ad1985_update_jacks(struct snd_ac97 *ac97) | 2128 | static 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 | ||
1975 | static struct snd_ac97_build_ops patch_ad1985_build_ops = { | 2151 | static 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 | ||
2185 | static 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 | |||
2195 | static 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 | |||
2206 | static 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 | |||
2231 | static 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 | |||
2242 | static 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 | |||
2267 | static 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 | |||
2276 | static 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 | |||
2291 | static 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 | |||
2310 | static 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 | |||
2363 | static 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 | |||
2407 | static 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 | |||
2440 | static 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 | |||
2451 | static 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 | |||
2460 | int 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 | ||
2067 | static DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max, -4350, 150, 0); | 2530 | static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_max, -4350, 150, 0); |
2068 | 2531 | ||
2069 | static int patch_alc650_specific(struct snd_ac97 * ac97) | 2532 | static 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 | */ |
2380 | static void cm9738_update_jacks(struct snd_ac97 *ac97) | 2844 | static 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 | ||
2387 | static const struct snd_kcontrol_new snd_ac97_cm9738_controls[] = { | 2851 | static 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 | ||
2464 | static void cm9739_update_jacks(struct snd_ac97 *ac97) | 2928 | static 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 | ||
2474 | static const struct snd_kcontrol_new snd_ac97_cm9739_controls[] = { | 2938 | static 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 | */ |
2829 | static void it2646_update_jacks(struct snd_ac97 *ac97) | 3294 | static 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 | ||
2839 | static const struct snd_kcontrol_new snd_ac97_controls_it2646[] = { | 3304 | static 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); | |||
48 | int patch_ad1981a(struct snd_ac97 * ac97); | 48 | int patch_ad1981a(struct snd_ac97 * ac97); |
49 | int patch_ad1981b(struct snd_ac97 * ac97); | 49 | int patch_ad1981b(struct snd_ac97 * ac97); |
50 | int patch_ad1985(struct snd_ac97 * ac97); | 50 | int patch_ad1985(struct snd_ac97 * ac97); |
51 | int patch_ad1986(struct snd_ac97 * ac97); | ||
51 | int patch_alc650(struct snd_ac97 * ac97); | 52 | int patch_alc650(struct snd_ac97 * ac97); |
52 | int patch_alc655(struct snd_ac97 * ac97); | 53 | int patch_alc655(struct snd_ac97 * ac97); |
53 | int patch_alc850(struct snd_ac97 * ac97); | 54 | int 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 | ||
270 | static DECLARE_TLV_DB_SCALE(db_scale_master, -6200, 200, 0); | 270 | static const DECLARE_TLV_DB_SCALE(db_scale_master, -6200, 200, 0); |
271 | static DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0); | 271 | static const DECLARE_TLV_DB_SCALE(db_scale_mono, -2800, 400, 0); |
272 | static DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0); | 272 | static const DECLARE_TLV_DB_SCALE(db_scale_input, -5000, 200, 0); |
273 | 273 | ||
274 | static struct snd_kcontrol_new snd_ak4531_controls[] = { | 274 | static 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 | ||
446 | static int snd_als300_pcm_hw_params(struct snd_pcm_substream *substream, | 446 | static 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 | ||
676 | static int __devinit snd_als300_create(snd_card_t *card, | 676 | static 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 */ | |||
45 | static int ac97_clock = 48000; | 45 | static int ac97_clock = 48000; |
46 | static char *ac97_quirk; | 46 | static char *ac97_quirk; |
47 | static int spdif_aclink = 1; | 47 | static int spdif_aclink = 1; |
48 | static int ac97_codec = -1; | ||
48 | 49 | ||
49 | module_param(index, int, 0444); | 50 | module_param(index, int, 0444); |
50 | MODULE_PARM_DESC(index, "Index value for ATI IXP controller."); | 51 | MODULE_PARM_DESC(index, "Index value for ATI IXP controller."); |
@@ -54,6 +55,8 @@ module_param(ac97_clock, int, 0444); | |||
54 | MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); | 55 | MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); |
55 | module_param(ac97_quirk, charp, 0444); | 56 | module_param(ac97_quirk, charp, 0444); |
56 | MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); | 57 | MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); |
58 | module_param(ac97_codec, int, 0444); | ||
59 | MODULE_PARM_DESC(ac97_codec, "Specify codec instead of probing."); | ||
57 | module_param(spdif_aclink, bool, 0444); | 60 | module_param(spdif_aclink, bool, 0444); |
58 | MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); | 61 | MODULE_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 | ||
294 | MODULE_DEVICE_TABLE(pci, snd_atiixp_ids); | 297 | MODULE_DEVICE_TABLE(pci, snd_atiixp_ids); |
295 | 298 | ||
299 | static 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 | ||
563 | static 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 | |||
556 | static int snd_atiixp_codec_detect(struct atiixp *chip) | 577 | static 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 | ||
77 | static DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1); | 77 | static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale1, -5175, 25, 1); |
78 | static DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1); | 78 | static const DECLARE_TLV_DB_SCALE(snd_ca0106_db_scale2, -10350, 50, 1); |
79 | 79 | ||
80 | static int snd_ca0106_shared_spdif_info(struct snd_kcontrol *kcontrol, | 80 | static 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 | |||
498 | static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = { | 485 | static 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 | |||
558 | static 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 | |||
564 | static int __devinit remove_ctl(struct snd_card *card, const char *name) | 565 | static 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 | ||
1058 | static DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0); | 1058 | static const DECLARE_TLV_DB_SCALE(db_scale_dsp, -4650, 150, 0); |
1059 | 1059 | ||
1060 | static struct snd_kcontrol_new snd_cs4281_fm_vol = | 1060 | static 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); | |||
39 | static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq, | 39 | static 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 | ||
44 | static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) | 44 | static 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); | |||
34 | MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard."); | 34 | MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard."); |
35 | 35 | ||
36 | static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; | 36 | static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999}; |
37 | static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1); | ||
37 | 38 | ||
38 | static int get_firmware(const struct firmware **fw_entry, | 39 | static 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, | |||
1011 | static struct snd_kcontrol_new snd_echo_line_output_gain __devinitdata = { | 1012 | static 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 |
1019 | static struct snd_kcontrol_new snd_echo_pcm_output_gain __devinitdata = { | 1022 | static 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 | ||
1088 | static const DECLARE_TLV_DB_SCALE(db_scale_input_gain, -2500, 50, 0); | ||
1089 | |||
1083 | static struct snd_kcontrol_new snd_echo_line_input_gain __devinitdata = { | 1090 | static 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, | |||
1277 | static struct snd_kcontrol_new snd_echo_monitor_mixer __devinitdata = { | 1286 | static 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, | |||
1343 | static struct snd_kcontrol_new snd_echo_vmixer __devinitdata = { | 1354 | static 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, | |||
1753 | static struct snd_kcontrol_new snd_echo_vumeters __devinitdata = { | 1766 | static 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 | |||
125 | static 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 | ||
121 | static int snd_emu10k1_init(struct snd_emu10k1 *emu, int enable_ir, int resume) | 141 | static 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 | ||
599 | static int snd_emu1212m_fpga_write(struct snd_emu10k1 * emu, int reg, int value) | 643 | static 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); | |
614 | static 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 | ||
626 | static 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 | ||
636 | static int snd_emu10k1_emu1212m_init(struct snd_emu10k1 * emu) | 690 | static 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, ® ); |
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, ® ); |
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, ® ); | ||
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, ® ); | ||
759 | snd_printk(KERN_INFO "emu1010: Card options=0x%x\n",reg); | ||
760 | snd_emu1010_fpga_read(emu, EMU_HANA_OPTION_CARDS, ® ); | ||
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, ® ); | ||
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, ® ); /* 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, ® ); | ||
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, ® ); | ||
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", ®, &channel_id, &val) != 3) | 1042 | if (sscanf(line, "%x %x %x", ®, &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 */ |
296 | static DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); | 299 | static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); |
297 | 300 | ||
298 | static const u32 onoff_table[2] = { | 301 | static 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 | |||
660 | static 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 | |||
682 | static 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 | |||
698 | static 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 | |||
655 | static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu, | 712 | static 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 | ||
720 | static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu, | 776 | static 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 | ||
1126 | static 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 | |||
1077 | static int __devinit _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu) | 1146 | static 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) \ |
1190 | A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input)) | 1257 | A_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? */ |
2142 | int snd_emu10k1_fx8010_tone_control_activate(struct snd_emu10k1 *emu, int output) | 2275 | int 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 | ||
45 | static const DECLARE_TLV_DB_SCALE(snd_audigy_db_scale2, -10350, 50, 1); /* WM8775 gain scale */ | ||
46 | |||
38 | static int snd_emu10k1_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 47 | static 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 | ||
80 | static 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 | |||
136 | static 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 | |||
192 | static 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 | |||
219 | static 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 | |||
244 | static 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 | |||
255 | static 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 | |||
266 | static 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 | |||
284 | static 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 | |||
295 | static 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 | |||
323 | static 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 | |||
360 | static 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 | |||
388 | static 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 | |||
397 | static 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 | |||
405 | static 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 | |||
436 | static 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 | |||
443 | static 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 | |||
452 | static 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 | |||
460 | static 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 | |||
491 | static 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 | |||
500 | static 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 | |||
516 | static 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 | |||
525 | static 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 | |||
576 | static 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 | |||
587 | static 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 | |||
608 | static 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 | |||
617 | static 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 | |||
659 | static 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 | |||
668 | static 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 | |||
678 | static 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 | |||
691 | static 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 | |||
738 | static 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 |
72 | static int snd_audigy_spdif_output_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 744 | static 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 | ||
982 | static 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 |
378 | static 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 | |||
375 | static void snd_emu_proc_io_reg_read(struct snd_info_entry *entry, | 399 | static 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", ®, &val) != 2) | 423 | if (sscanf(line, "%x %x", ®, &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", ®, &channel_id, &val) != 3) | 499 | if (sscanf(line, "%x %x %x", ®, &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 | ||
34 | unsigned int snd_emu10k1_ptr_read(struct snd_emu10k1 * emu, unsigned int reg, unsigned int chn) | 35 | unsigned 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 */ | ||
172 | int 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 | |||
229 | int 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 | |||
247 | int 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 | */ | ||
264 | int 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 | |||
170 | void snd_emu10k1_intr_enable(struct snd_emu10k1 *emu, unsigned int intrenb) | 274 | void 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 | } |
788 | static DECLARE_TLV_DB_SCALE(snd_p16v_db_scale1, -5175, 25, 1); | 788 | static 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 | ||
1610 | static struct { | 1608 | struct 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 | |||
1614 | static 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 | |||
1627 | static 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 | ||
1623 | static int snd_ensoniq_1371_mixer(struct ensoniq * ensoniq, int has_spdif, int has_line) | 1636 | static 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 | |||
1642 | static 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 |
1959 | static struct { | 1972 | static 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 | }; |
1969 | static struct { | 1979 | |
1970 | unsigned short vid; /* vendor ID */ | 1980 | static 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 | ||
1347 | static DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0); | 1347 | static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0); |
1348 | 1348 | ||
1349 | static struct snd_kcontrol_new snd_es1938_controls[] = { | 1349 | static struct snd_kcontrol_new snd_es1938_controls[] = { |
1350 | ES1938_DOUBLE_TLV("Master Playback Volume", 0, 0x60, 0x62, 0, 0, 63, 0, | 1350 | ES1938_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 | ||
1160 | static DECLARE_TLV_DB_SCALE(db_scale_dsp, -3450, 150, 0); | 1160 | static 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 @@ | |||
1 | snd-hda-intel-objs := hda_intel.o | 1 | snd-hda-intel-objs := hda_intel.o |
2 | snd-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 | 2 | snd-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 | ||
3 | ifdef CONFIG_PROC_FS | 12 | ifdef CONFIG_PROC_FS |
4 | snd-hda-codec-objs += hda_proc.o | 13 | snd-hda-codec-objs += hda_proc.o |
5 | endif | 14 | endif |
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 { | |||
52 | static struct hda_vendor_id hda_vendor_ids[] = { | 52 | static 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 | */ |
1725 | int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl) | 1722 | int 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 | */ | ||
1508 | static const struct snd_pci_quirk position_fix_list[] __devinitdata = { | ||
1509 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE), | ||
1510 | {} | ||
1511 | }; | ||
1512 | |||
1513 | static 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 | */ |
1507 | static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | 1533 | static 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 | */ |
176 | struct hda_board_config { | 176 | int 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 | |||
183 | int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl); | ||
184 | int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); | 179 | int 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[]; | |||
14 | extern struct hda_codec_preset snd_hda_preset_si3054[]; | 14 | extern struct hda_codec_preset snd_hda_preset_si3054[]; |
15 | /* ATI HDMI codecs */ | 15 | /* ATI HDMI codecs */ |
16 | extern struct hda_codec_preset snd_hda_preset_atihdmi[]; | 16 | extern struct hda_codec_preset snd_hda_preset_atihdmi[]; |
17 | /* Conexant audio codec */ | ||
18 | extern struct hda_codec_preset snd_hda_preset_conexant[]; | ||
19 | /* VIA codecs */ | ||
20 | extern struct hda_codec_preset snd_hda_preset_via[]; | ||
17 | 21 | ||
18 | static const struct hda_codec_preset *hda_preset_tables[] = { | 22 | static 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 */ |
784 | static struct hda_verb ad1986a_eapd_init_verbs[] = { | 784 | static 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 */ | ||
790 | static 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 */ |
790 | enum { AD1986A_6STACK, AD1986A_3STACK, AD1986A_LAPTOP, AD1986A_LAPTOP_EAPD }; | 801 | enum { |
791 | 802 | AD1986A_6STACK, | |
792 | static 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, | 810 | static 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 */ | 818 | static 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 */ |
1394 | enum { AD1981_BASIC, AD1981_HP, AD1981_THINKPAD }; | 1414 | enum { |
1415 | AD1981_BASIC, | ||
1416 | AD1981_HP, | ||
1417 | AD1981_THINKPAD, | ||
1418 | AD1981_MODELS | ||
1419 | }; | ||
1420 | |||
1421 | static const char *ad1981_models[AD1981_MODELS] = { | ||
1422 | [AD1981_HP] = "hp", | ||
1423 | [AD1981_THINKPAD] = "thinkpad", | ||
1424 | [AD1981_BASIC] = "basic", | ||
1425 | }; | ||
1395 | 1426 | ||
1396 | static struct hda_board_config ad1981_cfg_tbl[] = { | 1427 | static 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 | ||
2568 | static struct hda_board_config ad1988_cfg_tbl[] = { | 2597 | static 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 | ||
2579 | static int patch_ad1988(struct hda_codec *codec) | 2607 | static 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 | ||
45 | struct cmi_spec { | 46 | struct cmi_spec { |
@@ -603,14 +604,17 @@ static void cmi9880_free(struct hda_codec *codec) | |||
603 | /* | 604 | /* |
604 | */ | 605 | */ |
605 | 606 | ||
606 | static struct hda_board_config cmi9880_cfg_tbl[] = { | 607 | static 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 | |||
616 | static 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 | |||
43 | struct 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 | |||
91 | static 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 | |||
99 | static 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 | |||
111 | static 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 | */ | ||
122 | static 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 | |||
130 | static 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 | */ | ||
141 | static 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 | |||
153 | static 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 | |||
165 | static 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 | |||
177 | static 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 | |||
189 | static 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 | |||
200 | static 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 | |||
207 | static 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 | |||
244 | static 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 | |||
253 | static 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 | |||
264 | static 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 | |||
276 | static 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 | |||
286 | static 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 | ||
301 | static 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 | |||
317 | static 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 | |||
342 | static 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 | |||
357 | static 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 | |||
367 | static 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 | |||
380 | static 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 | |||
403 | static 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 | |||
412 | static 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 | |||
422 | static 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 | |||
442 | static 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 | |||
452 | static 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 | |||
466 | static 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 | |||
496 | static 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 | |||
506 | static 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 | |||
520 | static 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 | |||
555 | static hda_nid_t cxt5045_dac_nids[1] = { 0x19 }; | ||
556 | static hda_nid_t cxt5045_adc_nids[1] = { 0x1a }; | ||
557 | static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a }; | ||
558 | #define CXT5045_SPDIF_OUT 0x13 | ||
559 | |||
560 | static struct hda_channel_mode cxt5045_modes[1] = { | ||
561 | { 2, NULL }, | ||
562 | }; | ||
563 | |||
564 | static 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 */ | ||
573 | static 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 */ | ||
591 | static 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 */ | ||
611 | static 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 */ | ||
624 | static 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 | |||
635 | static 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 | |||
667 | static 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 | */ | ||
695 | static 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 | |||
706 | static 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 | |||
750 | static 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 */ | ||
801 | static int cxt5045_init(struct hda_codec *codec) | ||
802 | { | ||
803 | conexant_init(codec); | ||
804 | cxt5045_hp_automute(codec); | ||
805 | return 0; | ||
806 | } | ||
807 | |||
808 | |||
809 | enum { | ||
810 | CXT5045_LAPTOP, /* Laptops w/ EAPD support */ | ||
811 | #ifdef CONFIG_SND_DEBUG | ||
812 | CXT5045_TEST, | ||
813 | #endif | ||
814 | CXT5045_MODELS | ||
815 | }; | ||
816 | |||
817 | static const char *cxt5045_models[CXT5045_MODELS] = { | ||
818 | [CXT5045_LAPTOP] = "laptop", | ||
819 | #ifdef CONFIG_SND_DEBUG | ||
820 | [CXT5045_TEST] = "test", | ||
821 | #endif | ||
822 | }; | ||
823 | |||
824 | static struct snd_pci_quirk cxt5045_cfg_tbl[] = { | ||
825 | SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP), | ||
826 | {} | ||
827 | }; | ||
828 | |||
829 | static 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 | |||
884 | static hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; | ||
885 | static hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; | ||
886 | static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; | ||
887 | #define CXT5047_SPDIF_OUT 0x11 | ||
888 | |||
889 | static struct hda_channel_mode cxt5047_modes[1] = { | ||
890 | { 2, NULL }, | ||
891 | }; | ||
892 | |||
893 | static struct hda_input_mux cxt5047_capture_source = { | ||
894 | .num_items = 2, | ||
895 | .items = { | ||
896 | { "ExtMic", 0x1 }, | ||
897 | { "IntMic", 0x2 }, | ||
898 | } | ||
899 | }; | ||
900 | |||
901 | static 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 */ | ||
909 | static 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 */ | ||
928 | static 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 */ | ||
948 | static 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 */ | ||
961 | static 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 */ | ||
984 | static 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 | |||
998 | static 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 | |||
1025 | static 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 | |||
1051 | static 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 */ | ||
1073 | static 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 */ | ||
1082 | static 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 | ||
1093 | static 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 | |||
1104 | static 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 | |||
1152 | static 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 */ | ||
1214 | static 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 | |||
1223 | enum { | ||
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 | |||
1233 | static 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 | |||
1242 | static 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 | |||
1250 | static 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 | |||
1307 | struct 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 */ |
37 | enum { | 41 | enum { |
@@ -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 */ |
78 | enum { | 85 | enum { |
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 */ | ||
113 | enum { | ||
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 */ |
99 | enum { | 123 | enum { |
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 */ | ||
1048 | static 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 | |||
1077 | static 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 | |||
1091 | static 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 | */ | ||
1339 | static 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 | */ | ||
1377 | static 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 | |||
1406 | static 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 */ | ||
1412 | static 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 | |||
1433 | static 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 | |||
1444 | static 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 | |||
1457 | static 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 | } | ||
1475 | static 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 | ||
2128 | static struct hda_board_config alc880_cfg_tbl[] = { | 2364 | static 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 | |||
2391 | static 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 | */ |
3094 | static struct snd_kcontrol_new alc260_acer_mixer[] = { | 3331 | static 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 | */ |
3931 | static struct hda_board_config alc260_cfg_tbl[] = { | 4174 | static 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 | |||
4186 | static 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 */ | ||
4564 | static 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 | |||
4575 | static 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 | }; | ||
4625 | static 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 | */ |
4438 | static struct hda_board_config alc882_cfg_tbl[] = { | 4779 | static 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*/ | 4787 | static 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 | ||
5130 | static 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 | ||
5251 | static 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 | |||
5288 | static 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 | |||
5321 | static 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 | |||
4878 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { | 5346 | static 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 | ||
5434 | static 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 */ | ||
5454 | static 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 | |||
5467 | static 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 | */ |
5060 | static struct hda_board_config alc883_cfg_tbl[] = { | 5567 | static 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) */ | 5581 | static 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 | ||
5931 | static 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 | |||
5358 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | 5949 | static 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 | ||
5971 | static 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 | |||
5989 | static 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 | ||
6077 | static 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 | |||
6083 | static 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 */ | ||
6094 | static 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 */ | ||
6126 | static 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 | |||
6134 | static 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 */ | ||
6166 | static 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 | ||
6524 | static 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 | */ |
5869 | static struct hda_board_config alc262_cfg_tbl[] = { | 6675 | static 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 */ | 6686 | static 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 */ | ||
6944 | static 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 */ | ||
6958 | static 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 | |||
6976 | static 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 | ||
6083 | static struct snd_kcontrol_new alc861_base_mixer[] = { | 6983 | static 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 | |||
7059 | static 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 | |||
6158 | static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { | 7080 | static 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 | ||
7122 | static 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 */ | ||
7165 | static 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 | ||
7361 | static 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 */ | ||
7423 | static 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 | ||
7481 | static 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 */ | ||
7488 | static 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 | |||
7504 | static 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 | */ |
6713 | static struct hda_board_config alc861_cfg_tbl[] = { | 7787 | static 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 }, | 7799 | static 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 | ||
6796 | static int patch_alc861(struct hda_codec *codec) | 7920 | static 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 | |||
7983 | static 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 | */ | ||
7995 | static hda_nid_t alc660vd_dac_nids[3] = { | ||
7996 | /* front, rear, clfe, rear_surr */ | ||
7997 | 0x02, 0x04, 0x03 | ||
7998 | }; | ||
7999 | |||
8000 | static 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 */ | ||
8007 | static 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 | |||
8020 | static 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 | */ | ||
8049 | static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { | ||
8050 | { 2, NULL } | ||
8051 | }; | ||
8052 | |||
8053 | /* | ||
8054 | * 6ch mode | ||
8055 | */ | ||
8056 | static 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 | */ | ||
8067 | static 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 | |||
8075 | static struct hda_channel_mode alc861vd_6stack_modes[2] = { | ||
8076 | { 6, alc861vd_6stack_ch6_init }, | ||
8077 | { 8, alc861vd_6stack_ch8_init }, | ||
8078 | }; | ||
8079 | |||
8080 | static 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 | |||
8091 | static 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 | */ | ||
8114 | static 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 | |||
8153 | static 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 | */ | ||
8182 | static 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 | */ | ||
8232 | static 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 | */ | ||
8263 | static 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 | */ | ||
8313 | static 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 | |||
8321 | static 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 | |||
8330 | static 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 | */ | ||
8380 | static 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 | |||
8390 | static 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 | |||
8404 | static 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 | |||
8417 | static 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 */ | ||
8443 | static 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 */ | ||
8502 | static 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 */ | ||
8552 | static 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 */ | ||
8593 | static 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 | |||
8600 | static 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 | */ |
6851 | struct hda_codec_preset snd_hda_preset_realtek[] = { | 8663 | struct 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 | 40 | enum { |
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 | 45 | enum { |
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 | |||
50 | enum { | ||
51 | STAC_925x_REF, | ||
52 | STAC_M2_2, | ||
53 | STAC_MA6, | ||
54 | STAC_925x_MODELS | ||
55 | }; | ||
56 | |||
57 | enum { | ||
58 | STAC_D945_REF, | ||
59 | STAC_D945GTP3, | ||
60 | STAC_D945GTP5, | ||
61 | STAC_MACMINI, | ||
62 | STAC_922X_MODELS | ||
63 | }; | ||
64 | |||
65 | enum { | ||
66 | STAC_D965_REF, | ||
67 | STAC_D965_3ST, | ||
68 | STAC_D965_5ST, | ||
69 | STAC_927X_MODELS | ||
70 | }; | ||
48 | 71 | ||
49 | struct sigmatel_spec { | 72 | struct 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 | ||
139 | static hda_nid_t stac925x_adc_nids[1] = { | ||
140 | 0x03, | ||
141 | }; | ||
142 | |||
143 | static hda_nid_t stac925x_mux_nids[1] = { | ||
144 | 0x0f, | ||
145 | }; | ||
146 | |||
147 | static hda_nid_t stac925x_dac_nids[1] = { | ||
148 | 0x02, | ||
149 | }; | ||
150 | |||
110 | static hda_nid_t stac922x_adc_nids[2] = { | 151 | static 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 | ||
175 | static hda_nid_t stac9205_dmic_nids[3] = { | ||
176 | 0x17, 0x18, 0 | ||
177 | }; | ||
178 | |||
134 | static hda_nid_t stac9200_pin_nids[8] = { | 179 | static 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 | ||
184 | static hda_nid_t stac925x_pin_nids[8] = { | ||
185 | 0x07, 0x08, 0x0a, 0x0b, | ||
186 | 0x0c, 0x0d, 0x10, 0x11, | ||
187 | }; | ||
188 | |||
139 | static hda_nid_t stac922x_pin_nids[10] = { | 189 | static 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 | ||
207 | static 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 | |||
215 | static 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 | |||
225 | static 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 | |||
157 | static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 235 | static 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 | ||
268 | static struct hda_verb stac925x_core_init[] = { | ||
269 | /* set dac0mux for dac converter */ | ||
270 | { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
271 | {} | ||
272 | }; | ||
273 | |||
190 | static struct hda_verb stac922x_core_init[] = { | 274 | static 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 | ||
319 | static 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 */ |
236 | static struct snd_kcontrol_new stac922x_mixer[] = { | 337 | static 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 | ||
266 | static snd_kcontrol_new_t stac927x_mixer[] = { | 367 | static 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 | ||
281 | static snd_kcontrol_new_t stac9205_mixer[] = { | 382 | static 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 | ||
330 | static unsigned int *stac9200_brd_tbl[] = { | 439 | static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { |
331 | ref9200_pin_configs, | 440 | [STAC_REF] = ref9200_pin_configs, |
441 | }; | ||
442 | |||
443 | static const char *stac9200_models[STAC_9200_MODELS] = { | ||
444 | [STAC_REF] = "ref", | ||
332 | }; | 445 | }; |
333 | 446 | ||
334 | static struct hda_board_config stac9200_cfg_tbl[] = { | 447 | static 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 | |||
463 | static unsigned int ref925x_pin_configs[8] = { | ||
464 | 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, | ||
465 | 0x90a70320, 0x02214210, 0x400003f1, 0x9033032e, | ||
466 | }; | ||
467 | |||
468 | static unsigned int stac925x_MA6_pin_configs[8] = { | ||
469 | 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, | ||
470 | 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e, | ||
471 | }; | ||
472 | |||
473 | static unsigned int stac925xM2_2_pin_configs[8] = { | ||
474 | 0x40c003f3, 0x424503f2, 0x041800f4, 0x02a19020, | ||
475 | 0x50a103F0, 0x90100210, 0x400003f1, 0x9033032e, | ||
476 | }; | ||
477 | |||
478 | static 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 | |||
484 | static const char *stac925x_models[STAC_925x_MODELS] = { | ||
485 | [STAC_REF] = "ref", | ||
486 | [STAC_M2_2] = "m2-2", | ||
487 | [STAC_MA6] = "m6", | ||
488 | }; | ||
489 | |||
490 | static 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 | ||
367 | static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | 518 | static 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 | ||
374 | static struct hda_board_config stac922x_cfg_tbl[] = { | 525 | static 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 */ | 532 | static 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 | ||
486 | static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { | 617 | static 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 | ||
492 | static struct hda_board_config stac927x_cfg_tbl[] = { | 623 | static 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 */ | 629 | static 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 | ||
586 | static unsigned int ref9205_pin_configs[12] = { | 666 | static 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 | ||
592 | static unsigned int *stac9205_brd_tbl[] = { | 672 | static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { |
593 | ref9205_pin_configs, | 673 | ref9205_pin_configs, |
594 | }; | 674 | }; |
595 | 675 | ||
596 | static struct hda_board_config stac9205_cfg_tbl[] = { | 676 | static 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 */ | 680 | static 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 */ | ||
1241 | static 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 */ | ||
1247 | static 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; | ||
1282 | found: | ||
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 */ |
1158 | static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) | 1293 | static 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 | ||
1788 | static 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 | |||
1636 | static int patch_stac922x(struct hda_codec *codec) | 1838 | static 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 | }; | |
1969 | static struct hda_board_config stac9872_cfg_tbl[] = { | 2196 | |
1970 | { .modelname = "vaio", .config = CXD9872RD_VAIO }, | 2197 | static 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 }, | 2202 | static 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 | |||
65 | enum { | ||
66 | VIA_CTL_WIDGET_VOL, | ||
67 | VIA_CTL_WIDGET_MUTE, | ||
68 | }; | ||
69 | |||
70 | enum { | ||
71 | AUTO_SEQ_FRONT, | ||
72 | AUTO_SEQ_SURROUND, | ||
73 | AUTO_SEQ_CENLFE, | ||
74 | AUTO_SEQ_SIDE | ||
75 | }; | ||
76 | |||
77 | static 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 | |||
83 | struct 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 | |||
121 | static hda_nid_t vt1708_adc_nids[2] = { | ||
122 | /* ADC1-2 */ | ||
123 | 0x15, 0x27 | ||
124 | }; | ||
125 | |||
126 | static hda_nid_t vt1709_adc_nids[3] = { | ||
127 | /* ADC1-2 */ | ||
128 | 0x14, 0x15, 0x16 | ||
129 | }; | ||
130 | |||
131 | /* add dynamic controls */ | ||
132 | static 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 */ | ||
165 | static 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 | |||
184 | static 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 | |||
196 | static 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 | |||
208 | static 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 | |||
218 | static 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 | */ | ||
236 | static 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 | |||
244 | static 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 | |||
255 | static 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 */ | ||
278 | static 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 | */ | ||
301 | static 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 | |||
335 | static 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 | |||
343 | static 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 | |||
354 | static 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 | */ | ||
365 | static 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 | |||
373 | static 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 | */ | ||
384 | static 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 | |||
397 | static 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 | |||
407 | static 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 | |||
419 | static 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 | |||
430 | static 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 | |||
441 | static struct hda_pcm_stream vt1708_pcm_digital_capture = { | ||
442 | .substreams = 1, | ||
443 | .channels_min = 2, | ||
444 | .channels_max = 2, | ||
445 | }; | ||
446 | |||
447 | static 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 | |||
473 | static 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 | |||
511 | static 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 | |||
528 | static 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 | */ | ||
539 | static 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 | */ | ||
558 | static 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 */ | ||
569 | static 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 */ | ||
604 | static 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 | |||
684 | static 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 */ | ||
708 | static 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 | |||
754 | static 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 */ | ||
796 | static 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 | |||
805 | static 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 */ | ||
852 | static 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 | */ | ||
878 | static 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 | |||
920 | static 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 | |||
932 | static 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 | |||
944 | static 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 | |||
955 | static 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 | |||
966 | static struct hda_pcm_stream vt1709_pcm_digital_capture = { | ||
967 | .substreams = 1, | ||
968 | .channels_min = 2, | ||
969 | .channels_max = 2, | ||
970 | }; | ||
971 | |||
972 | static 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 */ | ||
1043 | static 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 | |||
1131 | static 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 */ | ||
1158 | static 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 | |||
1204 | static 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 | |||
1243 | static 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 | */ | ||
1291 | static 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 | |||
1333 | static 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 | */ | ||
1382 | struct 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 | ||
6 | snd-ice17xx-ak4xxx-objs := ak4xxx.o | 6 | snd-ice17xx-ak4xxx-objs := ak4xxx.o |
7 | snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o | 7 | snd-ice1712-objs := ice1712.o delta.o hoontech.o ews.o |
8 | snd-ice1724-objs := ice1724.o amp.o revo.o aureon.o vt1720_mobo.o pontis.o prodigy192.o juli.o phase.o | 8 | snd-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 |
11 | obj-$(CONFIG_SND_ICE1712) += snd-ice1712.o snd-ice17xx-ak4xxx.o | 11 | obj-$(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 | ||
43 | static int __devinit snd_vt1724_amp_init(struct snd_ice1712 *ice) | 43 | static 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 */ |
78 | struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = { | 78 | const 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 | ||
45 | extern struct snd_ice1712_card_info snd_vt1724_amp_cards[]; | 45 | extern 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 | |||
294 | static int aureon_ac97_init (struct snd_ice1712 *ice) | 294 | static 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) | |||
601 | static void wm_put_nocache(struct snd_ice1712 *ice, int reg, unsigned short val) | 602 | static 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 | ||
664 | static DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); | 667 | static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); |
665 | static DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); | 668 | static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); |
666 | static DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0); | 669 | static const DECLARE_TLV_DB_SCALE(db_scale_wm_adc, -1200, 100, 0); |
667 | static DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0); | 670 | static const DECLARE_TLV_DB_SCALE(db_scale_ac97_master, -4650, 150, 0); |
668 | static DECLARE_TLV_DB_SCALE(db_scale_ac97_gain, -3450, 150, 0); | 671 | static 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 | */ |
674 | static unsigned char wm_vol[256] = { | 677 | static 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 | */ |
1065 | static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1068 | static 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 | |||
1137 | static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1140 | static 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 | */ |
1364 | static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo) | 1369 | static 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 | ||
1409 | static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { | 1414 | static 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 | ||
1524 | static struct snd_kcontrol_new wm_controls[] __devinitdata = { | 1529 | static 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 | ||
1590 | static struct snd_kcontrol_new ac97_controls[] __devinitdata = { | 1595 | static 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 | ||
1695 | static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { | 1700 | static 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 | 1832 | static const struct snd_kcontrol_new cs8415_controls[] __devinitdata = { | |
1828 | static 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 | |||
1874 | static int __devinit aureon_add_controls(struct snd_ice1712 *ice) | 1877 | static 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 | */ |
1937 | static int __devinit aureon_init(struct snd_ice1712 *ice) | 1942 | static 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 | ||
2103 | static unsigned char aureon51_eeprom[] __devinitdata = { | 2110 | static 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 | ||
2119 | static unsigned char aureon71_eeprom[] __devinitdata = { | 2126 | static 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 | |
2135 | static unsigned char prodigy71_eeprom[] __devinitdata = { | 2142 | |
2136 | 0x0b, /* SYSCONF: clock 512, spdif-in/ADC, 4DACs */ | 2143 | static 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 | |
2151 | static 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 */ |
2169 | struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { | 2161 | const 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 | ||
39 | extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; | 41 | extern 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 | ||
419 | static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = | 419 | static 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 | ||
432 | static struct snd_akm4xxx akm_audiophile __devinitdata = { | 432 | static 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 | ||
441 | static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { | 441 | static 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 | ||
453 | static struct snd_akm4xxx akm_delta410 __devinitdata = { | 453 | static 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 | ||
462 | static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { | 462 | static 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 | ||
474 | static struct snd_akm4xxx akm_delta1010lt __devinitdata = { | 474 | static 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 | ||
484 | static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { | 484 | static 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 | ||
496 | static struct snd_akm4xxx akm_delta44 __devinitdata = { | 496 | static 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 | ||
506 | static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { | 506 | static 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 | ||
518 | static struct snd_akm4xxx akm_vx442 __devinitdata = { | 518 | static 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 | ||
528 | static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = { | 528 | static 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 | ||
653 | static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = | 653 | static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = |
654 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); | 654 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); |
655 | static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = | 655 | static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = |
656 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0); | 656 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0); |
657 | static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = | 657 | static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = |
658 | ICE1712_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); | 658 | ICE1712_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); |
659 | static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = | 659 | static const struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = |
660 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); | 660 | ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); |
661 | static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata = | 661 | static const struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata = |
662 | ICE1712_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); | 662 | ICE1712_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 */ |
738 | struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = { | 738 | const 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 */ |
49 | extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; | 49 | extern 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 | */ |
335 | static struct snd_akm4xxx akm_ews88mt __devinitdata = { | 335 | static 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 | ||
345 | static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { | 345 | static 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 | ||
357 | static struct snd_akm4xxx akm_ewx2496 __devinitdata = { | 357 | static 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 | ||
366 | static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { | 366 | static 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 | ||
378 | static struct snd_akm4xxx akm_6fire __devinitdata = { | 378 | static 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 | ||
387 | static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = { | 387 | static 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 | ||
581 | static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = { | 581 | static 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 | ||
681 | static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = { | 681 | static 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 | ||
690 | static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = { | 690 | static 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 | ||
772 | static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { | 772 | static 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 | ||
912 | static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = { | 912 | static 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 */ |
992 | struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = { | 992 | const 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 */ |
43 | extern struct snd_ice1712_card_info snd_ice1712_ews_cards[]; | 43 | extern 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) | |||
239 | static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice) | 239 | static 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 */ |
301 | struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = { | 301 | const 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 | ||
38 | extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[]; | 38 | extern 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); | |||
107 | MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); | 107 | MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE."); |
108 | 108 | ||
109 | 109 | ||
110 | static struct pci_device_id snd_ice1712_ids[] = { | 110 | static 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 | ||
290 | static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = { | 290 | static 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 | ||
722 | static struct snd_pcm_hardware snd_ice1712_playback = | 722 | static 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 | ||
742 | static struct snd_pcm_hardware snd_ice1712_playback_ds = | 742 | static 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 | ||
762 | static struct snd_pcm_hardware snd_ice1712_capture = | 762 | static 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 | ||
1136 | static struct snd_pcm_hardware snd_ice1712_playback_pro = | 1136 | static 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 | ||
1156 | static struct snd_pcm_hardware snd_ice1712_capture_pro = | 1156 | static 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 | ||
1381 | static DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0); | 1381 | static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0); |
1382 | 1382 | ||
1383 | static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = { | 1383 | static 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 | ||
1407 | static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = { | 1407 | static 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 | ||
1416 | static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { | 1416 | static 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 | ||
1426 | static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = { | 1426 | static 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 | ||
1438 | static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { | 1438 | static 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 | ||
1630 | static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = { | 1630 | static 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 | ||
1666 | static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = | 1666 | static 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 | ||
1717 | static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = | 1717 | static 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 | ||
1726 | static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = | 1726 | static 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 | ||
1753 | static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = | 1753 | static 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, | |||
1811 | static int snd_ice1712_pro_internal_clock_info(struct snd_kcontrol *kcontrol, | 1811 | static 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 | ||
1894 | static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = { | 1894 | static 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 = { | |||
1902 | static int snd_ice1712_pro_internal_clock_default_info(struct snd_kcontrol *kcontrol, | 1902 | static 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 | |||
1948 | static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcontrol, | 1948 | static 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 | ||
1965 | static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = { | 1965 | static 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 | ||
2004 | static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { | 2004 | static 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 | ||
2043 | static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = { | 2043 | static 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 = { | |||
2054 | static int snd_ice1712_pro_route_info(struct snd_kcontrol *kcontrol, | 2054 | static 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 | ||
2210 | static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = { | 2210 | static 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 | ||
2218 | static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { | 2218 | static 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 | ||
2260 | static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = { | 2260 | static 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 | ||
2293 | static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { | 2293 | static 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 | */ |
2308 | static struct snd_ice1712_card_info *card_tables[] __devinitdata = { | 2308 | static 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 | ||
2661 | static struct snd_ice1712_card_info no_matched __devinitdata; | 2661 | static const struct snd_ice1712_card_info no_matched __devinitdata; |
2662 | 2662 | ||
2663 | static int __devinit snd_ice1712_probe(struct pci_dev *pci, | 2663 | static 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 | ||
471 | static 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 | |||
465 | int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice); | 479 | int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice); |
466 | 480 | ||
467 | int snd_ice1712_akm4xxx_init(struct snd_akm4xxx *ak, const struct snd_akm4xxx *template, | 481 | int 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 | ||
55 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); | 55 | MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); |
56 | MODULE_DESCRIPTION("VIA ICEnsemble ICE1724/1720 (Envy24HT/PT)"); | 56 | MODULE_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 */ |
89 | static struct pci_device_id snd_vt1724_ids[] = { | 90 | static 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 | |||
605 | static int snd_vt1724_pcm_prepare(struct snd_pcm_substream *substream) | 606 | static 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) | |||
620 | static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substream) | 621 | static 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 | ||
649 | static struct vt1724_pcm_reg vt1724_playback_pro_reg = { | 650 | static 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 | ||
656 | static struct vt1724_pcm_reg vt1724_capture_pro_reg = { | 657 | static 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 | ||
663 | static struct snd_pcm_hardware snd_vt1724_playback_pro = | 664 | static 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 | ||
682 | static struct snd_pcm_hardware snd_vt1724_spdif = | 683 | static 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 | ||
704 | static struct snd_pcm_hardware snd_vt1724_2ch_stereo = | 705 | static 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 | ||
891 | static struct vt1724_pcm_reg vt1724_playback_spdif_reg = { | 892 | static 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 | ||
898 | static struct vt1724_pcm_reg vt1724_capture_spdif_reg = { | 899 | static 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 | ||
1093 | static struct vt1724_pcm_reg vt1724_playback_dma_regs[3] = { | 1094 | static 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 | ||
1320 | static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = { | 1321 | static 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 | ||
1433 | static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = | 1434 | static 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 | ||
1465 | static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = | 1466 | static 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 | ||
1474 | static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = | 1475 | static 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 | ||
1519 | static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = | 1520 | static 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, | |||
1584 | static int snd_vt1724_pro_internal_clock_info(struct snd_kcontrol *kcontrol, | 1585 | static 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 | ||
1697 | static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { | 1698 | static 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 | ||
1736 | static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { | 1737 | static 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 | ||
1775 | static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = { | 1776 | static 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 | ||
1894 | static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = { | 1895 | static 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 | ||
1902 | static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { | 1903 | static 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 | ||
1938 | static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { | 1939 | static 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 | ||
1950 | static struct snd_ice1712_card_info no_matched __devinitdata; | 1951 | static const struct snd_ice1712_card_info no_matched __devinitdata; |
1951 | 1952 | ||
1952 | static struct snd_ice1712_card_info *card_tables[] __devinitdata = { | 1953 | static 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 | ||
128 | static struct snd_akm4xxx akm_juli_dac __devinitdata = { | 128 | static 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 | */ |
147 | static int __devinit juli_init(struct snd_ice1712 *ice) | 147 | static 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 | ||
209 | static unsigned char juli_eeprom[] __devinitdata = { | 209 | static 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 */ |
226 | struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = { | 226 | const 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 | ||
8 | extern struct snd_ice1712_card_info snd_vt1724_juli_cards[]; | 8 | extern 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 | */ |
74 | static unsigned char wm_vol[256] = { | 74 | static 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 | ||
92 | static struct snd_akm4xxx akm_phase22 __devinitdata = { | 92 | static 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 | ||
98 | static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { | 98 | static 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 | ||
155 | static unsigned char phase22_eeprom[] __devinitdata = { | 155 | static 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 | ||
171 | static unsigned char phase28_eeprom[] __devinitdata = { | 171 | static 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 | ||
344 | static int __devinit phase28_init(struct snd_ice1712 *ice) | 344 | static 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 | ||
700 | static DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); | 700 | static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); |
701 | static DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); | 701 | static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); |
702 | 702 | ||
703 | static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { | 703 | static 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 | ||
818 | static struct snd_kcontrol_new wm_controls[] __devinitdata = { | 818 | static 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 | ||
873 | struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { | 873 | const 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 */ |
34 | extern struct snd_ice1712_card_info snd_vt1724_phase_cards[]; | 34 | extern 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 | */ |
435 | static int cs_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 435 | static 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 | ||
568 | static DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1); | 568 | static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1); |
569 | 569 | ||
570 | /* | 570 | /* |
571 | * mixers | 571 | * mixers |
572 | */ | 572 | */ |
573 | 573 | ||
574 | static struct snd_kcontrol_new pontis_controls[] __devinitdata = { | 574 | static 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 | */ |
742 | static int __devinit pontis_init(struct snd_ice1712 *ice) | 742 | static 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 | ||
829 | static unsigned char pontis_eeprom[] __devinitdata = { | 829 | static 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 */ |
846 | struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = { | 846 | const 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 | ||
31 | extern struct snd_ice1712_card_info snd_vt1720_pontis_cards[]; | 31 | extern 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 | ||
360 | static DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); | 360 | static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); |
361 | static DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); | 361 | static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); |
362 | 362 | ||
363 | /* | 363 | /* |
364 | * mixers | 364 | * mixers |
365 | */ | 365 | */ |
366 | 366 | ||
367 | static struct snd_kcontrol_new stac_controls[] __devinitdata = { | 367 | static 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 | */ |
476 | static int __devinit prodigy192_init(struct snd_ice1712 *ice) | 476 | static 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 | ||
509 | static unsigned char prodigy71_eeprom[] __devinitdata = { | 509 | static 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 */ |
527 | struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { | 527 | const 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 | ||
9 | extern struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[]; | 9 | extern 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 | |||
90 | static 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 | |||
96 | static 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 | |||
102 | static 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 | |||
119 | static 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 | |||
134 | static 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 | |||
145 | static 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 | |||
153 | static 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 | ||
92 | static struct snd_akm4xxx_dac_channel revo71_front[] = { | 188 | static 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 | ||
96 | static struct snd_akm4xxx_dac_channel revo71_surround[] = { | 192 | static 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 | ||
103 | static struct snd_akm4xxx_dac_channel revo51_dac[] = { | 199 | static 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 | ||
110 | static struct snd_akm4xxx_adc_channel revo51_adc[] = { | 206 | static const char *revo51_adc_input_names[] = { |
207 | "Mic", | ||
208 | "Line", | ||
209 | "CD", | ||
210 | NULL | ||
211 | }; | ||
212 | |||
213 | static 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 | ||
118 | static struct snd_akm4xxx akm_revo_front __devinitdata = { | 222 | static 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 | ||
127 | static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { | 231 | static 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 | ||
139 | static struct snd_akm4xxx akm_revo_surround __devinitdata = { | 243 | static 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 | ||
149 | static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { | 253 | static 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 | ||
161 | static struct snd_akm4xxx akm_revo51 __devinitdata = { | 265 | static 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 | ||
170 | static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { | 274 | static 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 | ||
182 | static struct snd_akm4xxx akm_revo51_adc __devinitdata = { | 286 | static 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 | ||
188 | static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { | 292 | static 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 | |||
304 | static struct snd_pt2258 ptc_revo51_volume; | ||
305 | |||
306 | /* AK4358 for AP192 DAC, AK5385A for ADC */ | ||
307 | static 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 | |||
323 | static const struct snd_akm4xxx_dac_channel ap192_dac[] = { | ||
324 | AK_DAC("PCM Playback Volume", 2) | ||
325 | }; | ||
326 | |||
327 | static 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 | |||
336 | static 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 | |||
364 | static 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 | |||
386 | static 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 | |||
408 | static 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 | |||
422 | static 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 | |||
431 | static 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 | |||
444 | static 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 | |||
457 | static 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 | |||
200 | static int __devinit revo_init(struct snd_ice1712 *ice) | 481 | static 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 */ |
268 | struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { | 585 | const 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 */ |
35 | extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; | 37 | extern 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 | ||
58 | static unsigned char k8x800_eeprom[] __devinitdata = { | 59 | static 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 | ||
74 | static unsigned char sn25p_eeprom[] __devinitdata = { | 75 | static 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 */ |
92 | struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { | 93 | const 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 | ||
39 | extern struct snd_ice1712_card_info snd_vt1720_mobo_cards[]; | 39 | extern 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 | */ | ||
45 | static 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 | |||
51 | static 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 | */ | ||
59 | static 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 | |||
65 | static 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 | */ | ||
74 | static 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 | |||
83 | static 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 | |||
105 | static 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 | */ | ||
146 | static 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 | |||
156 | static 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 | |||
178 | static 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 | */ | ||
221 | static 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 | |||
231 | static 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 | |||
253 | static 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 | */ | ||
289 | static 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 | |||
299 | static 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 | |||
323 | static 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 | |||
360 | static 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 | |||
370 | static 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 | |||
386 | static 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 | */ | ||
412 | static 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*/ | ||
476 | static 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 | |||
490 | static 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 | |||
513 | static 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*/ | ||
531 | struct 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 | |||
17 | extern 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; | |||
71 | static int buggy_semaphore; | 71 | static int buggy_semaphore; |
72 | static int buggy_irq = -1; /* auto-check */ | 72 | static int buggy_irq = -1; /* auto-check */ |
73 | static int xbox; | 73 | static int xbox; |
74 | static int spdif_aclink = -1; | ||
74 | 75 | ||
75 | module_param(index, int, 0444); | 76 | module_param(index, int, 0444); |
76 | MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); | 77 | MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); |
@@ -86,6 +87,8 @@ module_param(buggy_irq, bool, 0444); | |||
86 | MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards."); | 87 | MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards."); |
87 | module_param(xbox, bool, 0444); | 88 | module_param(xbox, bool, 0444); |
88 | MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection."); | 89 | MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection."); |
90 | module_param(spdif_aclink, int, 0444); | ||
91 | MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); | ||
89 | 92 | ||
90 | /* just for backward compatibility */ | 93 | /* just for backward compatibility */ |
91 | static int enable; | 94 | static 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 | ||
449 | static u8 igetbyte(struct intel8x0 *chip, u32 offset) | 448 | static 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 | ||
457 | static u16 igetword(struct intel8x0 *chip, u32 offset) | 453 | static 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 | ||
465 | static u32 igetdword(struct intel8x0 *chip, u32 offset) | 458 | static 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 | ||
473 | static void iputbyte(struct intel8x0 *chip, u32 offset, u8 val) | 463 | static 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 | ||
481 | static void iputword(struct intel8x0 *chip, u32 offset, u16 val) | 468 | static 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 | ||
489 | static void iputdword(struct intel8x0 *chip, u32 offset, u32 val) | 473 | static 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 | ||
501 | static u16 iagetword(struct intel8x0 *chip, u32 offset) | 482 | static 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 | ||
509 | static void iaputword(struct intel8x0 *chip, u32 offset, u16 val) | 487 | static 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 | ||
2940 | static 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 */ | ||
2946 | static 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 | |||
2967 | static int __devinit snd_intel8x0_probe(struct pci_dev *pci, | 2963 | static 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 | ||
256 | static u8 igetbyte(struct intel8x0m *chip, u32 offset) | 252 | static 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 | ||
264 | static u16 igetword(struct intel8x0m *chip, u32 offset) | 257 | static 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 | ||
272 | static u32 igetdword(struct intel8x0m *chip, u32 offset) | 262 | static 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 | ||
280 | static void iputbyte(struct intel8x0m *chip, u32 offset, u8 val) | 267 | static 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 | ||
288 | static void iputword(struct intel8x0m *chip, u32 offset, u16 val) | 272 | static 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 | ||
296 | static void iputdword(struct intel8x0m *chip, u32 offset, u32 val) | 277 | static 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 | ||
308 | static u16 iagetword(struct intel8x0m *chip, u32 offset) | 286 | static 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 | ||
316 | static void iaputword(struct intel8x0m *chip, u32 offset, u16 val) | 291 | static 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" |
271 | static const struct firmware static_dsp_code = { | ||
272 | .data = (u8 *)dspCode, | ||
273 | .size = sizeof dspCode | ||
274 | }; | ||
275 | #endif | ||
267 | 276 | ||
268 | enum ClockSourceIndex { | 277 | enum 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 | ||
52 | MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Takashi Iwai <tiwai@suse.de>"); | 54 | MODULE_AUTHOR("Zach Brown <zab@zabbo.net>, Takashi Iwai <tiwai@suse.de>"); |
53 | MODULE_DESCRIPTION("ESS Maestro3 PCI"); | 55 | MODULE_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 */ | ||
772 | struct 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 | |||
780 | struct 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 | |||
786 | struct m3_list { | 773 | struct 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 | ||
892 | MODULE_DEVICE_TABLE(pci, snd_m3_ids); | 884 | MODULE_DEVICE_TABLE(pci, snd_m3_ids); |
893 | 885 | ||
894 | static const struct m3_quirk m3_quirk_list[] = { | 886 | static 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. */ | 894 | static struct snd_pci_quirk m3_irda_quirk_list[] __devinitdata = { |
952 | static 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 */ | ||
902 | static 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 */ | ||
980 | static 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 | ||
2236 | static const struct firmware assp_kernel = { | ||
2237 | .data = (u8 *)assp_kernel_image, | ||
2238 | .size = sizeof assp_kernel_image | ||
2239 | }; | ||
2240 | static 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 | ||
2248 | static inline void snd_m3_convert_from_le(const struct firmware *fw) { } | ||
2249 | #else | ||
2250 | static 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] = { | |||
2274 | static void snd_m3_assp_init(struct snd_m3 *chip) | 2271 | static 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 | ||
392 | static DECLARE_TLV_DB_SCALE(db_scale_analog, -9600, 50, 0); | 392 | static const DECLARE_TLV_DB_SCALE(db_scale_analog, -9600, 50, 0); |
393 | 393 | ||
394 | static struct snd_kcontrol_new mixart_control_analog_level = { | 394 | static 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 | ||
875 | static DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0); | 875 | static const DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0); |
876 | 876 | ||
877 | static struct snd_kcontrol_new snd_mixart_pcm_vol = | 877 | static 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 | ||
1631 | struct nm256_quirk { | ||
1632 | unsigned short vendor; | ||
1633 | unsigned short device; | ||
1634 | int type; | ||
1635 | }; | ||
1636 | |||
1637 | enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 }; | 1631 | enum { NM_BLACKLISTED, NM_RESET_WORKAROUND, NM_RESET_WORKAROUND_2 }; |
1638 | 1632 | ||
1639 | static struct nm256_quirk nm256_quirks[] __devinitdata = { | 1633 | static 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 | ||
47 | static DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 0); | 47 | static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -9600, 50, 0); |
48 | static DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -12800, 100, 0); | 48 | static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -12800, 100, 0); |
49 | 49 | ||
50 | static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip, int is_capture, int channel) | 50 | static 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 | ||
198 | static DECLARE_TLV_DB_SCALE(db_scale_digital, -10950, 50, 0); | 198 | static 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) | |||
938 | static void hdsp_reset_hw_pointer(struct hdsp *hdsp) | 942 | static 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 | ||
943 | static void hdsp_start_audio(struct hdsp *s) | 952 | static 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 | ||
994 | static 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 | |||
985 | static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally) | 1018 | static 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 | ||
78 | MODULE_AUTHOR | 80 | MODULE_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>"); | ||
81 | MODULE_DESCRIPTION("RME HDSPM"); | 84 | MODULE_DESCRIPTION("RME HDSPM"); |
82 | MODULE_LICENSE("GPL"); | 85 | MODULE_LICENSE("GPL"); |
83 | MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); | 86 | MODULE_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 | |||
321 | struct hdspm_midi { | 400 | struct 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); | |||
453 | static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf, | 534 | static 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 | ||
537 | static 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 */ |
545 | static inline int hdspm_external_sample_rate(struct hdspm * hdspm) | 635 | static 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) | |||
1486 | static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol, | 1660 | static 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 | ||
1543 | static int hdspm_autosync_ref(struct hdspm * hdspm) | 1735 | static 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 | ||
1566 | static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol, | 1764 | static 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 | |||
2069 | static int hdspm_emphasis(struct hdspm * hdspm) | ||
2070 | { | ||
2071 | return (hdspm->control_register & HDSPM_Emphasis) ? 1 : 0; | ||
2072 | } | ||
2073 | |||
2074 | static 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 | |||
2085 | static 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 | |||
2095 | static 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 | |||
2106 | static 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 | |||
2132 | static int hdspm_dolby(struct hdspm * hdspm) | ||
2133 | { | ||
2134 | return (hdspm->control_register & HDSPM_Dolby) ? 1 : 0; | ||
2135 | } | ||
2136 | |||
2137 | static 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 | |||
2148 | static 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 | |||
2158 | static 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 | |||
2169 | static 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 | |||
2195 | static int hdspm_professional(struct hdspm * hdspm) | ||
2196 | { | ||
2197 | return (hdspm->control_register & HDSPM_Professional) ? 1 : 0; | ||
2198 | } | ||
2199 | |||
2200 | static 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 | |||
2211 | static 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 | |||
2221 | static 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 | |||
2232 | static 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 | |||
2329 | static int hdspm_ds_wire(struct hdspm * hdspm) | ||
2330 | { | ||
2331 | return (hdspm->control_register & HDSPM_DS_DoubleWire) ? 1 : 0; | ||
2332 | } | ||
2333 | |||
2334 | static 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 | |||
2345 | static 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 | |||
2363 | static 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 | |||
2374 | static 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 | |||
2400 | static 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 | |||
2409 | static 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 | |||
2427 | static 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 | |||
2445 | static 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 | |||
2456 | static 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 | ||
2136 | static int hdspm_wc_sync_check(struct hdspm * hdspm) | 2698 | static 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 | ||
2148 | static int snd_hdspm_get_wc_sync_check(struct snd_kcontrol *kcontrol, | 2720 | static 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 | |||
2772 | static 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 | |||
2783 | static 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 | ||
2193 | static struct snd_kcontrol_new snd_hdspm_controls[] = { | 2799 | static 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 | ||
2820 | static 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 | |||
2214 | static struct snd_kcontrol_new snd_hdspm_playback_mixer = HDSPM_PLAYBACK_MIXER; | 2843 | static 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 | 2908 | Note: 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 | 2909 | they are accesible via special IOCTL on hwdep |
2261 | and the mixer 2dimensional mixer control */ | 2910 | and 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 | ||
2291 | static void | 2940 | static void |
2292 | snd_hdspm_proc_read(struct snd_info_entry * entry, struct snd_info_buffer *buffer) | 2941 | snd_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 | ||
3136 | static void | ||
3137 | snd_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 | ||
3308 | static void | ||
3309 | snd_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 | |||
2487 | static void __devinit snd_hdspm_proc_init(struct hdspm * hdspm) | 3328 | static 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 | ||
2630 | static DECLARE_TLV_DB_SCALE(db_scale_gvol, -6375, 25, 0); | 2630 | static const DECLARE_TLV_DB_SCALE(db_scale_gvol, -6375, 25, 0); |
2631 | 2631 | ||
2632 | static int snd_trident_vol_control_put(struct snd_kcontrol *kcontrol, | 2632 | static 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 | ||
2847 | static DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1); | 2847 | static const DECLARE_TLV_DB_SCALE(db_scale_crvol, -3175, 25, 1); |
2848 | 2848 | ||
2849 | static struct snd_kcontrol_new snd_trident_pcm_rvol_control __devinitdata = | 2849 | static 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 | ||
1702 | static DECLARE_TLV_DB_SCALE(db_scale_dxs, -9450, 150, 1); | 1702 | static const DECLARE_TLV_DB_SCALE(db_scale_dxs, -9450, 150, 1); |
1703 | 1703 | ||
1704 | static struct snd_kcontrol_new snd_via8233_pcmdxs_volume_control __devinitdata = { | 1704 | static 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 | */ |
2360 | struct dxs_whitelist { | 2360 | |
2361 | unsigned short subvendor; | 2361 | static 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 | ||
2367 | static int __devinit check_dxs_list(struct pci_dev *pci, int revision) | 2404 | static 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 | ||
76 | static DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0); | 76 | static const DECLARE_TLV_DB_SCALE(db_scale_old_vol, -11350, 50, 0); |
77 | static DECLARE_TLV_DB_SCALE(db_scale_akm, -7350, 50, 0); | 77 | static const DECLARE_TLV_DB_SCALE(db_scale_akm, -7350, 50, 0); |
78 | 78 | ||
79 | static struct snd_vx_hardware vx222_old_hw = { | 79 | static 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 | ||
849 | static DECLARE_TLV_DB_SCALE(db_scale_mic, -6450, 50, 0); | 849 | static 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 | ||
4 | static unsigned long DspInst[YDSXG_DSPLENGTH / 4] = { | 4 | static 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 | ||
15 | static unsigned long CntrlInst[YDSXG_CTRLLENGTH / 4] = { | 15 | static 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 |
794 | static unsigned long CntrlInst1E[YDSXG_CTRLLENGTH / 4] = { | 794 | static 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 | ||
174 | static 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 | ||
1483 | static DECLARE_TLV_DB_LINEAR(db_scale_native, TLV_DB_GAIN_MUTE, 0); | 1507 | static 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 | ||
2007 | static struct firmware snd_ymfpci_dsp_microcode = { | ||
2008 | .size = YDSXG_DSPLENGTH, | ||
2009 | .data = (u8 *)DspInst, | ||
2010 | }; | ||
2011 | static struct firmware snd_ymfpci_controller_microcode = { | ||
2012 | .size = YDSXG_CTRLLENGTH, | ||
2013 | .data = (u8 *)CntrlInst, | ||
2014 | }; | ||
2015 | static struct firmware snd_ymfpci_controller_1e_microcode = { | ||
2016 | .size = YDSXG_CTRLLENGTH, | ||
2017 | .data = (u8 *)CntrlInst1E, | ||
2018 | }; | ||
2019 | #endif | ||
2020 | |||
2021 | #ifdef __LITTLE_ENDIAN | ||
2022 | static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { } | ||
2023 | #else | ||
2024 | static 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 | |||
2034 | static 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 | |||
1976 | static void snd_ymfpci_download_image(struct snd_ymfpci *chip) | 2084 | static 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.. */ |