aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/ac97_bus.c4
-rw-r--r--sound/aoa/codecs/onyx.c1
-rw-r--r--sound/core/control.c28
-rw-r--r--sound/core/init.c2
-rw-r--r--sound/core/oss/pcm_oss.c4
-rw-r--r--sound/core/pcm_lib.c32
-rw-r--r--sound/core/pcm_native.c5
-rw-r--r--sound/core/seq/seq.c4
-rw-r--r--sound/core/sound.c18
-rw-r--r--sound/core/timer.c7
-rw-r--r--sound/drivers/ml403-ac97cr.c4
-rw-r--r--sound/isa/opl3sa2.c2
-rw-r--r--sound/oss/soundcard.c4
-rw-r--r--sound/pci/Kconfig23
-rw-r--r--sound/pci/ac97/ac97_codec.c2
-rw-r--r--sound/pci/ac97/ac97_patch.c62
-rw-r--r--sound/pci/au88x0/au88x0_pcm.c24
-rw-r--r--sound/pci/azt3328.c406
-rw-r--r--sound/pci/bt87x.c10
-rw-r--r--sound/pci/ca0106/ca0106.h2
-rw-r--r--sound/pci/ca0106/ca0106_main.c2
-rw-r--r--sound/pci/cmipci.c25
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pm.c7
-rw-r--r--sound/pci/emu10k1/emu10k1x.c2
-rw-r--r--sound/pci/emu10k1/p16v.h2
-rw-r--r--sound/pci/es1968.c2
-rw-r--r--sound/pci/hda/hda_codec.c70
-rw-r--r--sound/pci/hda/hda_eld.c24
-rw-r--r--sound/pci/hda/hda_generic.c7
-rw-r--r--sound/pci/hda/hda_intel.c13
-rw-r--r--sound/pci/hda/hda_local.h6
-rw-r--r--sound/pci/hda/hda_proc.c2
-rw-r--r--sound/pci/hda/patch_analog.c280
-rw-r--r--sound/pci/hda/patch_cirrus.c4
-rw-r--r--sound/pci/hda/patch_cmedia.c2
-rw-r--r--sound/pci/hda/patch_conexant.c135
-rw-r--r--sound/pci/hda/patch_hdmi.c105
-rw-r--r--sound/pci/hda/patch_realtek.c1009
-rw-r--r--sound/pci/hda/patch_sigmatel.c111
-rw-r--r--sound/pci/hda/patch_via.c28
-rw-r--r--sound/pci/ice1712/delta.c56
-rw-r--r--sound/pci/ice1712/delta.h11
-rw-r--r--sound/pci/oxygen/Makefile4
-rw-r--r--sound/pci/oxygen/cs4245.h107
-rw-r--r--sound/pci/oxygen/hifier.c239
-rw-r--r--sound/pci/oxygen/oxygen.c356
-rw-r--r--sound/pci/oxygen/oxygen.h19
-rw-r--r--sound/pci/oxygen/oxygen_io.c4
-rw-r--r--sound/pci/oxygen/oxygen_lib.c65
-rw-r--r--sound/pci/oxygen/oxygen_mixer.c110
-rw-r--r--sound/pci/oxygen/oxygen_pcm.c55
-rw-r--r--sound/pci/oxygen/oxygen_regs.h16
-rw-r--r--sound/pci/oxygen/xonar.h2
-rw-r--r--sound/pci/oxygen/xonar_cs43xx.c84
-rw-r--r--sound/pci/oxygen/xonar_dg.c572
-rw-r--r--sound/pci/oxygen/xonar_dg.h8
-rw-r--r--sound/pci/oxygen/xonar_hdmi.c2
-rw-r--r--sound/pci/oxygen/xonar_lib.c6
-rw-r--r--sound/pci/oxygen/xonar_pcm179x.c473
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c317
-rw-r--r--sound/pci/rme9652/hdsp.c538
-rw-r--r--sound/pci/rme9652/hdspm.c6
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c12
-rw-r--r--sound/ppc/snd_ps3.c2
-rw-r--r--sound/soc/codecs/max98088.c2
-rw-r--r--sound/soc/pxa/pxa-ssp.c2
-rw-r--r--sound/soc/samsung/smdk_spdif.c6
-rw-r--r--sound/usb/format.c5
-rw-r--r--sound/usb/midi.c19
-rw-r--r--sound/usb/mixer.c11
-rw-r--r--sound/usb/quirks-table.h4
-rw-r--r--sound/usb/usx2y/us122l.c41
72 files changed, 3846 insertions, 1788 deletions
diff --git a/sound/ac97_bus.c b/sound/ac97_bus.c
index a351dd0a09c7..2b50cbe6aca9 100644
--- a/sound/ac97_bus.c
+++ b/sound/ac97_bus.c
@@ -19,8 +19,8 @@
19 19
20/* 20/*
21 * Let drivers decide whether they want to support given codec from their 21 * Let drivers decide whether they want to support given codec from their
22 * probe method. Drivers have direct access to the struct snd_ac97 structure and may 22 * probe method. Drivers have direct access to the struct snd_ac97
23 * decide based on the id field amongst other things. 23 * structure and may decide based on the id field amongst other things.
24 */ 24 */
25static int ac97_bus_match(struct device *dev, struct device_driver *drv) 25static int ac97_bus_match(struct device *dev, struct device_driver *drv)
26{ 26{
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 91852e49910e..3687a6cc9881 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -1114,7 +1114,6 @@ static int onyx_i2c_remove(struct i2c_client *client)
1114 of_node_put(onyx->codec.node); 1114 of_node_put(onyx->codec.node);
1115 if (onyx->codec_info) 1115 if (onyx->codec_info)
1116 kfree(onyx->codec_info); 1116 kfree(onyx->codec_info);
1117 i2c_set_clientdata(client, onyx);
1118 kfree(onyx); 1117 kfree(onyx);
1119 return 0; 1118 return 0;
1120} 1119}
diff --git a/sound/core/control.c b/sound/core/control.c
index 45a818002d99..9ce00ed20fba 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -1488,7 +1488,7 @@ int snd_ctl_create(struct snd_card *card)
1488} 1488}
1489 1489
1490/* 1490/*
1491 * Frequently used control callbacks 1491 * Frequently used control callbacks/helpers
1492 */ 1492 */
1493int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, 1493int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
1494 struct snd_ctl_elem_info *uinfo) 1494 struct snd_ctl_elem_info *uinfo)
@@ -1513,3 +1513,29 @@ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
1513} 1513}
1514 1514
1515EXPORT_SYMBOL(snd_ctl_boolean_stereo_info); 1515EXPORT_SYMBOL(snd_ctl_boolean_stereo_info);
1516
1517/**
1518 * snd_ctl_enum_info - fills the info structure for an enumerated control
1519 * @info: the structure to be filled
1520 * @channels: the number of the control's channels; often one
1521 * @items: the number of control values; also the size of @names
1522 * @names: an array containing the names of all control values
1523 *
1524 * Sets all required fields in @info to their appropriate values.
1525 * If the control's accessibility is not the default (readable and writable),
1526 * the caller has to fill @info->access.
1527 */
1528int snd_ctl_enum_info(struct snd_ctl_elem_info *info, unsigned int channels,
1529 unsigned int items, const char *const names[])
1530{
1531 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1532 info->count = channels;
1533 info->value.enumerated.items = items;
1534 if (info->value.enumerated.item >= items)
1535 info->value.enumerated.item = items - 1;
1536 strlcpy(info->value.enumerated.name,
1537 names[info->value.enumerated.item],
1538 sizeof(info->value.enumerated.name));
1539 return 0;
1540}
1541EXPORT_SYMBOL(snd_ctl_enum_info);
diff --git a/sound/core/init.c b/sound/core/init.c
index 57b792e2439a..3e65da21a08c 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -642,7 +642,7 @@ static struct device_attribute card_number_attrs =
642 * external accesses. Thus, you should call this function at the end 642 * external accesses. Thus, you should call this function at the end
643 * of the initialization of the card. 643 * of the initialization of the card.
644 * 644 *
645 * Returns zero otherwise a negative error code if the registrain failed. 645 * Returns zero otherwise a negative error code if the registration failed.
646 */ 646 */
647int snd_card_register(struct snd_card *card) 647int snd_card_register(struct snd_card *card)
648{ 648{
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index b753ec661fcf..a2e4eb324699 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -453,8 +453,10 @@ static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
453 } else { 453 } else {
454 *params = *save; 454 *params = *save;
455 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir); 455 max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
456 if (max < 0) 456 if (max < 0) {
457 kfree(save);
457 return max; 458 return max;
459 }
458 last = 1; 460 last = 1;
459 } 461 }
460 _end: 462 _end:
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index b75db8e9cc0f..a82e3756a72d 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -373,6 +373,27 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
373 (unsigned long)new_hw_ptr, 373 (unsigned long)new_hw_ptr,
374 (unsigned long)runtime->hw_ptr_base); 374 (unsigned long)runtime->hw_ptr_base);
375 } 375 }
376
377 if (runtime->no_period_wakeup) {
378 /*
379 * Without regular period interrupts, we have to check
380 * the elapsed time to detect xruns.
381 */
382 jdelta = jiffies - runtime->hw_ptr_jiffies;
383 if (jdelta < runtime->hw_ptr_buffer_jiffies / 2)
384 goto no_delta_check;
385 hdelta = jdelta - delta * HZ / runtime->rate;
386 while (hdelta > runtime->hw_ptr_buffer_jiffies / 2 + 1) {
387 delta += runtime->buffer_size;
388 hw_base += runtime->buffer_size;
389 if (hw_base >= runtime->boundary)
390 hw_base = 0;
391 new_hw_ptr = hw_base + pos;
392 hdelta -= runtime->hw_ptr_buffer_jiffies;
393 }
394 goto no_delta_check;
395 }
396
376 /* something must be really wrong */ 397 /* something must be really wrong */
377 if (delta >= runtime->buffer_size + runtime->period_size) { 398 if (delta >= runtime->buffer_size + runtime->period_size) {
378 hw_ptr_error(substream, 399 hw_ptr_error(substream,
@@ -442,6 +463,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
442 (long)old_hw_ptr); 463 (long)old_hw_ptr);
443 } 464 }
444 465
466 no_delta_check:
445 if (runtime->status->hw_ptr == new_hw_ptr) 467 if (runtime->status->hw_ptr == new_hw_ptr)
446 return 0; 468 return 0;
447 469
@@ -1070,8 +1092,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
1070 struct snd_pcm_hw_rule *new; 1092 struct snd_pcm_hw_rule *new;
1071 unsigned int new_rules = constrs->rules_all + 16; 1093 unsigned int new_rules = constrs->rules_all + 16;
1072 new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL); 1094 new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL);
1073 if (!new) 1095 if (!new) {
1096 va_end(args);
1074 return -ENOMEM; 1097 return -ENOMEM;
1098 }
1075 if (constrs->rules) { 1099 if (constrs->rules) {
1076 memcpy(new, constrs->rules, 1100 memcpy(new, constrs->rules,
1077 constrs->rules_num * sizeof(*c)); 1101 constrs->rules_num * sizeof(*c));
@@ -1087,8 +1111,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
1087 c->private = private; 1111 c->private = private;
1088 k = 0; 1112 k = 0;
1089 while (1) { 1113 while (1) {
1090 if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) 1114 if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) {
1115 va_end(args);
1091 return -EINVAL; 1116 return -EINVAL;
1117 }
1092 c->deps[k++] = dep; 1118 c->deps[k++] = dep;
1093 if (dep < 0) 1119 if (dep < 0)
1094 break; 1120 break;
@@ -1097,7 +1123,7 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond,
1097 constrs->rules_num++; 1123 constrs->rules_num++;
1098 va_end(args); 1124 va_end(args);
1099 return 0; 1125 return 0;
1100} 1126}
1101 1127
1102EXPORT_SYMBOL(snd_pcm_hw_rule_add); 1128EXPORT_SYMBOL(snd_pcm_hw_rule_add);
1103 1129
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index e82c1f97d99e..4be45e7be8ad 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -422,6 +422,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream,
422 runtime->info = params->info; 422 runtime->info = params->info;
423 runtime->rate_num = params->rate_num; 423 runtime->rate_num = params->rate_num;
424 runtime->rate_den = params->rate_den; 424 runtime->rate_den = params->rate_den;
425 runtime->no_period_wakeup =
426 (params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) &&
427 (params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP);
425 428
426 bits = snd_pcm_format_physical_width(runtime->format); 429 bits = snd_pcm_format_physical_width(runtime->format);
427 runtime->sample_bits = bits; 430 runtime->sample_bits = bits;
@@ -984,7 +987,7 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
984 if (push) 987 if (push)
985 snd_pcm_update_hw_ptr(substream); 988 snd_pcm_update_hw_ptr(substream);
986 /* The jiffies check in snd_pcm_update_hw_ptr*() is done by 989 /* The jiffies check in snd_pcm_update_hw_ptr*() is done by
987 * a delta betwen the current jiffies, this gives a large enough 990 * a delta between the current jiffies, this gives a large enough
988 * delta, effectively to skip the check once. 991 * delta, effectively to skip the check once.
989 */ 992 */
990 substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000; 993 substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000;
diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c
index bf09a5ad1865..119fddb6fc99 100644
--- a/sound/core/seq/seq.c
+++ b/sound/core/seq/seq.c
@@ -32,6 +32,7 @@
32#include "seq_timer.h" 32#include "seq_timer.h"
33#include "seq_system.h" 33#include "seq_system.h"
34#include "seq_info.h" 34#include "seq_info.h"
35#include <sound/minors.h>
35#include <sound/seq_device.h> 36#include <sound/seq_device.h>
36 37
37#if defined(CONFIG_SND_SEQ_DUMMY_MODULE) 38#if defined(CONFIG_SND_SEQ_DUMMY_MODULE)
@@ -73,6 +74,9 @@ MODULE_PARM_DESC(seq_default_timer_subdevice, "The default timer subdevice numbe
73module_param(seq_default_timer_resolution, int, 0644); 74module_param(seq_default_timer_resolution, int, 0644);
74MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz."); 75MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz.");
75 76
77MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_SEQUENCER);
78MODULE_ALIAS("devname:snd/seq");
79
76/* 80/*
77 * INIT PART 81 * INIT PART
78 */ 82 */
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 66691fe437e6..1c7a3efe1778 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -188,14 +188,22 @@ static const struct file_operations snd_fops =
188}; 188};
189 189
190#ifdef CONFIG_SND_DYNAMIC_MINORS 190#ifdef CONFIG_SND_DYNAMIC_MINORS
191static int snd_find_free_minor(void) 191static int snd_find_free_minor(int type)
192{ 192{
193 int minor; 193 int minor;
194 194
195 /* static minors for module auto loading */
196 if (type == SNDRV_DEVICE_TYPE_SEQUENCER)
197 return SNDRV_MINOR_SEQUENCER;
198 if (type == SNDRV_DEVICE_TYPE_TIMER)
199 return SNDRV_MINOR_TIMER;
200
195 for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) { 201 for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) {
196 /* skip minors still used statically for autoloading devices */ 202 /* skip static minors still used for module auto loading */
197 if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL || 203 if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL)
198 minor == SNDRV_MINOR_SEQUENCER) 204 continue;
205 if (minor == SNDRV_MINOR_SEQUENCER ||
206 minor == SNDRV_MINOR_TIMER)
199 continue; 207 continue;
200 if (!snd_minors[minor]) 208 if (!snd_minors[minor])
201 return minor; 209 return minor;
@@ -269,7 +277,7 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
269 preg->private_data = private_data; 277 preg->private_data = private_data;
270 mutex_lock(&sound_mutex); 278 mutex_lock(&sound_mutex);
271#ifdef CONFIG_SND_DYNAMIC_MINORS 279#ifdef CONFIG_SND_DYNAMIC_MINORS
272 minor = snd_find_free_minor(); 280 minor = snd_find_free_minor(type);
273#else 281#else
274 minor = snd_kernel_minor(type, card, dev); 282 minor = snd_kernel_minor(type, card, dev);
275 if (minor >= 0 && snd_minors[minor]) 283 if (minor >= 0 && snd_minors[minor])
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 13afb60999b9..ed016329e911 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -34,8 +34,8 @@
34#include <sound/initval.h> 34#include <sound/initval.h>
35#include <linux/kmod.h> 35#include <linux/kmod.h>
36 36
37#if defined(CONFIG_SND_HPET) || defined(CONFIG_SND_HPET_MODULE) 37#if defined(CONFIG_SND_HRTIMER) || defined(CONFIG_SND_HRTIMER_MODULE)
38#define DEFAULT_TIMER_LIMIT 3 38#define DEFAULT_TIMER_LIMIT 4
39#elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE) 39#elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE)
40#define DEFAULT_TIMER_LIMIT 2 40#define DEFAULT_TIMER_LIMIT 2
41#else 41#else
@@ -52,6 +52,9 @@ MODULE_PARM_DESC(timer_limit, "Maximum global timers in system.");
52module_param(timer_tstamp_monotonic, int, 0444); 52module_param(timer_tstamp_monotonic, int, 0444);
53MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default)."); 53MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default).");
54 54
55MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_TIMER);
56MODULE_ALIAS("devname:snd/timer");
57
55struct snd_timer_user { 58struct snd_timer_user {
56 struct snd_timer_instance *timeri; 59 struct snd_timer_instance *timeri;
57 int tread; /* enhanced read with timestamps and events */ 60 int tread; /* enhanced read with timestamps and events */
diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c
index a1282c1c0591..5cfcb908c430 100644
--- a/sound/drivers/ml403-ac97cr.c
+++ b/sound/drivers/ml403-ac97cr.c
@@ -1143,8 +1143,8 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev,
1143 (resource->start) + 1); 1143 (resource->start) + 1);
1144 if (ml403_ac97cr->port == NULL) { 1144 if (ml403_ac97cr->port == NULL) {
1145 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": " 1145 snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": "
1146 "unable to remap memory region (%x to %x)\n", 1146 "unable to remap memory region (%pR)\n",
1147 resource->start, resource->end); 1147 resource);
1148 snd_ml403_ac97cr_free(ml403_ac97cr); 1148 snd_ml403_ac97cr_free(ml403_ac97cr);
1149 return -EBUSY; 1149 return -EBUSY;
1150 } 1150 }
diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c
index 265abcce9dba..9b915e27b5bd 100644
--- a/sound/isa/opl3sa2.c
+++ b/sound/isa/opl3sa2.c
@@ -264,7 +264,7 @@ static int __devinit snd_opl3sa2_detect(struct snd_card *card)
264 snd_printd("OPL3-SA [0x%lx] detect (1) = 0x%x (0x%x)\n", port, tmp, tmp1); 264 snd_printd("OPL3-SA [0x%lx] detect (1) = 0x%x (0x%x)\n", port, tmp, tmp1);
265 return -ENODEV; 265 return -ENODEV;
266 } 266 }
267 /* try if the MIC register is accesible */ 267 /* try if the MIC register is accessible */
268 tmp = snd_opl3sa2_read(chip, OPL3SA2_MIC); 268 tmp = snd_opl3sa2_read(chip, OPL3SA2_MIC);
269 snd_opl3sa2_write(chip, OPL3SA2_MIC, 0x8a); 269 snd_opl3sa2_write(chip, OPL3SA2_MIC, 0x8a);
270 if (((tmp1 = snd_opl3sa2_read(chip, OPL3SA2_MIC)) & 0x9f) != 0x8a) { 270 if (((tmp1 = snd_opl3sa2_read(chip, OPL3SA2_MIC)) & 0x9f) != 0x8a) {
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 46c0d03dbecc..fcb14a099822 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -87,7 +87,7 @@ int *load_mixer_volumes(char *name, int *levels, int present)
87 int i, n; 87 int i, n;
88 88
89 for (i = 0; i < num_mixer_volumes; i++) { 89 for (i = 0; i < num_mixer_volumes; i++) {
90 if (strcmp(name, mixer_vols[i].name) == 0) { 90 if (strncmp(name, mixer_vols[i].name, 32) == 0) {
91 if (present) 91 if (present)
92 mixer_vols[i].num = i; 92 mixer_vols[i].num = i;
93 return mixer_vols[i].levels; 93 return mixer_vols[i].levels;
@@ -99,7 +99,7 @@ int *load_mixer_volumes(char *name, int *levels, int present)
99 } 99 }
100 n = num_mixer_volumes++; 100 n = num_mixer_volumes++;
101 101
102 strcpy(mixer_vols[n].name, name); 102 strncpy(mixer_vols[n].name, name, 32);
103 103
104 if (present) 104 if (present)
105 mixer_vols[n].num = n; 105 mixer_vols[n].num = n;
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig
index 12e34653b8a8..9823d59d7ad7 100644
--- a/sound/pci/Kconfig
+++ b/sound/pci/Kconfig
@@ -209,7 +209,7 @@ config SND_OXYGEN_LIB
209 tristate 209 tristate
210 210
211config SND_OXYGEN 211config SND_OXYGEN
212 tristate "C-Media 8788 (Oxygen)" 212 tristate "C-Media 8786, 8787, 8788 (Oxygen)"
213 select SND_OXYGEN_LIB 213 select SND_OXYGEN_LIB
214 select SND_PCM 214 select SND_PCM
215 select SND_MPU401_UART 215 select SND_MPU401_UART
@@ -217,13 +217,18 @@ config SND_OXYGEN
217 Say Y here to include support for sound cards based on the 217 Say Y here to include support for sound cards based on the
218 C-Media CMI8788 (Oxygen HD Audio) chip: 218 C-Media CMI8788 (Oxygen HD Audio) chip:
219 * Asound A-8788 219 * Asound A-8788
220 * Asus Xonar DG
220 * AuzenTech X-Meridian 221 * AuzenTech X-Meridian
222 * AuzenTech X-Meridian 2G
221 * Bgears b-Enspirer 223 * Bgears b-Enspirer
222 * Club3D Theatron DTS 224 * Club3D Theatron DTS
223 * HT-Omega Claro (plus) 225 * HT-Omega Claro (plus)
224 * HT-Omega Claro halo (XT) 226 * HT-Omega Claro halo (XT)
227 * Kuroutoshikou CMI8787-HG2PCI
225 * Razer Barracuda AC-1 228 * Razer Barracuda AC-1
226 * Sondigo Inferno 229 * Sondigo Inferno
230 * TempoTec/MediaTek HiFier Fantasia
231 * TempoTec/MediaTek HiFier Serenade
227 232
228 To compile this driver as a module, choose M here: the module 233 To compile this driver as a module, choose M here: the module
229 will be called snd-oxygen. 234 will be called snd-oxygen.
@@ -578,18 +583,6 @@ config SND_HDSPM
578 To compile this driver as a module, choose M here: the module 583 To compile this driver as a module, choose M here: the module
579 will be called snd-hdspm. 584 will be called snd-hdspm.
580 585
581config SND_HIFIER
582 tristate "TempoTec HiFier Fantasia"
583 select SND_OXYGEN_LIB
584 select SND_PCM
585 select SND_MPU401_UART
586 help
587 Say Y here to include support for the MediaTek/TempoTec HiFier
588 Fantasia sound card.
589
590 To compile this driver as a module, choose M here: the module
591 will be called snd-hifier.
592
593config SND_ICE1712 586config SND_ICE1712
594 tristate "ICEnsemble ICE1712 (Envy24)" 587 tristate "ICEnsemble ICE1712 (Envy24)"
595 select SND_MPU401_UART 588 select SND_MPU401_UART
@@ -826,8 +819,8 @@ config SND_VIRTUOSO
826 Say Y here to include support for sound cards based on the 819 Say Y here to include support for sound cards based on the
827 Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS, 820 Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS,
828 Essence ST (Deluxe), and Essence STX. 821 Essence ST (Deluxe), and Essence STX.
829 Support for the HDAV1.3 (Deluxe) is incomplete; for the 822 Support for the HDAV1.3 (Deluxe) and HDAV1.3 Slim is experimental;
830 HDAV1.3 Slim and Xense, missing. 823 for the Xense, missing.
831 824
832 To compile this driver as a module, choose M here: the module 825 To compile this driver as a module, choose M here: the module
833 will be called snd-virtuoso. 826 will be called snd-virtuoso.
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index 0fc614ce16c1..cb62d178b3e0 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -1961,7 +1961,7 @@ static int snd_ac97_dev_disconnect(struct snd_device *device)
1961} 1961}
1962 1962
1963/* build_ops to do nothing */ 1963/* build_ops to do nothing */
1964static struct snd_ac97_build_ops null_build_ops; 1964static const struct snd_ac97_build_ops null_build_ops;
1965 1965
1966#ifdef CONFIG_SND_AC97_POWER_SAVE 1966#ifdef CONFIG_SND_AC97_POWER_SAVE
1967static void do_update_power(struct work_struct *work) 1967static void do_update_power(struct work_struct *work)
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index e68c98ef4041..bf47574ca1f0 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -371,7 +371,7 @@ static int patch_yamaha_ymf743_build_spdif(struct snd_ac97 *ac97)
371 return 0; 371 return 0;
372} 372}
373 373
374static struct snd_ac97_build_ops patch_yamaha_ymf743_ops = { 374static const struct snd_ac97_build_ops patch_yamaha_ymf743_ops = {
375 .build_spdif = patch_yamaha_ymf743_build_spdif, 375 .build_spdif = patch_yamaha_ymf743_build_spdif,
376 .build_3d = patch_yamaha_ymf7x3_3d, 376 .build_3d = patch_yamaha_ymf7x3_3d,
377}; 377};
@@ -455,7 +455,7 @@ static int patch_yamaha_ymf753_post_spdif(struct snd_ac97 * ac97)
455 return 0; 455 return 0;
456} 456}
457 457
458static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { 458static const struct snd_ac97_build_ops patch_yamaha_ymf753_ops = {
459 .build_3d = patch_yamaha_ymf7x3_3d, 459 .build_3d = patch_yamaha_ymf7x3_3d,
460 .build_post_spdif = patch_yamaha_ymf753_post_spdif 460 .build_post_spdif = patch_yamaha_ymf753_post_spdif
461}; 461};
@@ -502,7 +502,7 @@ static int patch_wolfson_wm9703_specific(struct snd_ac97 * ac97)
502 return 0; 502 return 0;
503} 503}
504 504
505static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { 505static const struct snd_ac97_build_ops patch_wolfson_wm9703_ops = {
506 .build_specific = patch_wolfson_wm9703_specific, 506 .build_specific = patch_wolfson_wm9703_specific,
507}; 507};
508 508
@@ -533,7 +533,7 @@ static int patch_wolfson_wm9704_specific(struct snd_ac97 * ac97)
533 return 0; 533 return 0;
534} 534}
535 535
536static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { 536static const struct snd_ac97_build_ops patch_wolfson_wm9704_ops = {
537 .build_specific = patch_wolfson_wm9704_specific, 537 .build_specific = patch_wolfson_wm9704_specific,
538}; 538};
539 539
@@ -677,7 +677,7 @@ static int patch_wolfson_wm9711_specific(struct snd_ac97 * ac97)
677 return 0; 677 return 0;
678} 678}
679 679
680static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { 680static const struct snd_ac97_build_ops patch_wolfson_wm9711_ops = {
681 .build_specific = patch_wolfson_wm9711_specific, 681 .build_specific = patch_wolfson_wm9711_specific,
682}; 682};
683 683
@@ -871,7 +871,7 @@ static void patch_wolfson_wm9713_resume (struct snd_ac97 * ac97)
871} 871}
872#endif 872#endif
873 873
874static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { 874static const struct snd_ac97_build_ops patch_wolfson_wm9713_ops = {
875 .build_specific = patch_wolfson_wm9713_specific, 875 .build_specific = patch_wolfson_wm9713_specific,
876 .build_3d = patch_wolfson_wm9713_3d, 876 .build_3d = patch_wolfson_wm9713_3d,
877#ifdef CONFIG_PM 877#ifdef CONFIG_PM
@@ -976,7 +976,7 @@ static int patch_sigmatel_stac97xx_specific(struct snd_ac97 * ac97)
976 return 0; 976 return 0;
977} 977}
978 978
979static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = { 979static const struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = {
980 .build_3d = patch_sigmatel_stac9700_3d, 980 .build_3d = patch_sigmatel_stac9700_3d,
981 .build_specific = patch_sigmatel_stac97xx_specific 981 .build_specific = patch_sigmatel_stac97xx_specific
982}; 982};
@@ -1023,7 +1023,7 @@ static int patch_sigmatel_stac9708_specific(struct snd_ac97 *ac97)
1023 return patch_sigmatel_stac97xx_specific(ac97); 1023 return patch_sigmatel_stac97xx_specific(ac97);
1024} 1024}
1025 1025
1026static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = { 1026static const struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = {
1027 .build_3d = patch_sigmatel_stac9708_3d, 1027 .build_3d = patch_sigmatel_stac9708_3d,
1028 .build_specific = patch_sigmatel_stac9708_specific 1028 .build_specific = patch_sigmatel_stac9708_specific
1029}; 1029};
@@ -1252,7 +1252,7 @@ static int patch_sigmatel_stac9758_specific(struct snd_ac97 *ac97)
1252 return 0; 1252 return 0;
1253} 1253}
1254 1254
1255static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = { 1255static const struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = {
1256 .build_3d = patch_sigmatel_stac9700_3d, 1256 .build_3d = patch_sigmatel_stac9700_3d,
1257 .build_specific = patch_sigmatel_stac9758_specific 1257 .build_specific = patch_sigmatel_stac9758_specific
1258}; 1258};
@@ -1327,7 +1327,7 @@ static int patch_cirrus_build_spdif(struct snd_ac97 * ac97)
1327 return 0; 1327 return 0;
1328} 1328}
1329 1329
1330static struct snd_ac97_build_ops patch_cirrus_ops = { 1330static const struct snd_ac97_build_ops patch_cirrus_ops = {
1331 .build_spdif = patch_cirrus_build_spdif 1331 .build_spdif = patch_cirrus_build_spdif
1332}; 1332};
1333 1333
@@ -1384,7 +1384,7 @@ static int patch_conexant_build_spdif(struct snd_ac97 * ac97)
1384 return 0; 1384 return 0;
1385} 1385}
1386 1386
1387static struct snd_ac97_build_ops patch_conexant_ops = { 1387static const struct snd_ac97_build_ops patch_conexant_ops = {
1388 .build_spdif = patch_conexant_build_spdif 1388 .build_spdif = patch_conexant_build_spdif
1389}; 1389};
1390 1390
@@ -1560,7 +1560,7 @@ static void patch_ad1881_chained(struct snd_ac97 * ac97, int unchained_idx, int
1560 } 1560 }
1561} 1561}
1562 1562
1563static struct snd_ac97_build_ops patch_ad1881_build_ops = { 1563static const struct snd_ac97_build_ops patch_ad1881_build_ops = {
1564#ifdef CONFIG_PM 1564#ifdef CONFIG_PM
1565 .resume = ad18xx_resume 1565 .resume = ad18xx_resume
1566#endif 1566#endif
@@ -1647,7 +1647,7 @@ static int patch_ad1885_specific(struct snd_ac97 * ac97)
1647 return 0; 1647 return 0;
1648} 1648}
1649 1649
1650static struct snd_ac97_build_ops patch_ad1885_build_ops = { 1650static const struct snd_ac97_build_ops patch_ad1885_build_ops = {
1651 .build_specific = &patch_ad1885_specific, 1651 .build_specific = &patch_ad1885_specific,
1652#ifdef CONFIG_PM 1652#ifdef CONFIG_PM
1653 .resume = ad18xx_resume 1653 .resume = ad18xx_resume
@@ -1674,7 +1674,7 @@ static int patch_ad1886_specific(struct snd_ac97 * ac97)
1674 return 0; 1674 return 0;
1675} 1675}
1676 1676
1677static struct snd_ac97_build_ops patch_ad1886_build_ops = { 1677static const struct snd_ac97_build_ops patch_ad1886_build_ops = {
1678 .build_specific = &patch_ad1886_specific, 1678 .build_specific = &patch_ad1886_specific,
1679#ifdef CONFIG_PM 1679#ifdef CONFIG_PM
1680 .resume = ad18xx_resume 1680 .resume = ad18xx_resume
@@ -1881,7 +1881,7 @@ static int patch_ad1981a_specific(struct snd_ac97 * ac97)
1881 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense)); 1881 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
1882} 1882}
1883 1883
1884static struct snd_ac97_build_ops patch_ad1981a_build_ops = { 1884static const struct snd_ac97_build_ops patch_ad1981a_build_ops = {
1885 .build_post_spdif = patch_ad198x_post_spdif, 1885 .build_post_spdif = patch_ad198x_post_spdif,
1886 .build_specific = patch_ad1981a_specific, 1886 .build_specific = patch_ad1981a_specific,
1887#ifdef CONFIG_PM 1887#ifdef CONFIG_PM
@@ -1936,7 +1936,7 @@ static int patch_ad1981b_specific(struct snd_ac97 *ac97)
1936 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense)); 1936 ARRAY_SIZE(snd_ac97_ad1981x_jack_sense));
1937} 1937}
1938 1938
1939static struct snd_ac97_build_ops patch_ad1981b_build_ops = { 1939static const struct snd_ac97_build_ops patch_ad1981b_build_ops = {
1940 .build_post_spdif = patch_ad198x_post_spdif, 1940 .build_post_spdif = patch_ad198x_post_spdif,
1941 .build_specific = patch_ad1981b_specific, 1941 .build_specific = patch_ad1981b_specific,
1942#ifdef CONFIG_PM 1942#ifdef CONFIG_PM
@@ -2075,7 +2075,7 @@ static int patch_ad1888_specific(struct snd_ac97 *ac97)
2075 return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls)); 2075 return patch_build_controls(ac97, snd_ac97_ad1888_controls, ARRAY_SIZE(snd_ac97_ad1888_controls));
2076} 2076}
2077 2077
2078static struct snd_ac97_build_ops patch_ad1888_build_ops = { 2078static const struct snd_ac97_build_ops patch_ad1888_build_ops = {
2079 .build_post_spdif = patch_ad198x_post_spdif, 2079 .build_post_spdif = patch_ad198x_post_spdif,
2080 .build_specific = patch_ad1888_specific, 2080 .build_specific = patch_ad1888_specific,
2081#ifdef CONFIG_PM 2081#ifdef CONFIG_PM
@@ -2124,7 +2124,7 @@ static int patch_ad1980_specific(struct snd_ac97 *ac97)
2124 return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1); 2124 return patch_build_controls(ac97, &snd_ac97_ad198x_2cmic, 1);
2125} 2125}
2126 2126
2127static struct snd_ac97_build_ops patch_ad1980_build_ops = { 2127static const struct snd_ac97_build_ops patch_ad1980_build_ops = {
2128 .build_post_spdif = patch_ad198x_post_spdif, 2128 .build_post_spdif = patch_ad198x_post_spdif,
2129 .build_specific = patch_ad1980_specific, 2129 .build_specific = patch_ad1980_specific,
2130#ifdef CONFIG_PM 2130#ifdef CONFIG_PM
@@ -2239,7 +2239,7 @@ static int patch_ad1985_specific(struct snd_ac97 *ac97)
2239 ARRAY_SIZE(snd_ac97_ad1985_controls)); 2239 ARRAY_SIZE(snd_ac97_ad1985_controls));
2240} 2240}
2241 2241
2242static struct snd_ac97_build_ops patch_ad1985_build_ops = { 2242static const struct snd_ac97_build_ops patch_ad1985_build_ops = {
2243 .build_post_spdif = patch_ad198x_post_spdif, 2243 .build_post_spdif = patch_ad198x_post_spdif,
2244 .build_specific = patch_ad1985_specific, 2244 .build_specific = patch_ad1985_specific,
2245#ifdef CONFIG_PM 2245#ifdef CONFIG_PM
@@ -2531,7 +2531,7 @@ static int patch_ad1986_specific(struct snd_ac97 *ac97)
2531 ARRAY_SIZE(snd_ac97_ad1985_controls)); 2531 ARRAY_SIZE(snd_ac97_ad1985_controls));
2532} 2532}
2533 2533
2534static struct snd_ac97_build_ops patch_ad1986_build_ops = { 2534static const struct snd_ac97_build_ops patch_ad1986_build_ops = {
2535 .build_post_spdif = patch_ad198x_post_spdif, 2535 .build_post_spdif = patch_ad198x_post_spdif,
2536 .build_specific = patch_ad1986_specific, 2536 .build_specific = patch_ad1986_specific,
2537#ifdef CONFIG_PM 2537#ifdef CONFIG_PM
@@ -2636,7 +2636,7 @@ static int patch_alc650_specific(struct snd_ac97 * ac97)
2636 return 0; 2636 return 0;
2637} 2637}
2638 2638
2639static struct snd_ac97_build_ops patch_alc650_ops = { 2639static const struct snd_ac97_build_ops patch_alc650_ops = {
2640 .build_specific = patch_alc650_specific, 2640 .build_specific = patch_alc650_specific,
2641 .update_jacks = alc650_update_jacks 2641 .update_jacks = alc650_update_jacks
2642}; 2642};
@@ -2788,7 +2788,7 @@ static int patch_alc655_specific(struct snd_ac97 * ac97)
2788 return 0; 2788 return 0;
2789} 2789}
2790 2790
2791static struct snd_ac97_build_ops patch_alc655_ops = { 2791static const struct snd_ac97_build_ops patch_alc655_ops = {
2792 .build_specific = patch_alc655_specific, 2792 .build_specific = patch_alc655_specific,
2793 .update_jacks = alc655_update_jacks 2793 .update_jacks = alc655_update_jacks
2794}; 2794};
@@ -2900,7 +2900,7 @@ static int patch_alc850_specific(struct snd_ac97 *ac97)
2900 return 0; 2900 return 0;
2901} 2901}
2902 2902
2903static struct snd_ac97_build_ops patch_alc850_ops = { 2903static const struct snd_ac97_build_ops patch_alc850_ops = {
2904 .build_specific = patch_alc850_specific, 2904 .build_specific = patch_alc850_specific,
2905 .update_jacks = alc850_update_jacks 2905 .update_jacks = alc850_update_jacks
2906}; 2906};
@@ -2962,7 +2962,7 @@ static int patch_cm9738_specific(struct snd_ac97 * ac97)
2962 return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls)); 2962 return patch_build_controls(ac97, snd_ac97_cm9738_controls, ARRAY_SIZE(snd_ac97_cm9738_controls));
2963} 2963}
2964 2964
2965static struct snd_ac97_build_ops patch_cm9738_ops = { 2965static const struct snd_ac97_build_ops patch_cm9738_ops = {
2966 .build_specific = patch_cm9738_specific, 2966 .build_specific = patch_cm9738_specific,
2967 .update_jacks = cm9738_update_jacks 2967 .update_jacks = cm9738_update_jacks
2968}; 2968};
@@ -3053,7 +3053,7 @@ static int patch_cm9739_post_spdif(struct snd_ac97 * ac97)
3053 return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif)); 3053 return patch_build_controls(ac97, snd_ac97_cm9739_controls_spdif, ARRAY_SIZE(snd_ac97_cm9739_controls_spdif));
3054} 3054}
3055 3055
3056static struct snd_ac97_build_ops patch_cm9739_ops = { 3056static const struct snd_ac97_build_ops patch_cm9739_ops = {
3057 .build_specific = patch_cm9739_specific, 3057 .build_specific = patch_cm9739_specific,
3058 .build_post_spdif = patch_cm9739_post_spdif, 3058 .build_post_spdif = patch_cm9739_post_spdif,
3059 .update_jacks = cm9739_update_jacks 3059 .update_jacks = cm9739_update_jacks
@@ -3227,7 +3227,7 @@ static int patch_cm9761_specific(struct snd_ac97 * ac97)
3227 return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls)); 3227 return patch_build_controls(ac97, snd_ac97_cm9761_controls, ARRAY_SIZE(snd_ac97_cm9761_controls));
3228} 3228}
3229 3229
3230static struct snd_ac97_build_ops patch_cm9761_ops = { 3230static const struct snd_ac97_build_ops patch_cm9761_ops = {
3231 .build_specific = patch_cm9761_specific, 3231 .build_specific = patch_cm9761_specific,
3232 .build_post_spdif = patch_cm9761_post_spdif, 3232 .build_post_spdif = patch_cm9761_post_spdif,
3233 .update_jacks = cm9761_update_jacks 3233 .update_jacks = cm9761_update_jacks
@@ -3323,7 +3323,7 @@ static int patch_cm9780_specific(struct snd_ac97 *ac97)
3323 return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls)); 3323 return patch_build_controls(ac97, cm9780_controls, ARRAY_SIZE(cm9780_controls));
3324} 3324}
3325 3325
3326static struct snd_ac97_build_ops patch_cm9780_ops = { 3326static const struct snd_ac97_build_ops patch_cm9780_ops = {
3327 .build_specific = patch_cm9780_specific, 3327 .build_specific = patch_cm9780_specific,
3328 .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */ 3328 .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */
3329}; 3329};
@@ -3443,7 +3443,7 @@ static int patch_vt1616_specific(struct snd_ac97 * ac97)
3443 return 0; 3443 return 0;
3444} 3444}
3445 3445
3446static struct snd_ac97_build_ops patch_vt1616_ops = { 3446static const struct snd_ac97_build_ops patch_vt1616_ops = {
3447 .build_specific = patch_vt1616_specific 3447 .build_specific = patch_vt1616_specific
3448}; 3448};
3449 3449
@@ -3797,7 +3797,7 @@ static int patch_it2646_specific(struct snd_ac97 * ac97)
3797 return 0; 3797 return 0;
3798} 3798}
3799 3799
3800static struct snd_ac97_build_ops patch_it2646_ops = { 3800static const struct snd_ac97_build_ops patch_it2646_ops = {
3801 .build_specific = patch_it2646_specific, 3801 .build_specific = patch_it2646_specific,
3802 .update_jacks = it2646_update_jacks 3802 .update_jacks = it2646_update_jacks
3803}; 3803};
@@ -3831,7 +3831,7 @@ static int patch_si3036_specific(struct snd_ac97 * ac97)
3831 return 0; 3831 return 0;
3832} 3832}
3833 3833
3834static struct snd_ac97_build_ops patch_si3036_ops = { 3834static const struct snd_ac97_build_ops patch_si3036_ops = {
3835 .build_specific = patch_si3036_specific, 3835 .build_specific = patch_si3036_specific,
3836}; 3836};
3837 3837
@@ -3898,7 +3898,7 @@ static int patch_ucb1400_specific(struct snd_ac97 * ac97)
3898 return 0; 3898 return 0;
3899} 3899}
3900 3900
3901static struct snd_ac97_build_ops patch_ucb1400_ops = { 3901static const struct snd_ac97_build_ops patch_ucb1400_ops = {
3902 .build_specific = patch_ucb1400_specific, 3902 .build_specific = patch_ucb1400_specific,
3903}; 3903};
3904 3904
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c
index b9d2f202cf9b..5439d662d104 100644
--- a/sound/pci/au88x0/au88x0_pcm.c
+++ b/sound/pci/au88x0/au88x0_pcm.c
@@ -42,11 +42,7 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_adb = {
42 .rate_min = 5000, 42 .rate_min = 5000,
43 .rate_max = 48000, 43 .rate_max = 48000,
44 .channels_min = 1, 44 .channels_min = 1,
45#ifdef CHIP_AU8830
46 .channels_max = 4,
47#else
48 .channels_max = 2, 45 .channels_max = 2,
49#endif
50 .buffer_bytes_max = 0x10000, 46 .buffer_bytes_max = 0x10000,
51 .period_bytes_min = 0x1, 47 .period_bytes_min = 0x1,
52 .period_bytes_max = 0x1000, 48 .period_bytes_max = 0x1000,
@@ -115,6 +111,17 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_wt = {
115 .periods_max = 64, 111 .periods_max = 64,
116}; 112};
117#endif 113#endif
114#ifdef CHIP_AU8830
115static unsigned int au8830_channels[3] = {
116 1, 2, 4,
117};
118
119static struct snd_pcm_hw_constraint_list hw_constraints_au8830_channels = {
120 .count = ARRAY_SIZE(au8830_channels),
121 .list = au8830_channels,
122 .mask = 0,
123};
124#endif
118/* open callback */ 125/* open callback */
119static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) 126static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
120{ 127{
@@ -156,6 +163,15 @@ static int snd_vortex_pcm_open(struct snd_pcm_substream *substream)
156 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB 163 if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB
157 || VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S) 164 || VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_I2S)
158 runtime->hw = snd_vortex_playback_hw_adb; 165 runtime->hw = snd_vortex_playback_hw_adb;
166#ifdef CHIP_AU8830
167 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
168 VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_ADB) {
169 runtime->hw.channels_max = 4;
170 snd_pcm_hw_constraint_list(runtime, 0,
171 SNDRV_PCM_HW_PARAM_CHANNELS,
172 &hw_constraints_au8830_channels);
173 }
174#endif
159 substream->runtime->private_data = NULL; 175 substream->runtime->private_data = NULL;
160 } 176 }
161#ifndef CHIP_AU8810 177#ifndef CHIP_AU8810
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 2f3cacbd5528..6117595fc075 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). 2 * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168).
3 * Copyright (C) 2002, 2005 - 2009 by Andreas Mohr <andi AT lisas.de> 3 * Copyright (C) 2002, 2005 - 2010 by Andreas Mohr <andi AT lisas.de>
4 * 4 *
5 * Framework borrowed from Bart Hartgers's als4000.c. 5 * Framework borrowed from Bart Hartgers's als4000.c.
6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), 6 * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801),
@@ -175,6 +175,7 @@
175 175
176#include <asm/io.h> 176#include <asm/io.h>
177#include <linux/init.h> 177#include <linux/init.h>
178#include <linux/bug.h> /* WARN_ONCE */
178#include <linux/pci.h> 179#include <linux/pci.h>
179#include <linux/delay.h> 180#include <linux/delay.h>
180#include <linux/slab.h> 181#include <linux/slab.h>
@@ -201,14 +202,15 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
201 202
202/* === Debug settings === 203/* === Debug settings ===
203 Further diagnostic functionality than the settings below 204 Further diagnostic functionality than the settings below
204 does not need to be provided, since one can easily write a bash script 205 does not need to be provided, since one can easily write a POSIX shell script
205 to dump the card's I/O ports (those listed in lspci -v -v): 206 to dump the card's I/O ports (those listed in lspci -v -v):
206 function dump() 207 dump()
207 { 208 {
208 local descr=$1; local addr=$2; local count=$3 209 local descr=$1; local addr=$2; local count=$3
209 210
210 echo "${descr}: ${count} @ ${addr}:" 211 echo "${descr}: ${count} @ ${addr}:"
211 dd if=/dev/port skip=$[${addr}] count=${count} bs=1 2>/dev/null| hexdump -C 212 dd if=/dev/port skip=`printf %d ${addr}` count=${count} bs=1 \
213 2>/dev/null| hexdump -C
212 } 214 }
213 and then use something like 215 and then use something like
214 "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8", 216 "dump joy200 0x200 8", "dump mpu388 0x388 4", "dump joy 0xb400 8",
@@ -216,14 +218,14 @@ MODULE_SUPPORTED_DEVICE("{{Aztech,AZF3328}}");
216 possibly within a "while true; do ... sleep 1; done" loop. 218 possibly within a "while true; do ... sleep 1; done" loop.
217 Tweaking ports could be done using 219 Tweaking ports could be done using
218 VALSTRING="`printf "%02x" $value`" 220 VALSTRING="`printf "%02x" $value`"
219 printf "\x""$VALSTRING"|dd of=/dev/port seek=$[${addr}] bs=1 2>/dev/null 221 printf "\x""$VALSTRING"|dd of=/dev/port seek=`printf %d ${addr}` bs=1 \
222 2>/dev/null
220*/ 223*/
221 224
222#define DEBUG_MISC 0 225#define DEBUG_MISC 0
223#define DEBUG_CALLS 0 226#define DEBUG_CALLS 0
224#define DEBUG_MIXER 0 227#define DEBUG_MIXER 0
225#define DEBUG_CODEC 0 228#define DEBUG_CODEC 0
226#define DEBUG_IO 0
227#define DEBUG_TIMER 0 229#define DEBUG_TIMER 0
228#define DEBUG_GAME 0 230#define DEBUG_GAME 0
229#define DEBUG_PM 0 231#define DEBUG_PM 0
@@ -291,19 +293,23 @@ static int seqtimer_scaling = 128;
291module_param(seqtimer_scaling, int, 0444); 293module_param(seqtimer_scaling, int, 0444);
292MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128."); 294MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128.");
293 295
294struct snd_azf3328_codec_data {
295 unsigned long io_base;
296 struct snd_pcm_substream *substream;
297 bool running;
298 const char *name;
299};
300
301enum snd_azf3328_codec_type { 296enum snd_azf3328_codec_type {
297 /* warning: fixed indices (also used for bitmask checks!) */
302 AZF_CODEC_PLAYBACK = 0, 298 AZF_CODEC_PLAYBACK = 0,
303 AZF_CODEC_CAPTURE = 1, 299 AZF_CODEC_CAPTURE = 1,
304 AZF_CODEC_I2S_OUT = 2, 300 AZF_CODEC_I2S_OUT = 2,
305}; 301};
306 302
303struct snd_azf3328_codec_data {
304 unsigned long io_base; /* keep first! (avoid offset calc) */
305 unsigned int dma_base; /* helper to avoid an indirection in hotpath */
306 spinlock_t *lock; /* TODO: convert to our own per-codec lock member */
307 struct snd_pcm_substream *substream;
308 bool running;
309 enum snd_azf3328_codec_type type;
310 const char *name;
311};
312
307struct snd_azf3328 { 313struct snd_azf3328 {
308 /* often-used fields towards beginning, then grouped */ 314 /* often-used fields towards beginning, then grouped */
309 315
@@ -362,6 +368,9 @@ MODULE_DEVICE_TABLE(pci, snd_azf3328_ids);
362static int 368static int
363snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set) 369snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set)
364{ 370{
371 /* Well, strictly spoken, the inb/outb sequence isn't atomic
372 and would need locking. However we currently don't care
373 since it potentially complicates matters. */
365 u8 prev = inb(reg), new; 374 u8 prev = inb(reg), new;
366 375
367 new = (do_set) ? (prev|mask) : (prev & ~mask); 376 new = (do_set) ? (prev|mask) : (prev & ~mask);
@@ -413,6 +422,21 @@ snd_azf3328_codec_outl(const struct snd_azf3328_codec_data *codec,
413 outl(value, codec->io_base + reg); 422 outl(value, codec->io_base + reg);
414} 423}
415 424
425static inline void
426snd_azf3328_codec_outl_multi(const struct snd_azf3328_codec_data *codec,
427 unsigned reg, const void *buffer, int count
428)
429{
430 unsigned long addr = codec->io_base + reg;
431 if (count) {
432 const u32 *buf = buffer;
433 do {
434 outl(*buf++, addr);
435 addr += 4;
436 } while (--count);
437 }
438}
439
416static inline u32 440static inline u32
417snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg) 441snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg)
418{ 442{
@@ -943,38 +967,43 @@ snd_azf3328_hw_free(struct snd_pcm_substream *substream)
943} 967}
944 968
945static void 969static void
946snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, 970snd_azf3328_codec_setfmt(struct snd_azf3328_codec_data *codec,
947 enum snd_azf3328_codec_type codec_type,
948 enum azf_freq_t bitrate, 971 enum azf_freq_t bitrate,
949 unsigned int format_width, 972 unsigned int format_width,
950 unsigned int channels 973 unsigned int channels
951) 974)
952{ 975{
953 unsigned long flags; 976 unsigned long flags;
954 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
955 u16 val = 0xff00; 977 u16 val = 0xff00;
978 u8 freq = 0;
956 979
957 snd_azf3328_dbgcallenter(); 980 snd_azf3328_dbgcallenter();
958 switch (bitrate) { 981 switch (bitrate) {
959 case AZF_FREQ_4000: val |= SOUNDFORMAT_FREQ_SUSPECTED_4000; break; 982#define AZF_FMT_XLATE(in_freq, out_bits) \
960 case AZF_FREQ_4800: val |= SOUNDFORMAT_FREQ_SUSPECTED_4800; break; 983 do { \
961 case AZF_FREQ_5512: 984 case AZF_FREQ_ ## in_freq: \
962 /* the AZF3328 names it "5510" for some strange reason */ 985 freq = SOUNDFORMAT_FREQ_ ## out_bits; \
963 val |= SOUNDFORMAT_FREQ_5510; break; 986 break; \
964 case AZF_FREQ_6620: val |= SOUNDFORMAT_FREQ_6620; break; 987 } while (0);
965 case AZF_FREQ_8000: val |= SOUNDFORMAT_FREQ_8000; break; 988 AZF_FMT_XLATE(4000, SUSPECTED_4000)
966 case AZF_FREQ_9600: val |= SOUNDFORMAT_FREQ_9600; break; 989 AZF_FMT_XLATE(4800, SUSPECTED_4800)
967 case AZF_FREQ_11025: val |= SOUNDFORMAT_FREQ_11025; break; 990 /* the AZF3328 names it "5510" for some strange reason: */
968 case AZF_FREQ_13240: val |= SOUNDFORMAT_FREQ_SUSPECTED_13240; break; 991 AZF_FMT_XLATE(5512, 5510)
969 case AZF_FREQ_16000: val |= SOUNDFORMAT_FREQ_16000; break; 992 AZF_FMT_XLATE(6620, 6620)
970 case AZF_FREQ_22050: val |= SOUNDFORMAT_FREQ_22050; break; 993 AZF_FMT_XLATE(8000, 8000)
971 case AZF_FREQ_32000: val |= SOUNDFORMAT_FREQ_32000; break; 994 AZF_FMT_XLATE(9600, 9600)
995 AZF_FMT_XLATE(11025, 11025)
996 AZF_FMT_XLATE(13240, SUSPECTED_13240)
997 AZF_FMT_XLATE(16000, 16000)
998 AZF_FMT_XLATE(22050, 22050)
999 AZF_FMT_XLATE(32000, 32000)
972 default: 1000 default:
973 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate); 1001 snd_printk(KERN_WARNING "unknown bitrate %d, assuming 44.1kHz!\n", bitrate);
974 /* fall-through */ 1002 /* fall-through */
975 case AZF_FREQ_44100: val |= SOUNDFORMAT_FREQ_44100; break; 1003 AZF_FMT_XLATE(44100, 44100)
976 case AZF_FREQ_48000: val |= SOUNDFORMAT_FREQ_48000; break; 1004 AZF_FMT_XLATE(48000, 48000)
977 case AZF_FREQ_66200: val |= SOUNDFORMAT_FREQ_SUSPECTED_66200; break; 1005 AZF_FMT_XLATE(66200, SUSPECTED_66200)
1006#undef AZF_FMT_XLATE
978 } 1007 }
979 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */ 1008 /* val = 0xff07; 3m27.993s (65301Hz; -> 64000Hz???) hmm, 66120, 65967, 66123 */
980 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */ 1009 /* val = 0xff09; 17m15.098s (13123,478Hz; -> 12000Hz???) hmm, 13237.2Hz? */
@@ -986,13 +1015,15 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
986 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */ 1015 /* val = 0xff0d; 41m23.135s (5523,600Hz; -> 5512Hz???) */
987 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */ 1016 /* val = 0xff0e; 28m30.777s (8017Hz; -> 8000Hz???) */
988 1017
1018 val |= freq;
1019
989 if (channels == 2) 1020 if (channels == 2)
990 val |= SOUNDFORMAT_FLAG_2CHANNELS; 1021 val |= SOUNDFORMAT_FLAG_2CHANNELS;
991 1022
992 if (format_width == 16) 1023 if (format_width == 16)
993 val |= SOUNDFORMAT_FLAG_16BIT; 1024 val |= SOUNDFORMAT_FLAG_16BIT;
994 1025
995 spin_lock_irqsave(&chip->reg_lock, flags); 1026 spin_lock_irqsave(codec->lock, flags);
996 1027
997 /* set bitrate/format */ 1028 /* set bitrate/format */
998 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val); 1029 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_SOUNDFORMAT, val);
@@ -1004,7 +1035,8 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
1004 * (FIXME: yes, it works, but what exactly am I doing here?? :) 1035 * (FIXME: yes, it works, but what exactly am I doing here?? :)
1005 * FIXME: does this have some side effects for full-duplex 1036 * FIXME: does this have some side effects for full-duplex
1006 * or other dramatic side effects? */ 1037 * or other dramatic side effects? */
1007 if (codec_type == AZF_CODEC_PLAYBACK) /* only do it for playback */ 1038 /* do it for non-capture codecs only */
1039 if (codec->type != AZF_CODEC_CAPTURE)
1008 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, 1040 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1009 snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) | 1041 snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS) |
1010 DMA_RUN_SOMETHING1 | 1042 DMA_RUN_SOMETHING1 |
@@ -1014,20 +1046,19 @@ snd_azf3328_codec_setfmt(struct snd_azf3328 *chip,
1014 DMA_SOMETHING_ELSE 1046 DMA_SOMETHING_ELSE
1015 ); 1047 );
1016 1048
1017 spin_unlock_irqrestore(&chip->reg_lock, flags); 1049 spin_unlock_irqrestore(codec->lock, flags);
1018 snd_azf3328_dbgcallleave(); 1050 snd_azf3328_dbgcallleave();
1019} 1051}
1020 1052
1021static inline void 1053static inline void
1022snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip, 1054snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328_codec_data *codec
1023 enum snd_azf3328_codec_type codec_type
1024) 1055)
1025{ 1056{
1026 /* choose lowest frequency for low power consumption. 1057 /* choose lowest frequency for low power consumption.
1027 * While this will cause louder noise due to rather coarse frequency, 1058 * While this will cause louder noise due to rather coarse frequency,
1028 * it should never matter since output should always 1059 * it should never matter since output should always
1029 * get disabled properly when idle anyway. */ 1060 * get disabled properly when idle anyway. */
1030 snd_azf3328_codec_setfmt(chip, codec_type, AZF_FREQ_4000, 8, 1); 1061 snd_azf3328_codec_setfmt(codec, AZF_FREQ_4000, 8, 1);
1031} 1062}
1032 1063
1033static void 1064static void
@@ -1101,69 +1132,87 @@ snd_azf3328_ctrl_codec_activity(struct snd_azf3328 *chip,
1101 /* ...and adjust clock, too 1132 /* ...and adjust clock, too
1102 * (reduce noise and power consumption) */ 1133 * (reduce noise and power consumption) */
1103 if (!enable) 1134 if (!enable)
1104 snd_azf3328_codec_setfmt_lowpower( 1135 snd_azf3328_codec_setfmt_lowpower(codec);
1105 chip,
1106 codec_type
1107 );
1108 codec->running = enable; 1136 codec->running = enable;
1109 } 1137 }
1110} 1138}
1111 1139
1112static void 1140static void
1113snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip, 1141snd_azf3328_codec_setdmaa(struct snd_azf3328_codec_data *codec,
1114 enum snd_azf3328_codec_type codec_type,
1115 unsigned long addr, 1142 unsigned long addr,
1116 unsigned int count, 1143 unsigned int period_bytes,
1117 unsigned int size 1144 unsigned int buffer_bytes
1118) 1145)
1119{ 1146{
1120 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1121 snd_azf3328_dbgcallenter(); 1147 snd_azf3328_dbgcallenter();
1148 WARN_ONCE(period_bytes & 1, "odd period length!?\n");
1149 WARN_ONCE(buffer_bytes != 2 * period_bytes,
1150 "missed our input expectations! %u vs. %u\n",
1151 buffer_bytes, period_bytes);
1122 if (!codec->running) { 1152 if (!codec->running) {
1123 /* AZF3328 uses a two buffer pointer DMA transfer approach */ 1153 /* AZF3328 uses a two buffer pointer DMA transfer approach */
1124 1154
1125 unsigned long flags, addr_area2; 1155 unsigned long flags;
1126 1156
1127 /* width 32bit (prevent overflow): */ 1157 /* width 32bit (prevent overflow): */
1128 u32 count_areas, lengths; 1158 u32 area_length;
1159 struct codec_setup_io {
1160 u32 dma_start_1;
1161 u32 dma_start_2;
1162 u32 dma_lengths;
1163 } __attribute__((packed)) setup_io;
1164
1165 area_length = buffer_bytes/2;
1166
1167 setup_io.dma_start_1 = addr;
1168 setup_io.dma_start_2 = addr+area_length;
1129 1169
1130 count_areas = size/2; 1170 snd_azf3328_dbgcodec(
1131 addr_area2 = addr+count_areas; 1171 "setdma: buffers %08x[%u] / %08x[%u], %u, %u\n",
1132 snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n", 1172 setup_io.dma_start_1, area_length,
1133 addr, count_areas, addr_area2, count_areas); 1173 setup_io.dma_start_2, area_length,
1174 period_bytes, buffer_bytes);
1134 1175
1135 count_areas--; /* max. index */ 1176 /* Hmm, are we really supposed to decrement this by 1??
1177 Most definitely certainly not: configuring full length does
1178 work properly (i.e. likely better), and BTW we
1179 violated possibly differing frame sizes with this...
1180
1181 area_length--; |* max. index *|
1182 */
1136 1183
1137 /* build combined I/O buffer length word */ 1184 /* build combined I/O buffer length word */
1138 lengths = (count_areas << 16) | (count_areas); 1185 setup_io.dma_lengths = (area_length << 16) | (area_length);
1139 spin_lock_irqsave(&chip->reg_lock, flags); 1186
1140 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_1, addr); 1187 spin_lock_irqsave(codec->lock, flags);
1141 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_START_2, 1188 snd_azf3328_codec_outl_multi(
1142 addr_area2); 1189 codec, IDX_IO_CODEC_DMA_START_1, &setup_io, 3
1143 snd_azf3328_codec_outl(codec, IDX_IO_CODEC_DMA_LENGTHS, 1190 );
1144 lengths); 1191 spin_unlock_irqrestore(codec->lock, flags);
1145 spin_unlock_irqrestore(&chip->reg_lock, flags);
1146 } 1192 }
1147 snd_azf3328_dbgcallleave(); 1193 snd_azf3328_dbgcallleave();
1148} 1194}
1149 1195
1150static int 1196static int
1151snd_azf3328_codec_prepare(struct snd_pcm_substream *substream) 1197snd_azf3328_pcm_prepare(struct snd_pcm_substream *substream)
1152{ 1198{
1153#if 0
1154 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1155 struct snd_pcm_runtime *runtime = substream->runtime; 1199 struct snd_pcm_runtime *runtime = substream->runtime;
1200 struct snd_azf3328_codec_data *codec = runtime->private_data;
1201#if 0
1156 unsigned int size = snd_pcm_lib_buffer_bytes(substream); 1202 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1157 unsigned int count = snd_pcm_lib_period_bytes(substream); 1203 unsigned int count = snd_pcm_lib_period_bytes(substream);
1158#endif 1204#endif
1159 1205
1160 snd_azf3328_dbgcallenter(); 1206 snd_azf3328_dbgcallenter();
1207
1208 codec->dma_base = runtime->dma_addr;
1209
1161#if 0 1210#if 0
1162 snd_azf3328_codec_setfmt(chip, AZF_CODEC_..., 1211 snd_azf3328_codec_setfmt(codec,
1163 runtime->rate, 1212 runtime->rate,
1164 snd_pcm_format_width(runtime->format), 1213 snd_pcm_format_width(runtime->format),
1165 runtime->channels); 1214 runtime->channels);
1166 snd_azf3328_codec_setdmaa(chip, AZF_CODEC_..., 1215 snd_azf3328_codec_setdmaa(codec,
1167 runtime->dma_addr, count, size); 1216 runtime->dma_addr, count, size);
1168#endif 1217#endif
1169 snd_azf3328_dbgcallleave(); 1218 snd_azf3328_dbgcallleave();
@@ -1171,24 +1220,23 @@ snd_azf3328_codec_prepare(struct snd_pcm_substream *substream)
1171} 1220}
1172 1221
1173static int 1222static int
1174snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, 1223snd_azf3328_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
1175 struct snd_pcm_substream *substream, int cmd)
1176{ 1224{
1177 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1225 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1178 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1179 struct snd_pcm_runtime *runtime = substream->runtime; 1226 struct snd_pcm_runtime *runtime = substream->runtime;
1227 struct snd_azf3328_codec_data *codec = runtime->private_data;
1180 int result = 0; 1228 int result = 0;
1181 u16 flags1; 1229 u16 flags1;
1182 bool previously_muted = 0; 1230 bool previously_muted = 0;
1183 bool is_playback_codec = (AZF_CODEC_PLAYBACK == codec_type); 1231 bool is_main_mixer_playback_codec = (AZF_CODEC_PLAYBACK == codec->type);
1184 1232
1185 snd_azf3328_dbgcalls("snd_azf3328_codec_trigger cmd %d\n", cmd); 1233 snd_azf3328_dbgcalls("snd_azf3328_pcm_trigger cmd %d\n", cmd);
1186 1234
1187 switch (cmd) { 1235 switch (cmd) {
1188 case SNDRV_PCM_TRIGGER_START: 1236 case SNDRV_PCM_TRIGGER_START:
1189 snd_azf3328_dbgcodec("START %s\n", codec->name); 1237 snd_azf3328_dbgcodec("START %s\n", codec->name);
1190 1238
1191 if (is_playback_codec) { 1239 if (is_main_mixer_playback_codec) {
1192 /* mute WaveOut (avoid clicking during setup) */ 1240 /* mute WaveOut (avoid clicking during setup) */
1193 previously_muted = 1241 previously_muted =
1194 snd_azf3328_mixer_set_mute( 1242 snd_azf3328_mixer_set_mute(
@@ -1196,12 +1244,12 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1196 ); 1244 );
1197 } 1245 }
1198 1246
1199 snd_azf3328_codec_setfmt(chip, codec_type, 1247 snd_azf3328_codec_setfmt(codec,
1200 runtime->rate, 1248 runtime->rate,
1201 snd_pcm_format_width(runtime->format), 1249 snd_pcm_format_width(runtime->format),
1202 runtime->channels); 1250 runtime->channels);
1203 1251
1204 spin_lock(&chip->reg_lock); 1252 spin_lock(codec->lock);
1205 /* first, remember current value: */ 1253 /* first, remember current value: */
1206 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS); 1254 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1207 1255
@@ -1211,14 +1259,14 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1211 1259
1212 /* FIXME: clear interrupts or what??? */ 1260 /* FIXME: clear interrupts or what??? */
1213 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff); 1261 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_IRQTYPE, 0xffff);
1214 spin_unlock(&chip->reg_lock); 1262 spin_unlock(codec->lock);
1215 1263
1216 snd_azf3328_codec_setdmaa(chip, codec_type, runtime->dma_addr, 1264 snd_azf3328_codec_setdmaa(codec, runtime->dma_addr,
1217 snd_pcm_lib_period_bytes(substream), 1265 snd_pcm_lib_period_bytes(substream),
1218 snd_pcm_lib_buffer_bytes(substream) 1266 snd_pcm_lib_buffer_bytes(substream)
1219 ); 1267 );
1220 1268
1221 spin_lock(&chip->reg_lock); 1269 spin_lock(codec->lock);
1222#ifdef WIN9X 1270#ifdef WIN9X
1223 /* FIXME: enable playback/recording??? */ 1271 /* FIXME: enable playback/recording??? */
1224 flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2; 1272 flags1 |= DMA_RUN_SOMETHING1 | DMA_RUN_SOMETHING2;
@@ -1242,10 +1290,10 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1242 DMA_EPILOGUE_SOMETHING | 1290 DMA_EPILOGUE_SOMETHING |
1243 DMA_SOMETHING_ELSE); 1291 DMA_SOMETHING_ELSE);
1244#endif 1292#endif
1245 spin_unlock(&chip->reg_lock); 1293 spin_unlock(codec->lock);
1246 snd_azf3328_ctrl_codec_activity(chip, codec_type, 1); 1294 snd_azf3328_ctrl_codec_activity(chip, codec->type, 1);
1247 1295
1248 if (is_playback_codec) { 1296 if (is_main_mixer_playback_codec) {
1249 /* now unmute WaveOut */ 1297 /* now unmute WaveOut */
1250 if (!previously_muted) 1298 if (!previously_muted)
1251 snd_azf3328_mixer_set_mute( 1299 snd_azf3328_mixer_set_mute(
@@ -1258,19 +1306,19 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1258 case SNDRV_PCM_TRIGGER_RESUME: 1306 case SNDRV_PCM_TRIGGER_RESUME:
1259 snd_azf3328_dbgcodec("RESUME %s\n", codec->name); 1307 snd_azf3328_dbgcodec("RESUME %s\n", codec->name);
1260 /* resume codec if we were active */ 1308 /* resume codec if we were active */
1261 spin_lock(&chip->reg_lock); 1309 spin_lock(codec->lock);
1262 if (codec->running) 1310 if (codec->running)
1263 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, 1311 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS,
1264 snd_azf3328_codec_inw( 1312 snd_azf3328_codec_inw(
1265 codec, IDX_IO_CODEC_DMA_FLAGS 1313 codec, IDX_IO_CODEC_DMA_FLAGS
1266 ) | DMA_RESUME 1314 ) | DMA_RESUME
1267 ); 1315 );
1268 spin_unlock(&chip->reg_lock); 1316 spin_unlock(codec->lock);
1269 break; 1317 break;
1270 case SNDRV_PCM_TRIGGER_STOP: 1318 case SNDRV_PCM_TRIGGER_STOP:
1271 snd_azf3328_dbgcodec("STOP %s\n", codec->name); 1319 snd_azf3328_dbgcodec("STOP %s\n", codec->name);
1272 1320
1273 if (is_playback_codec) { 1321 if (is_main_mixer_playback_codec) {
1274 /* mute WaveOut (avoid clicking during setup) */ 1322 /* mute WaveOut (avoid clicking during setup) */
1275 previously_muted = 1323 previously_muted =
1276 snd_azf3328_mixer_set_mute( 1324 snd_azf3328_mixer_set_mute(
@@ -1278,7 +1326,7 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1278 ); 1326 );
1279 } 1327 }
1280 1328
1281 spin_lock(&chip->reg_lock); 1329 spin_lock(codec->lock);
1282 /* first, remember current value: */ 1330 /* first, remember current value: */
1283 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS); 1331 flags1 = snd_azf3328_codec_inw(codec, IDX_IO_CODEC_DMA_FLAGS);
1284 1332
@@ -1293,10 +1341,10 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1293 1341
1294 flags1 &= ~DMA_RUN_SOMETHING1; 1342 flags1 &= ~DMA_RUN_SOMETHING1;
1295 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1); 1343 snd_azf3328_codec_outw(codec, IDX_IO_CODEC_DMA_FLAGS, flags1);
1296 spin_unlock(&chip->reg_lock); 1344 spin_unlock(codec->lock);
1297 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); 1345 snd_azf3328_ctrl_codec_activity(chip, codec->type, 0);
1298 1346
1299 if (is_playback_codec) { 1347 if (is_main_mixer_playback_codec) {
1300 /* now unmute WaveOut */ 1348 /* now unmute WaveOut */
1301 if (!previously_muted) 1349 if (!previously_muted)
1302 snd_azf3328_mixer_set_mute( 1350 snd_azf3328_mixer_set_mute(
@@ -1330,67 +1378,29 @@ snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type,
1330 return result; 1378 return result;
1331} 1379}
1332 1380
1333static int
1334snd_azf3328_codec_playback_trigger(struct snd_pcm_substream *substream, int cmd)
1335{
1336 return snd_azf3328_codec_trigger(AZF_CODEC_PLAYBACK, substream, cmd);
1337}
1338
1339static int
1340snd_azf3328_codec_capture_trigger(struct snd_pcm_substream *substream, int cmd)
1341{
1342 return snd_azf3328_codec_trigger(AZF_CODEC_CAPTURE, substream, cmd);
1343}
1344
1345static int
1346snd_azf3328_codec_i2s_out_trigger(struct snd_pcm_substream *substream, int cmd)
1347{
1348 return snd_azf3328_codec_trigger(AZF_CODEC_I2S_OUT, substream, cmd);
1349}
1350
1351static snd_pcm_uframes_t 1381static snd_pcm_uframes_t
1352snd_azf3328_codec_pointer(struct snd_pcm_substream *substream, 1382snd_azf3328_pcm_pointer(struct snd_pcm_substream *substream
1353 enum snd_azf3328_codec_type codec_type
1354) 1383)
1355{ 1384{
1356 const struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1385 const struct snd_azf3328_codec_data *codec =
1357 const struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type]; 1386 substream->runtime->private_data;
1358 unsigned long bufptr, result; 1387 unsigned long result;
1359 snd_pcm_uframes_t frmres; 1388 snd_pcm_uframes_t frmres;
1360 1389
1361#ifdef QUERY_HARDWARE
1362 bufptr = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1363#else
1364 bufptr = substream->runtime->dma_addr;
1365#endif
1366 result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS); 1390 result = snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_CURRPOS);
1367 1391
1368 /* calculate offset */ 1392 /* calculate offset */
1369 result -= bufptr; 1393#ifdef QUERY_HARDWARE
1394 result -= snd_azf3328_codec_inl(codec, IDX_IO_CODEC_DMA_START_1);
1395#else
1396 result -= codec->dma_base;
1397#endif
1370 frmres = bytes_to_frames( substream->runtime, result); 1398 frmres = bytes_to_frames( substream->runtime, result);
1371 snd_azf3328_dbgcodec("%s @ 0x%8lx, frames %8ld\n", 1399 snd_azf3328_dbgcodec("%08li %s @ 0x%8lx, frames %8ld\n",
1372 codec->name, result, frmres); 1400 jiffies, codec->name, result, frmres);
1373 return frmres; 1401 return frmres;
1374} 1402}
1375 1403
1376static snd_pcm_uframes_t
1377snd_azf3328_codec_playback_pointer(struct snd_pcm_substream *substream)
1378{
1379 return snd_azf3328_codec_pointer(substream, AZF_CODEC_PLAYBACK);
1380}
1381
1382static snd_pcm_uframes_t
1383snd_azf3328_codec_capture_pointer(struct snd_pcm_substream *substream)
1384{
1385 return snd_azf3328_codec_pointer(substream, AZF_CODEC_CAPTURE);
1386}
1387
1388static snd_pcm_uframes_t
1389snd_azf3328_codec_i2s_out_pointer(struct snd_pcm_substream *substream)
1390{
1391 return snd_azf3328_codec_pointer(substream, AZF_CODEC_I2S_OUT);
1392}
1393
1394/******************************************************************/ 1404/******************************************************************/
1395 1405
1396#ifdef SUPPORT_GAMEPORT 1406#ifdef SUPPORT_GAMEPORT
@@ -1532,7 +1542,7 @@ snd_azf3328_gameport_cooked_read(struct gameport *gameport,
1532 } 1542 }
1533 } 1543 }
1534 1544
1535 /* trigger next axes sampling, to be evaluated the next time we 1545 /* trigger next sampling of axes, to be evaluated the next time we
1536 * enter this function */ 1546 * enter this function */
1537 1547
1538 /* for some very, very strange reason we cannot enable 1548 /* for some very, very strange reason we cannot enable
@@ -1624,29 +1634,29 @@ snd_azf3328_irq_log_unknown_type(u8 which)
1624} 1634}
1625 1635
1626static inline void 1636static inline void
1627snd_azf3328_codec_interrupt(struct snd_azf3328 *chip, u8 status) 1637snd_azf3328_pcm_interrupt(const struct snd_azf3328_codec_data *first_codec,
1638 u8 status
1639)
1628{ 1640{
1629 u8 which; 1641 u8 which;
1630 enum snd_azf3328_codec_type codec_type; 1642 enum snd_azf3328_codec_type codec_type;
1631 const struct snd_azf3328_codec_data *codec; 1643 const struct snd_azf3328_codec_data *codec = first_codec;
1632 1644
1633 for (codec_type = AZF_CODEC_PLAYBACK; 1645 for (codec_type = AZF_CODEC_PLAYBACK;
1634 codec_type <= AZF_CODEC_I2S_OUT; 1646 codec_type <= AZF_CODEC_I2S_OUT;
1635 ++codec_type) { 1647 ++codec_type, ++codec) {
1636 1648
1637 /* skip codec if there's no interrupt for it */ 1649 /* skip codec if there's no interrupt for it */
1638 if (!(status & (1 << codec_type))) 1650 if (!(status & (1 << codec_type)))
1639 continue; 1651 continue;
1640 1652
1641 codec = &chip->codecs[codec_type]; 1653 spin_lock(codec->lock);
1642
1643 spin_lock(&chip->reg_lock);
1644 which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE); 1654 which = snd_azf3328_codec_inb(codec, IDX_IO_CODEC_IRQTYPE);
1645 /* ack all IRQ types immediately */ 1655 /* ack all IRQ types immediately */
1646 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which); 1656 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_IRQTYPE, which);
1647 spin_unlock(&chip->reg_lock); 1657 spin_unlock(codec->lock);
1648 1658
1649 if ((chip->pcm[codec_type]) && (codec->substream)) { 1659 if (codec->substream) {
1650 snd_pcm_period_elapsed(codec->substream); 1660 snd_pcm_period_elapsed(codec->substream);
1651 snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n", 1661 snd_azf3328_dbgcodec("%s period done (#%x), @ %x\n",
1652 codec->name, 1662 codec->name,
@@ -1701,7 +1711,7 @@ snd_azf3328_interrupt(int irq, void *dev_id)
1701 } 1711 }
1702 1712
1703 if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT)) 1713 if (status & (IRQ_PLAYBACK|IRQ_RECORDING|IRQ_I2S_OUT))
1704 snd_azf3328_codec_interrupt(chip, status); 1714 snd_azf3328_pcm_interrupt(chip->codecs, status);
1705 1715
1706 if (status & IRQ_GAMEPORT) 1716 if (status & IRQ_GAMEPORT)
1707 snd_azf3328_gameport_interrupt(chip); 1717 snd_azf3328_gameport_interrupt(chip);
@@ -1789,101 +1799,85 @@ snd_azf3328_pcm_open(struct snd_pcm_substream *substream,
1789{ 1799{
1790 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1800 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream);
1791 struct snd_pcm_runtime *runtime = substream->runtime; 1801 struct snd_pcm_runtime *runtime = substream->runtime;
1802 struct snd_azf3328_codec_data *codec = &chip->codecs[codec_type];
1792 1803
1793 snd_azf3328_dbgcallenter(); 1804 snd_azf3328_dbgcallenter();
1794 chip->codecs[codec_type].substream = substream; 1805 codec->substream = substream;
1795 1806
1796 /* same parameters for all our codecs - at least we think so... */ 1807 /* same parameters for all our codecs - at least we think so... */
1797 runtime->hw = snd_azf3328_hardware; 1808 runtime->hw = snd_azf3328_hardware;
1798 1809
1799 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, 1810 snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1800 &snd_azf3328_hw_constraints_rates); 1811 &snd_azf3328_hw_constraints_rates);
1812 runtime->private_data = codec;
1801 snd_azf3328_dbgcallleave(); 1813 snd_azf3328_dbgcallleave();
1802 return 0; 1814 return 0;
1803} 1815}
1804 1816
1805static int 1817static int
1806snd_azf3328_playback_open(struct snd_pcm_substream *substream) 1818snd_azf3328_pcm_playback_open(struct snd_pcm_substream *substream)
1807{ 1819{
1808 return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK); 1820 return snd_azf3328_pcm_open(substream, AZF_CODEC_PLAYBACK);
1809} 1821}
1810 1822
1811static int 1823static int
1812snd_azf3328_capture_open(struct snd_pcm_substream *substream) 1824snd_azf3328_pcm_capture_open(struct snd_pcm_substream *substream)
1813{ 1825{
1814 return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE); 1826 return snd_azf3328_pcm_open(substream, AZF_CODEC_CAPTURE);
1815} 1827}
1816 1828
1817static int 1829static int
1818snd_azf3328_i2s_out_open(struct snd_pcm_substream *substream) 1830snd_azf3328_pcm_i2s_out_open(struct snd_pcm_substream *substream)
1819{ 1831{
1820 return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT); 1832 return snd_azf3328_pcm_open(substream, AZF_CODEC_I2S_OUT);
1821} 1833}
1822 1834
1823static int 1835static int
1824snd_azf3328_pcm_close(struct snd_pcm_substream *substream, 1836snd_azf3328_pcm_close(struct snd_pcm_substream *substream
1825 enum snd_azf3328_codec_type codec_type
1826) 1837)
1827{ 1838{
1828 struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); 1839 struct snd_azf3328_codec_data *codec =
1840 substream->runtime->private_data;
1829 1841
1830 snd_azf3328_dbgcallenter(); 1842 snd_azf3328_dbgcallenter();
1831 chip->codecs[codec_type].substream = NULL; 1843 codec->substream = NULL;
1832 snd_azf3328_dbgcallleave(); 1844 snd_azf3328_dbgcallleave();
1833 return 0; 1845 return 0;
1834} 1846}
1835 1847
1836static int
1837snd_azf3328_playback_close(struct snd_pcm_substream *substream)
1838{
1839 return snd_azf3328_pcm_close(substream, AZF_CODEC_PLAYBACK);
1840}
1841
1842static int
1843snd_azf3328_capture_close(struct snd_pcm_substream *substream)
1844{
1845 return snd_azf3328_pcm_close(substream, AZF_CODEC_CAPTURE);
1846}
1847
1848static int
1849snd_azf3328_i2s_out_close(struct snd_pcm_substream *substream)
1850{
1851 return snd_azf3328_pcm_close(substream, AZF_CODEC_I2S_OUT);
1852}
1853
1854/******************************************************************/ 1848/******************************************************************/
1855 1849
1856static struct snd_pcm_ops snd_azf3328_playback_ops = { 1850static struct snd_pcm_ops snd_azf3328_playback_ops = {
1857 .open = snd_azf3328_playback_open, 1851 .open = snd_azf3328_pcm_playback_open,
1858 .close = snd_azf3328_playback_close, 1852 .close = snd_azf3328_pcm_close,
1859 .ioctl = snd_pcm_lib_ioctl, 1853 .ioctl = snd_pcm_lib_ioctl,
1860 .hw_params = snd_azf3328_hw_params, 1854 .hw_params = snd_azf3328_hw_params,
1861 .hw_free = snd_azf3328_hw_free, 1855 .hw_free = snd_azf3328_hw_free,
1862 .prepare = snd_azf3328_codec_prepare, 1856 .prepare = snd_azf3328_pcm_prepare,
1863 .trigger = snd_azf3328_codec_playback_trigger, 1857 .trigger = snd_azf3328_pcm_trigger,
1864 .pointer = snd_azf3328_codec_playback_pointer 1858 .pointer = snd_azf3328_pcm_pointer
1865}; 1859};
1866 1860
1867static struct snd_pcm_ops snd_azf3328_capture_ops = { 1861static struct snd_pcm_ops snd_azf3328_capture_ops = {
1868 .open = snd_azf3328_capture_open, 1862 .open = snd_azf3328_pcm_capture_open,
1869 .close = snd_azf3328_capture_close, 1863 .close = snd_azf3328_pcm_close,
1870 .ioctl = snd_pcm_lib_ioctl, 1864 .ioctl = snd_pcm_lib_ioctl,
1871 .hw_params = snd_azf3328_hw_params, 1865 .hw_params = snd_azf3328_hw_params,
1872 .hw_free = snd_azf3328_hw_free, 1866 .hw_free = snd_azf3328_hw_free,
1873 .prepare = snd_azf3328_codec_prepare, 1867 .prepare = snd_azf3328_pcm_prepare,
1874 .trigger = snd_azf3328_codec_capture_trigger, 1868 .trigger = snd_azf3328_pcm_trigger,
1875 .pointer = snd_azf3328_codec_capture_pointer 1869 .pointer = snd_azf3328_pcm_pointer
1876}; 1870};
1877 1871
1878static struct snd_pcm_ops snd_azf3328_i2s_out_ops = { 1872static struct snd_pcm_ops snd_azf3328_i2s_out_ops = {
1879 .open = snd_azf3328_i2s_out_open, 1873 .open = snd_azf3328_pcm_i2s_out_open,
1880 .close = snd_azf3328_i2s_out_close, 1874 .close = snd_azf3328_pcm_close,
1881 .ioctl = snd_pcm_lib_ioctl, 1875 .ioctl = snd_pcm_lib_ioctl,
1882 .hw_params = snd_azf3328_hw_params, 1876 .hw_params = snd_azf3328_hw_params,
1883 .hw_free = snd_azf3328_hw_free, 1877 .hw_free = snd_azf3328_hw_free,
1884 .prepare = snd_azf3328_codec_prepare, 1878 .prepare = snd_azf3328_pcm_prepare,
1885 .trigger = snd_azf3328_codec_i2s_out_trigger, 1879 .trigger = snd_azf3328_pcm_trigger,
1886 .pointer = snd_azf3328_codec_i2s_out_pointer 1880 .pointer = snd_azf3328_pcm_pointer
1887}; 1881};
1888 1882
1889static int __devinit 1883static int __devinit
@@ -1966,7 +1960,7 @@ snd_azf3328_timer_start(struct snd_timer *timer)
1966 snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay); 1960 snd_azf3328_dbgtimer("delay was too low (%d)!\n", delay);
1967 delay = 49; /* minimum time is 49 ticks */ 1961 delay = 49; /* minimum time is 49 ticks */
1968 } 1962 }
1969 snd_azf3328_dbgtimer("setting timer countdown value %d, add COUNTDOWN|IRQ\n", delay); 1963 snd_azf3328_dbgtimer("setting timer countdown value %d\n", delay);
1970 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE; 1964 delay |= TIMER_COUNTDOWN_ENABLE | TIMER_IRQ_ENABLE;
1971 spin_lock_irqsave(&chip->reg_lock, flags); 1965 spin_lock_irqsave(&chip->reg_lock, flags);
1972 snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay); 1966 snd_azf3328_ctrl_outl(chip, IDX_IO_TIMER_VALUE, delay);
@@ -2180,6 +2174,7 @@ snd_azf3328_create(struct snd_card *card,
2180 }; 2174 };
2181 u8 dma_init; 2175 u8 dma_init;
2182 enum snd_azf3328_codec_type codec_type; 2176 enum snd_azf3328_codec_type codec_type;
2177 struct snd_azf3328_codec_data *codec_setup;
2183 2178
2184 *rchip = NULL; 2179 *rchip = NULL;
2185 2180
@@ -2217,15 +2212,23 @@ snd_azf3328_create(struct snd_card *card,
2217 chip->opl3_io = pci_resource_start(pci, 3); 2212 chip->opl3_io = pci_resource_start(pci, 3);
2218 chip->mixer_io = pci_resource_start(pci, 4); 2213 chip->mixer_io = pci_resource_start(pci, 4);
2219 2214
2220 chip->codecs[AZF_CODEC_PLAYBACK].io_base = 2215 codec_setup = &chip->codecs[AZF_CODEC_PLAYBACK];
2221 chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK; 2216 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_PLAYBACK;
2222 chip->codecs[AZF_CODEC_PLAYBACK].name = "PLAYBACK"; 2217 codec_setup->lock = &chip->reg_lock;
2223 chip->codecs[AZF_CODEC_CAPTURE].io_base = 2218 codec_setup->type = AZF_CODEC_PLAYBACK;
2224 chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE; 2219 codec_setup->name = "PLAYBACK";
2225 chip->codecs[AZF_CODEC_CAPTURE].name = "CAPTURE"; 2220
2226 chip->codecs[AZF_CODEC_I2S_OUT].io_base = 2221 codec_setup = &chip->codecs[AZF_CODEC_CAPTURE];
2227 chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT; 2222 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_CAPTURE;
2228 chip->codecs[AZF_CODEC_I2S_OUT].name = "I2S_OUT"; 2223 codec_setup->lock = &chip->reg_lock;
2224 codec_setup->type = AZF_CODEC_CAPTURE;
2225 codec_setup->name = "CAPTURE";
2226
2227 codec_setup = &chip->codecs[AZF_CODEC_I2S_OUT];
2228 codec_setup->io_base = chip->ctrl_io + AZF_IO_OFFS_CODEC_I2S_OUT;
2229 codec_setup->lock = &chip->reg_lock;
2230 codec_setup->type = AZF_CODEC_I2S_OUT;
2231 codec_setup->name = "I2S_OUT";
2229 2232
2230 if (request_irq(pci->irq, snd_azf3328_interrupt, 2233 if (request_irq(pci->irq, snd_azf3328_interrupt,
2231 IRQF_SHARED, card->shortname, chip)) { 2234 IRQF_SHARED, card->shortname, chip)) {
@@ -2257,15 +2260,15 @@ snd_azf3328_create(struct snd_card *card,
2257 struct snd_azf3328_codec_data *codec = 2260 struct snd_azf3328_codec_data *codec =
2258 &chip->codecs[codec_type]; 2261 &chip->codecs[codec_type];
2259 2262
2260 /* shutdown codecs to save power */ 2263 /* shutdown codecs to reduce power / noise */
2261 /* have ...ctrl_codec_activity() act properly */ 2264 /* have ...ctrl_codec_activity() act properly */
2262 codec->running = 1; 2265 codec->running = 1;
2263 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0); 2266 snd_azf3328_ctrl_codec_activity(chip, codec_type, 0);
2264 2267
2265 spin_lock_irq(&chip->reg_lock); 2268 spin_lock_irq(codec->lock);
2266 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS, 2269 snd_azf3328_codec_outb(codec, IDX_IO_CODEC_DMA_FLAGS,
2267 dma_init); 2270 dma_init);
2268 spin_unlock_irq(&chip->reg_lock); 2271 spin_unlock_irq(codec->lock);
2269 } 2272 }
2270 2273
2271 snd_card_set_dev(card, &pci->dev); 2274 snd_card_set_dev(card, &pci->dev);
@@ -2419,6 +2422,7 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2419 2422
2420 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2423 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2421 2424
2425 /* same pcm object for playback/capture */
2422 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]); 2426 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_PLAYBACK]);
2423 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]); 2427 snd_pcm_suspend_all(chip->pcm[AZF_CODEC_I2S_OUT]);
2424 2428
diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c
index 37e1b5df5ab8..2958a05b5293 100644
--- a/sound/pci/bt87x.c
+++ b/sound/pci/bt87x.c
@@ -637,15 +637,9 @@ static struct snd_kcontrol_new snd_bt87x_capture_boost = {
637static int snd_bt87x_capture_source_info(struct snd_kcontrol *kcontrol, 637static int snd_bt87x_capture_source_info(struct snd_kcontrol *kcontrol,
638 struct snd_ctl_elem_info *info) 638 struct snd_ctl_elem_info *info)
639{ 639{
640 static char *texts[3] = {"TV Tuner", "FM", "Mic/Line"}; 640 static const char *const texts[3] = {"TV Tuner", "FM", "Mic/Line"};
641 641
642 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 642 return snd_ctl_enum_info(info, 1, 3, texts);
643 info->count = 1;
644 info->value.enumerated.items = 3;
645 if (info->value.enumerated.item > 2)
646 info->value.enumerated.item = 2;
647 strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]);
648 return 0;
649} 643}
650 644
651static int snd_bt87x_capture_source_get(struct snd_kcontrol *kcontrol, 645static int snd_bt87x_capture_source_get(struct snd_kcontrol *kcontrol,
diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h
index f19c11077255..fc53b9bca26d 100644
--- a/sound/pci/ca0106/ca0106.h
+++ b/sound/pci/ca0106/ca0106.h
@@ -188,7 +188,7 @@
188#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ 188#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
189 /* PTR[5:0], Default: 0x0 */ 189 /* PTR[5:0], Default: 0x0 */
190#define PLAYBACK_UNKNOWN3 0x03 /* Not used ?? */ 190#define PLAYBACK_UNKNOWN3 0x03 /* Not used ?? */
191#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */ 191#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */
192 /* DMA[31:0], Default: 0x0 */ 192 /* DMA[31:0], Default: 0x0 */
193#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */ 193#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */
194 /* SIZE[31:16], Default: 0x0 */ 194 /* SIZE[31:16], Default: 0x0 */
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index d2d12c08f937..01b49388fafd 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1082,7 +1082,7 @@ snd_ca0106_pcm_pointer_capture(struct snd_pcm_substream *substream)
1082 struct snd_pcm_runtime *runtime = substream->runtime; 1082 struct snd_pcm_runtime *runtime = substream->runtime;
1083 struct snd_ca0106_pcm *epcm = runtime->private_data; 1083 struct snd_ca0106_pcm *epcm = runtime->private_data;
1084 snd_pcm_uframes_t ptr, ptr1, ptr2 = 0; 1084 snd_pcm_uframes_t ptr, ptr1, ptr2 = 0;
1085 int channel = channel=epcm->channel_id; 1085 int channel = epcm->channel_id;
1086 1086
1087 if (!epcm->running) 1087 if (!epcm->running)
1088 return 0; 1088 return 0;
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 329968edca9b..b5bb036ef73c 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -2507,14 +2507,12 @@ static int snd_cmipci_line_in_mode_info(struct snd_kcontrol *kcontrol,
2507 struct snd_ctl_elem_info *uinfo) 2507 struct snd_ctl_elem_info *uinfo)
2508{ 2508{
2509 struct cmipci *cm = snd_kcontrol_chip(kcontrol); 2509 struct cmipci *cm = snd_kcontrol_chip(kcontrol);
2510 static char *texts[3] = { "Line-In", "Rear Output", "Bass Output" }; 2510 static const char *const texts[3] = {
2511 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2511 "Line-In", "Rear Output", "Bass Output"
2512 uinfo->count = 1; 2512 };
2513 uinfo->value.enumerated.items = cm->chip_version >= 39 ? 3 : 2; 2513
2514 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 2514 return snd_ctl_enum_info(uinfo, 1,
2515 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; 2515 cm->chip_version >= 39 ? 3 : 2, texts);
2516 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2517 return 0;
2518} 2516}
2519 2517
2520static inline unsigned int get_line_in_mode(struct cmipci *cm) 2518static inline unsigned int get_line_in_mode(struct cmipci *cm)
@@ -2564,14 +2562,9 @@ static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol,
2564static int snd_cmipci_mic_in_mode_info(struct snd_kcontrol *kcontrol, 2562static int snd_cmipci_mic_in_mode_info(struct snd_kcontrol *kcontrol,
2565 struct snd_ctl_elem_info *uinfo) 2563 struct snd_ctl_elem_info *uinfo)
2566{ 2564{
2567 static char *texts[2] = { "Mic-In", "Center/LFE Output" }; 2565 static const char *const texts[2] = { "Mic-In", "Center/LFE Output" };
2568 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2566
2569 uinfo->count = 1; 2567 return snd_ctl_enum_info(uinfo, 1, 2, texts);
2570 uinfo->value.enumerated.items = 2;
2571 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2572 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2573 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2574 return 0;
2575} 2568}
2576 2569
2577static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol, 2570static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol,
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
index a3301cc4ab82..185b00088320 100644
--- a/sound/pci/cs5535audio/cs5535audio_pm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pm.c
@@ -90,12 +90,7 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
90 int i; 90 int i;
91 91
92 pci_set_power_state(pci, PCI_D0); 92 pci_set_power_state(pci, PCI_D0);
93 if (pci_restore_state(pci) < 0) { 93 pci_restore_state(pci);
94 printk(KERN_ERR "cs5535audio: pci_restore_state failed, "
95 "disabling device\n");
96 snd_card_disconnect(card);
97 return -EIO;
98 }
99 if (pci_enable_device(pci) < 0) { 94 if (pci_enable_device(pci) < 0) {
100 printk(KERN_ERR "cs5535audio: pci_enable_device failed, " 95 printk(KERN_ERR "cs5535audio: pci_enable_device failed, "
101 "disabling device\n"); 96 "disabling device\n");
diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c
index df47f738098d..0c701e4ec8a5 100644
--- a/sound/pci/emu10k1/emu10k1x.c
+++ b/sound/pci/emu10k1/emu10k1x.c
@@ -114,7 +114,7 @@ MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard.");
114 */ 114 */
115#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */ 115#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
116#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ 116#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
117#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */ 117#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */
118#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size */ 118#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size */
119#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Sample currently in DAC */ 119#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Sample currently in DAC */
120#define PLAYBACK_UNKNOWN1 0x07 120#define PLAYBACK_UNKNOWN1 0x07
diff --git a/sound/pci/emu10k1/p16v.h b/sound/pci/emu10k1/p16v.h
index 153214940336..00f4817533b1 100644
--- a/sound/pci/emu10k1/p16v.h
+++ b/sound/pci/emu10k1/p16v.h
@@ -96,7 +96,7 @@
96#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */ 96#define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */
97#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ 97#define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */
98#define PLAYBACK_UNKNOWN3 0x03 /* Not used */ 98#define PLAYBACK_UNKNOWN3 0x03 /* Not used */
99#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */ 99#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */
100#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */ 100#define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */
101#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */ 101#define PLAYBACK_POINTER 0x06 /* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */
102#define PLAYBACK_FIFO_END_ADDRESS 0x07 /* Playback FIFO end address */ 102#define PLAYBACK_FIFO_END_ADDRESS 0x07 /* Playback FIFO end address */
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 23a58f0d6cb9..7c17f45d876d 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -220,7 +220,7 @@ MODULE_PARM_DESC(joystick, "Enable joystick.");
220#define RINGB_EN_2CODEC 0x0020 220#define RINGB_EN_2CODEC 0x0020
221#define RINGB_SING_BIT_DUAL 0x0040 221#define RINGB_SING_BIT_DUAL 0x0040
222 222
223/* ****Port Adresses**** */ 223/* ****Port Addresses**** */
224 224
225/* Write & Read */ 225/* Write & Read */
226#define ESM_INDEX 0x02 226#define ESM_INDEX 0x02
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 644e3f14f8ca..ae5c5d5e4b7c 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1919,6 +1919,16 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1919} 1919}
1920EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); 1920EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
1921 1921
1922static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name)
1923{
1924 int idx;
1925 for (idx = 0; idx < 16; idx++) { /* 16 ctlrs should be large enough */
1926 if (!_snd_hda_find_mixer_ctl(codec, name, idx))
1927 return idx;
1928 }
1929 return -EBUSY;
1930}
1931
1922/** 1932/**
1923 * snd_hda_ctl_add - Add a control element and assign to the codec 1933 * snd_hda_ctl_add - Add a control element and assign to the codec
1924 * @codec: HD-audio codec 1934 * @codec: HD-audio codec
@@ -2124,10 +2134,10 @@ int snd_hda_codec_reset(struct hda_codec *codec)
2124 * This function returns zero if successful or a negative error code. 2134 * This function returns zero if successful or a negative error code.
2125 */ 2135 */
2126int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 2136int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
2127 unsigned int *tlv, const char **slaves) 2137 unsigned int *tlv, const char * const *slaves)
2128{ 2138{
2129 struct snd_kcontrol *kctl; 2139 struct snd_kcontrol *kctl;
2130 const char **s; 2140 const char * const *s;
2131 int err; 2141 int err;
2132 2142
2133 for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) 2143 for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++)
@@ -2654,8 +2664,6 @@ static struct snd_kcontrol_new dig_mixes[] = {
2654 { } /* end */ 2664 { } /* end */
2655}; 2665};
2656 2666
2657#define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */
2658
2659/** 2667/**
2660 * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls 2668 * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
2661 * @codec: the HDA codec 2669 * @codec: the HDA codec
@@ -2673,12 +2681,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
2673 struct snd_kcontrol_new *dig_mix; 2681 struct snd_kcontrol_new *dig_mix;
2674 int idx; 2682 int idx;
2675 2683
2676 for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { 2684 idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch");
2677 if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch", 2685 if (idx < 0) {
2678 idx))
2679 break;
2680 }
2681 if (idx >= SPDIF_MAX_IDX) {
2682 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); 2686 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
2683 return -EBUSY; 2687 return -EBUSY;
2684 } 2688 }
@@ -2829,12 +2833,8 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
2829 struct snd_kcontrol_new *dig_mix; 2833 struct snd_kcontrol_new *dig_mix;
2830 int idx; 2834 int idx;
2831 2835
2832 for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { 2836 idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch");
2833 if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch", 2837 if (idx < 0) {
2834 idx))
2835 break;
2836 }
2837 if (idx >= SPDIF_MAX_IDX) {
2838 printk(KERN_ERR "hda_codec: too many IEC958 inputs\n"); 2838 printk(KERN_ERR "hda_codec: too many IEC958 inputs\n");
2839 return -EBUSY; 2839 return -EBUSY;
2840 } 2840 }
@@ -3689,7 +3689,7 @@ EXPORT_SYMBOL_HDA(snd_hda_build_pcms);
3689 * If no entries are matching, the function returns a negative value. 3689 * If no entries are matching, the function returns a negative value.
3690 */ 3690 */
3691int snd_hda_check_board_config(struct hda_codec *codec, 3691int snd_hda_check_board_config(struct hda_codec *codec,
3692 int num_configs, const char **models, 3692 int num_configs, const char * const *models,
3693 const struct snd_pci_quirk *tbl) 3693 const struct snd_pci_quirk *tbl)
3694{ 3694{
3695 if (codec->modelname && models) { 3695 if (codec->modelname && models) {
@@ -3753,7 +3753,7 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
3753 * If no entries are matching, the function returns a negative value. 3753 * If no entries are matching, the function returns a negative value.
3754 */ 3754 */
3755int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, 3755int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
3756 int num_configs, const char **models, 3756 int num_configs, const char * const *models,
3757 const struct snd_pci_quirk *tbl) 3757 const struct snd_pci_quirk *tbl)
3758{ 3758{
3759 const struct snd_pci_quirk *q; 3759 const struct snd_pci_quirk *q;
@@ -3808,21 +3808,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
3808 3808
3809 for (; knew->name; knew++) { 3809 for (; knew->name; knew++) {
3810 struct snd_kcontrol *kctl; 3810 struct snd_kcontrol *kctl;
3811 int addr = 0, idx = 0;
3811 if (knew->iface == -1) /* skip this codec private value */ 3812 if (knew->iface == -1) /* skip this codec private value */
3812 continue; 3813 continue;
3813 kctl = snd_ctl_new1(knew, codec); 3814 for (;;) {
3814 if (!kctl)
3815 return -ENOMEM;
3816 err = snd_hda_ctl_add(codec, 0, kctl);
3817 if (err < 0) {
3818 if (!codec->addr)
3819 return err;
3820 kctl = snd_ctl_new1(knew, codec); 3815 kctl = snd_ctl_new1(knew, codec);
3821 if (!kctl) 3816 if (!kctl)
3822 return -ENOMEM; 3817 return -ENOMEM;
3823 kctl->id.device = codec->addr; 3818 if (addr > 0)
3819 kctl->id.device = addr;
3820 if (idx > 0)
3821 kctl->id.index = idx;
3824 err = snd_hda_ctl_add(codec, 0, kctl); 3822 err = snd_hda_ctl_add(codec, 0, kctl);
3825 if (err < 0) 3823 if (!err)
3824 break;
3825 /* try first with another device index corresponding to
3826 * the codec addr; if it still fails (or it's the
3827 * primary codec), then try another control index
3828 */
3829 if (!addr && codec->addr)
3830 addr = codec->addr;
3831 else if (!idx && !knew->index) {
3832 idx = find_empty_mixer_ctl_idx(codec,
3833 knew->name);
3834 if (idx <= 0)
3835 return err;
3836 } else
3826 return err; 3837 return err;
3827 } 3838 }
3828 } 3839 }
@@ -4560,6 +4571,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4560 } 4571 }
4561 memset(cfg->hp_pins + cfg->hp_outs, 0, 4572 memset(cfg->hp_pins + cfg->hp_outs, 0,
4562 sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs)); 4573 sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs));
4574 if (!cfg->hp_outs)
4575 cfg->line_out_type = AUTO_PIN_HP_OUT;
4576
4563 } 4577 }
4564 4578
4565 /* sort by sequence */ 4579 /* sort by sequence */
@@ -4676,7 +4690,7 @@ const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin,
4676 int check_location) 4690 int check_location)
4677{ 4691{
4678 unsigned int def_conf; 4692 unsigned int def_conf;
4679 static const char *mic_names[] = { 4693 static const char * const mic_names[] = {
4680 "Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic", 4694 "Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic",
4681 }; 4695 };
4682 int attr; 4696 int attr;
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c
index cb0c23a6b473..4a663471dadc 100644
--- a/sound/pci/hda/hda_eld.c
+++ b/sound/pci/hda/hda_eld.c
@@ -189,6 +189,9 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
189 a->channels = GRAB_BITS(buf, 0, 0, 3); 189 a->channels = GRAB_BITS(buf, 0, 0, 3);
190 a->channels++; 190 a->channels++;
191 191
192 a->sample_bits = 0;
193 a->max_bitrate = 0;
194
192 a->format = GRAB_BITS(buf, 0, 3, 4); 195 a->format = GRAB_BITS(buf, 0, 3, 4);
193 switch (a->format) { 196 switch (a->format) {
194 case AUDIO_CODING_TYPE_REF_STREAM_HEADER: 197 case AUDIO_CODING_TYPE_REF_STREAM_HEADER:
@@ -198,7 +201,6 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a,
198 201
199 case AUDIO_CODING_TYPE_LPCM: 202 case AUDIO_CODING_TYPE_LPCM:
200 val = GRAB_BITS(buf, 2, 0, 3); 203 val = GRAB_BITS(buf, 2, 0, 3);
201 a->sample_bits = 0;
202 for (i = 0; i < 3; i++) 204 for (i = 0; i < 3; i++)
203 if (val & (1 << i)) 205 if (val & (1 << i))
204 a->sample_bits |= cea_sample_sizes[i + 1]; 206 a->sample_bits |= cea_sample_sizes[i + 1];
@@ -598,24 +600,19 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
598{ 600{
599 int i; 601 int i;
600 602
601 pcm->rates = 0; 603 /* assume basic audio support (the basic audio flag is not in ELD;
602 pcm->formats = 0; 604 * however, all audio capable sinks are required to support basic
603 pcm->maxbps = 0; 605 * audio) */
604 pcm->channels_min = -1; 606 pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
605 pcm->channels_max = 0; 607 pcm->formats = SNDRV_PCM_FMTBIT_S16_LE;
608 pcm->maxbps = 16;
609 pcm->channels_max = 2;
606 for (i = 0; i < eld->sad_count; i++) { 610 for (i = 0; i < eld->sad_count; i++) {
607 struct cea_sad *a = &eld->sad[i]; 611 struct cea_sad *a = &eld->sad[i];
608 pcm->rates |= a->rates; 612 pcm->rates |= a->rates;
609 if (a->channels < pcm->channels_min)
610 pcm->channels_min = a->channels;
611 if (a->channels > pcm->channels_max) 613 if (a->channels > pcm->channels_max)
612 pcm->channels_max = a->channels; 614 pcm->channels_max = a->channels;
613 if (a->format == AUDIO_CODING_TYPE_LPCM) { 615 if (a->format == AUDIO_CODING_TYPE_LPCM) {
614 if (a->sample_bits & AC_SUPPCM_BITS_16) {
615 pcm->formats |= SNDRV_PCM_FMTBIT_S16_LE;
616 if (pcm->maxbps < 16)
617 pcm->maxbps = 16;
618 }
619 if (a->sample_bits & AC_SUPPCM_BITS_20) { 616 if (a->sample_bits & AC_SUPPCM_BITS_20) {
620 pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; 617 pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE;
621 if (pcm->maxbps < 20) 618 if (pcm->maxbps < 20)
@@ -635,7 +632,6 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm,
635 /* restrict the parameters by the values the codec provides */ 632 /* restrict the parameters by the values the codec provides */
636 pcm->rates &= codec_pars->rates; 633 pcm->rates &= codec_pars->rates;
637 pcm->formats &= codec_pars->formats; 634 pcm->formats &= codec_pars->formats;
638 pcm->channels_min = max(pcm->channels_min, codec_pars->channels_min);
639 pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max); 635 pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max);
640 pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); 636 pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps);
641} 637}
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index fb0582f8d725..a63c54d9d767 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -762,7 +762,8 @@ static int check_existing_control(struct hda_codec *codec, const char *type, con
762/* 762/*
763 * build output mixer controls 763 * build output mixer controls
764 */ 764 */
765static int create_output_mixers(struct hda_codec *codec, const char **names) 765static int create_output_mixers(struct hda_codec *codec,
766 const char * const *names)
766{ 767{
767 struct hda_gspec *spec = codec->spec; 768 struct hda_gspec *spec = codec->spec;
768 int i, err; 769 int i, err;
@@ -780,8 +781,8 @@ static int create_output_mixers(struct hda_codec *codec, const char **names)
780static int build_output_controls(struct hda_codec *codec) 781static int build_output_controls(struct hda_codec *codec)
781{ 782{
782 struct hda_gspec *spec = codec->spec; 783 struct hda_gspec *spec = codec->spec;
783 static const char *types_speaker[] = { "Speaker", "Headphone" }; 784 static const char * const types_speaker[] = { "Speaker", "Headphone" };
784 static const char *types_line[] = { "Front", "Headphone" }; 785 static const char * const types_line[] = { "Front", "Headphone" };
785 786
786 switch (spec->pcm_vol_nodes) { 787 switch (spec->pcm_vol_nodes) {
787 case 1: 788 case 1:
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 21aa9b0e28f6..2e91a991eb15 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1235,7 +1235,8 @@ static int azx_setup_periods(struct azx *chip,
1235 pos_adj = 0; 1235 pos_adj = 0;
1236 } else { 1236 } else {
1237 ofs = setup_bdle(substream, azx_dev, 1237 ofs = setup_bdle(substream, azx_dev,
1238 &bdl, ofs, pos_adj, 1); 1238 &bdl, ofs, pos_adj,
1239 !substream->runtime->no_period_wakeup);
1239 if (ofs < 0) 1240 if (ofs < 0)
1240 goto error; 1241 goto error;
1241 } 1242 }
@@ -1247,7 +1248,8 @@ static int azx_setup_periods(struct azx *chip,
1247 period_bytes - pos_adj, 0); 1248 period_bytes - pos_adj, 0);
1248 else 1249 else
1249 ofs = setup_bdle(substream, azx_dev, &bdl, ofs, 1250 ofs = setup_bdle(substream, azx_dev, &bdl, ofs,
1250 period_bytes, 1); 1251 period_bytes,
1252 !substream->runtime->no_period_wakeup);
1251 if (ofs < 0) 1253 if (ofs < 0)
1252 goto error; 1254 goto error;
1253 } 1255 }
@@ -1515,7 +1517,8 @@ static struct snd_pcm_hardware azx_pcm_hw = {
1515 /* No full-resume yet implemented */ 1517 /* No full-resume yet implemented */
1516 /* SNDRV_PCM_INFO_RESUME |*/ 1518 /* SNDRV_PCM_INFO_RESUME |*/
1517 SNDRV_PCM_INFO_PAUSE | 1519 SNDRV_PCM_INFO_PAUSE |
1518 SNDRV_PCM_INFO_SYNC_START), 1520 SNDRV_PCM_INFO_SYNC_START |
1521 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP),
1519 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1522 .formats = SNDRV_PCM_FMTBIT_S16_LE,
1520 .rates = SNDRV_PCM_RATE_48000, 1523 .rates = SNDRV_PCM_RATE_48000,
1521 .rate_min = 48000, 1524 .rate_min = 48000,
@@ -2296,9 +2299,11 @@ static int azx_dev_free(struct snd_device *device)
2296 */ 2299 */
2297static struct snd_pci_quirk position_fix_list[] __devinitdata = { 2300static struct snd_pci_quirk position_fix_list[] __devinitdata = {
2298 SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB), 2301 SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB),
2302 SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB),
2299 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), 2303 SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB),
2300 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), 2304 SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB),
2301 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), 2305 SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB),
2306 SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB),
2302 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), 2307 SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB),
2303 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), 2308 SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB),
2304 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), 2309 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB),
@@ -2804,6 +2809,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
2804#endif 2809#endif
2805 /* Vortex86MX */ 2810 /* Vortex86MX */
2806 { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, 2811 { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC },
2812 /* VMware HDAudio */
2813 { PCI_DEVICE(0x15ad, 0x1977), .driver_data = AZX_DRIVER_GENERIC },
2807 /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */ 2814 /* AMD/ATI Generic, PCI class code and Vendor ID for HD Audio */
2808 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), 2815 { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID),
2809 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, 2816 .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 46bbefe2e4a9..3ab5e7a303db 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -140,7 +140,7 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
140struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, 140struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
141 const char *name); 141 const char *name);
142int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 142int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
143 unsigned int *tlv, const char **slaves); 143 unsigned int *tlv, const char * const *slaves);
144int snd_hda_codec_reset(struct hda_codec *codec); 144int snd_hda_codec_reset(struct hda_codec *codec);
145 145
146/* amp value bits */ 146/* amp value bits */
@@ -341,10 +341,10 @@ void snd_print_pcm_bits(int pcm, char *buf, int buflen);
341 * Misc 341 * Misc
342 */ 342 */
343int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, 343int snd_hda_check_board_config(struct hda_codec *codec, int num_configs,
344 const char **modelnames, 344 const char * const *modelnames,
345 const struct snd_pci_quirk *pci_list); 345 const struct snd_pci_quirk *pci_list);
346int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, 346int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
347 int num_configs, const char **models, 347 int num_configs, const char * const *models,
348 const struct snd_pci_quirk *tbl); 348 const struct snd_pci_quirk *tbl);
349int snd_hda_add_new_ctls(struct hda_codec *codec, 349int snd_hda_add_new_ctls(struct hda_codec *codec,
350 struct snd_kcontrol_new *knew); 350 struct snd_kcontrol_new *knew);
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index f025200f2a62..bfe74c2fb079 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -418,7 +418,7 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
418 418
419static const char *get_pwr_state(u32 state) 419static const char *get_pwr_state(u32 state)
420{ 420{
421 static const char *buf[4] = { 421 static const char * const buf[4] = {
422 "D0", "D1", "D2", "D3" 422 "D0", "D1", "D2", "D3"
423 }; 423 };
424 if (state < 4) 424 if (state < 4)
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index f7ff3f7ccb8e..8dabab798689 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -46,6 +46,9 @@ struct ad198x_spec {
46 unsigned int cur_eapd; 46 unsigned int cur_eapd;
47 unsigned int need_dac_fix; 47 unsigned int need_dac_fix;
48 48
49 hda_nid_t *alt_dac_nid;
50 struct hda_pcm_stream *stream_analog_alt_playback;
51
49 /* capture */ 52 /* capture */
50 unsigned int num_adc_nids; 53 unsigned int num_adc_nids;
51 hda_nid_t *adc_nids; 54 hda_nid_t *adc_nids;
@@ -81,8 +84,8 @@ struct ad198x_spec {
81#endif 84#endif
82 /* for virtual master */ 85 /* for virtual master */
83 hda_nid_t vmaster_nid; 86 hda_nid_t vmaster_nid;
84 const char **slave_vols; 87 const char * const *slave_vols;
85 const char **slave_sws; 88 const char * const *slave_sws;
86}; 89};
87 90
88/* 91/*
@@ -130,7 +133,7 @@ static int ad198x_init(struct hda_codec *codec)
130 return 0; 133 return 0;
131} 134}
132 135
133static const char *ad_slave_vols[] = { 136static const char * const ad_slave_vols[] = {
134 "Front Playback Volume", 137 "Front Playback Volume",
135 "Surround Playback Volume", 138 "Surround Playback Volume",
136 "Center Playback Volume", 139 "Center Playback Volume",
@@ -143,7 +146,7 @@ static const char *ad_slave_vols[] = {
143 NULL 146 NULL
144}; 147};
145 148
146static const char *ad_slave_sws[] = { 149static const char * const ad_slave_sws[] = {
147 "Front Playback Switch", 150 "Front Playback Switch",
148 "Surround Playback Switch", 151 "Surround Playback Switch",
149 "Center Playback Switch", 152 "Center Playback Switch",
@@ -156,6 +159,25 @@ static const char *ad_slave_sws[] = {
156 NULL 159 NULL
157}; 160};
158 161
162static const char * const ad1988_6stack_fp_slave_vols[] = {
163 "Front Playback Volume",
164 "Surround Playback Volume",
165 "Center Playback Volume",
166 "LFE Playback Volume",
167 "Side Playback Volume",
168 "IEC958 Playback Volume",
169 NULL
170};
171
172static const char * const ad1988_6stack_fp_slave_sws[] = {
173 "Front Playback Switch",
174 "Surround Playback Switch",
175 "Center Playback Switch",
176 "LFE Playback Switch",
177 "Side Playback Switch",
178 "IEC958 Playback Switch",
179 NULL
180};
159static void ad198x_free_kctls(struct hda_codec *codec); 181static void ad198x_free_kctls(struct hda_codec *codec);
160 182
161#ifdef CONFIG_SND_HDA_INPUT_BEEP 183#ifdef CONFIG_SND_HDA_INPUT_BEEP
@@ -309,6 +331,38 @@ static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
309 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 331 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
310} 332}
311 333
334static int ad198x_alt_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
335 struct hda_codec *codec,
336 unsigned int stream_tag,
337 unsigned int format,
338 struct snd_pcm_substream *substream)
339{
340 struct ad198x_spec *spec = codec->spec;
341 snd_hda_codec_setup_stream(codec, spec->alt_dac_nid[0], stream_tag,
342 0, format);
343 return 0;
344}
345
346static int ad198x_alt_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
347 struct hda_codec *codec,
348 struct snd_pcm_substream *substream)
349{
350 struct ad198x_spec *spec = codec->spec;
351 snd_hda_codec_cleanup_stream(codec, spec->alt_dac_nid[0]);
352 return 0;
353}
354
355static struct hda_pcm_stream ad198x_pcm_analog_alt_playback = {
356 .substreams = 1,
357 .channels_min = 2,
358 .channels_max = 2,
359 /* NID is set in ad198x_build_pcms */
360 .ops = {
361 .prepare = ad198x_alt_playback_pcm_prepare,
362 .cleanup = ad198x_alt_playback_pcm_cleanup
363 },
364};
365
312/* 366/*
313 * Digital out 367 * Digital out
314 */ 368 */
@@ -446,6 +500,17 @@ static int ad198x_build_pcms(struct hda_codec *codec)
446 } 500 }
447 } 501 }
448 502
503 if (spec->alt_dac_nid && spec->stream_analog_alt_playback) {
504 codec->num_pcms++;
505 info = spec->pcm_rec + 2;
506 info->name = "AD198x Headphone";
507 info->pcm_type = HDA_PCM_TYPE_AUDIO;
508 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
509 *spec->stream_analog_alt_playback;
510 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
511 spec->alt_dac_nid[0];
512 }
513
449 return 0; 514 return 0;
450} 515}
451 516
@@ -666,7 +731,7 @@ static struct snd_kcontrol_new ad1986a_mixers[] = {
666 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), 731 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 732 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
668 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 733 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
669 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), 734 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
670 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), 735 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
671 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), 736 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
672 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 737 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
@@ -729,7 +794,7 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
729 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), 794 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
730 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
731 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 796 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
732 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), 797 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
733 /* 798 /*
734 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), 799 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
735 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */ 800 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
@@ -775,7 +840,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
775 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 840 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
776 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 841 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
777 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 842 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
778 HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), 843 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
779 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 844 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
780 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), 845 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
781 { 846 {
@@ -1069,7 +1134,7 @@ enum {
1069 AD1986A_MODELS 1134 AD1986A_MODELS
1070}; 1135};
1071 1136
1072static const char *ad1986a_models[AD1986A_MODELS] = { 1137static const char * const ad1986a_models[AD1986A_MODELS] = {
1073 [AD1986A_6STACK] = "6stack", 1138 [AD1986A_6STACK] = "6stack",
1074 [AD1986A_3STACK] = "3stack", 1139 [AD1986A_3STACK] = "3stack",
1075 [AD1986A_LAPTOP] = "laptop", 1140 [AD1986A_LAPTOP] = "laptop",
@@ -1358,7 +1423,7 @@ static struct snd_kcontrol_new ad1983_mixers[] = {
1358 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1423 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1359 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), 1424 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1360 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), 1425 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1361 HDA_CODEC_VOLUME("Mic Boost", 0x0c, 0x0, HDA_OUTPUT), 1426 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT),
1362 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1427 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1363 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1428 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1364 { 1429 {
@@ -1515,8 +1580,8 @@ static struct snd_kcontrol_new ad1981_mixers[] = {
1515 HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), 1580 HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1516 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1581 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1517 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1582 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1518 HDA_CODEC_VOLUME("Front Mic Boost", 0x08, 0x0, HDA_INPUT), 1583 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1519 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x0, HDA_INPUT), 1584 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1520 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1585 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1521 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1586 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1522 { 1587 {
@@ -1726,8 +1791,8 @@ static struct snd_kcontrol_new ad1981_hp_mixers[] = {
1726 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1791 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1727 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1792 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1728#endif 1793#endif
1729 HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT), 1794 HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1730 HDA_CODEC_VOLUME("Internal Mic Boost", 0x18, 0x0, HDA_INPUT), 1795 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1731 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1796 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1732 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1797 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1733 { 1798 {
@@ -1774,7 +1839,7 @@ static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
1774 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1839 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1775 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 1840 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1776 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 1841 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1777 HDA_CODEC_VOLUME("Mic Boost", 0x08, 0x0, HDA_INPUT), 1842 HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1778 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 1843 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1779 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 1844 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1780 { 1845 {
@@ -1813,7 +1878,7 @@ enum {
1813 AD1981_MODELS 1878 AD1981_MODELS
1814}; 1879};
1815 1880
1816static const char *ad1981_models[AD1981_MODELS] = { 1881static const char * const ad1981_models[AD1981_MODELS] = {
1817 [AD1981_HP] = "hp", 1882 [AD1981_HP] = "hp",
1818 [AD1981_THINKPAD] = "thinkpad", 1883 [AD1981_THINKPAD] = "thinkpad",
1819 [AD1981_BASIC] = "basic", 1884 [AD1981_BASIC] = "basic",
@@ -2015,6 +2080,7 @@ static int patch_ad1981(struct hda_codec *codec)
2015enum { 2080enum {
2016 AD1988_6STACK, 2081 AD1988_6STACK,
2017 AD1988_6STACK_DIG, 2082 AD1988_6STACK_DIG,
2083 AD1988_6STACK_DIG_FP,
2018 AD1988_3STACK, 2084 AD1988_3STACK,
2019 AD1988_3STACK_DIG, 2085 AD1988_3STACK_DIG,
2020 AD1988_LAPTOP, 2086 AD1988_LAPTOP,
@@ -2047,6 +2113,10 @@ static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
2047 0x04, 0x05, 0x0a, 0x06 2113 0x04, 0x05, 0x0a, 0x06
2048}; 2114};
2049 2115
2116static hda_nid_t ad1988_alt_dac_nid[1] = {
2117 0x03
2118};
2119
2050static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { 2120static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
2051 0x04, 0x0a, 0x06 2121 0x04, 0x0a, 0x06
2052}; 2122};
@@ -2160,8 +2230,37 @@ static struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2160 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 2230 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2161 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 2231 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2162 2232
2163 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), 2233 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2164 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), 2234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2235
2236 { } /* end */
2237};
2238
2239static struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = {
2240 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2241
2242 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2243 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2244 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
2245 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
2246 HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
2247 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2248 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2249
2250 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2251 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2252 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2253 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2254 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2255 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2256 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2257 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2258
2259 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2260 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2261
2262 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2263 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2165 2264
2166 { } /* end */ 2265 { } /* end */
2167}; 2266};
@@ -2203,8 +2302,8 @@ static struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2203 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 2302 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2204 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 2303 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2205 2304
2206 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), 2305 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2207 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), 2306 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2208 { 2307 {
2209 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2308 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2210 .name = "Channel Mode", 2309 .name = "Channel Mode",
@@ -2232,7 +2331,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2232 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 2331 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2233 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 2332 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2234 2333
2235 HDA_CODEC_VOLUME("Mic Boost", 0x39, 0x0, HDA_OUTPUT), 2334 HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2236 2335
2237 { 2336 {
2238 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2337 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -2445,6 +2544,68 @@ static struct hda_verb ad1988_6stack_init_verbs[] = {
2445 { } 2544 { }
2446}; 2545};
2447 2546
2547static struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2548 /* Front, Surround, CLFE, side DAC; unmute as default */
2549 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2550 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2551 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2552 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2553 /* Headphone; unmute as default */
2554 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2555 /* Port-A front headphon path */
2556 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2557 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2558 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2559 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2560 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2561 /* Port-D line-out path */
2562 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2563 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2564 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2565 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2566 /* Port-F surround path */
2567 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2568 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2569 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2570 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2571 /* Port-G CLFE path */
2572 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2573 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2574 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2575 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2576 /* Port-H side path */
2577 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2578 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2579 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2580 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2581 /* Mono out path */
2582 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2583 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2584 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2585 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2586 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2587 /* Port-B front mic-in path */
2588 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2590 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2591 /* Port-C line-in path */
2592 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2593 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2594 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2595 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2596 /* Port-E mic-in path */
2597 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2598 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2599 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2600 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2601 /* Analog CD Input */
2602 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2603 /* Analog Mix output amp */
2604 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2605
2606 { }
2607};
2608
2448static struct hda_verb ad1988_capture_init_verbs[] = { 2609static struct hda_verb ad1988_capture_init_verbs[] = {
2449 /* mute analog mix */ 2610 /* mute analog mix */
2450 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 2611 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
@@ -2792,7 +2953,9 @@ static int ad1988_auto_create_multi_out_ctls(struct ad198x_spec *spec,
2792 const struct auto_pin_cfg *cfg) 2953 const struct auto_pin_cfg *cfg)
2793{ 2954{
2794 char name[32]; 2955 char name[32];
2795 static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; 2956 static const char * const chname[4] = {
2957 "Front", "Surround", NULL /*CLFE*/, "Side"
2958 };
2796 hda_nid_t nid; 2959 hda_nid_t nid;
2797 int i, err; 2960 int i, err;
2798 2961
@@ -2902,7 +3065,7 @@ static int new_analog_input(struct ad198x_spec *spec, hda_nid_t pin,
2902 idx = ad1988_pin_idx(pin); 3065 idx = ad1988_pin_idx(pin);
2903 bnid = ad1988_boost_nids[idx]; 3066 bnid = ad1988_boost_nids[idx];
2904 if (bnid) { 3067 if (bnid) {
2905 sprintf(name, "%s Boost", ctlname); 3068 sprintf(name, "%s Boost Volume", ctlname);
2906 return add_control(spec, AD_CTL_WIDGET_VOL, name, 3069 return add_control(spec, AD_CTL_WIDGET_VOL, name,
2907 HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT)); 3070 HDA_COMPOSE_AMP_VAL(bnid, 3, idx, HDA_OUTPUT));
2908 3071
@@ -3074,13 +3237,13 @@ static int ad1988_auto_init(struct hda_codec *codec)
3074 return 0; 3237 return 0;
3075} 3238}
3076 3239
3077
3078/* 3240/*
3079 */ 3241 */
3080 3242
3081static const char *ad1988_models[AD1988_MODEL_LAST] = { 3243static const char * const ad1988_models[AD1988_MODEL_LAST] = {
3082 [AD1988_6STACK] = "6stack", 3244 [AD1988_6STACK] = "6stack",
3083 [AD1988_6STACK_DIG] = "6stack-dig", 3245 [AD1988_6STACK_DIG] = "6stack-dig",
3246 [AD1988_6STACK_DIG_FP] = "6stack-dig-fp",
3084 [AD1988_3STACK] = "3stack", 3247 [AD1988_3STACK] = "3stack",
3085 [AD1988_3STACK_DIG] = "3stack-dig", 3248 [AD1988_3STACK_DIG] = "3stack-dig",
3086 [AD1988_LAPTOP] = "laptop", 3249 [AD1988_LAPTOP] = "laptop",
@@ -3140,6 +3303,7 @@ static int patch_ad1988(struct hda_codec *codec)
3140 switch (board_config) { 3303 switch (board_config) {
3141 case AD1988_6STACK: 3304 case AD1988_6STACK:
3142 case AD1988_6STACK_DIG: 3305 case AD1988_6STACK_DIG:
3306 case AD1988_6STACK_DIG_FP:
3143 spec->multiout.max_channels = 8; 3307 spec->multiout.max_channels = 8;
3144 spec->multiout.num_dacs = 4; 3308 spec->multiout.num_dacs = 4;
3145 if (is_rev2(codec)) 3309 if (is_rev2(codec))
@@ -3152,10 +3316,22 @@ static int patch_ad1988(struct hda_codec *codec)
3152 spec->mixers[0] = ad1988_6stack_mixers1_rev2; 3316 spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3153 else 3317 else
3154 spec->mixers[0] = ad1988_6stack_mixers1; 3318 spec->mixers[0] = ad1988_6stack_mixers1;
3155 spec->mixers[1] = ad1988_6stack_mixers2; 3319 if (board_config == AD1988_6STACK_DIG_FP) {
3320 spec->mixers[1] = ad1988_6stack_fp_mixers;
3321 spec->slave_vols = ad1988_6stack_fp_slave_vols;
3322 spec->slave_sws = ad1988_6stack_fp_slave_sws;
3323 spec->alt_dac_nid = ad1988_alt_dac_nid;
3324 spec->stream_analog_alt_playback =
3325 &ad198x_pcm_analog_alt_playback;
3326 } else
3327 spec->mixers[1] = ad1988_6stack_mixers2;
3156 spec->num_init_verbs = 1; 3328 spec->num_init_verbs = 1;
3157 spec->init_verbs[0] = ad1988_6stack_init_verbs; 3329 if (board_config == AD1988_6STACK_DIG_FP)
3158 if (board_config == AD1988_6STACK_DIG) { 3330 spec->init_verbs[0] = ad1988_6stack_fp_init_verbs;
3331 else
3332 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3333 if ((board_config == AD1988_6STACK_DIG) ||
3334 (board_config == AD1988_6STACK_DIG_FP)) {
3159 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 3335 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3160 spec->dig_in_nid = AD1988_SPDIF_IN; 3336 spec->dig_in_nid = AD1988_SPDIF_IN;
3161 } 3337 }
@@ -3300,8 +3476,8 @@ static struct snd_kcontrol_new ad1884_base_mixers[] = {
3300 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 3476 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3301 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), 3477 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3302 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), 3478 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3303 HDA_CODEC_VOLUME("Mic Boost", 0x15, 0x0, HDA_INPUT), 3479 HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3304 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), 3480 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3305 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3481 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3306 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3482 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3307 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3483 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3399,7 +3575,7 @@ static struct hda_amp_list ad1884_loopbacks[] = {
3399}; 3575};
3400#endif 3576#endif
3401 3577
3402static const char *ad1884_slave_vols[] = { 3578static const char * const ad1884_slave_vols[] = {
3403 "PCM Playback Volume", 3579 "PCM Playback Volume",
3404 "Mic Playback Volume", 3580 "Mic Playback Volume",
3405 "Mono Playback Volume", 3581 "Mono Playback Volume",
@@ -3499,9 +3675,9 @@ static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3499 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), 3675 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3500 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 3676 HDA_CODEC_VOLUME("Docking Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3501 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 3677 HDA_CODEC_MUTE("Docking Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3502 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), 3678 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3503 HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT), 3679 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3504 HDA_CODEC_VOLUME("Docking Mic Boost", 0x25, 0x0, HDA_OUTPUT), 3680 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3505 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3681 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3506 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3682 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3507 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3683 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3560,8 +3736,8 @@ static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3560 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 3736 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3561 HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT), 3737 HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3562 HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT), 3738 HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3563 HDA_CODEC_VOLUME("Line-In Boost", 0x15, 0x0, HDA_INPUT), 3739 HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT),
3564 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), 3740 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3565 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3741 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3566 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3742 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3567 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3743 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3637,7 +3813,7 @@ enum {
3637 AD1984_MODELS 3813 AD1984_MODELS
3638}; 3814};
3639 3815
3640static const char *ad1984_models[AD1984_MODELS] = { 3816static const char * const ad1984_models[AD1984_MODELS] = {
3641 [AD1984_BASIC] = "basic", 3817 [AD1984_BASIC] = "basic",
3642 [AD1984_THINKPAD] = "thinkpad", 3818 [AD1984_THINKPAD] = "thinkpad",
3643 [AD1984_DELL_DESKTOP] = "dell_desktop", 3819 [AD1984_DELL_DESKTOP] = "dell_desktop",
@@ -3745,9 +3921,9 @@ static struct snd_kcontrol_new ad1884a_base_mixers[] = {
3745 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 3921 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3746 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), 3922 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3747 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), 3923 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3748 HDA_CODEC_VOLUME("Front Mic Boost", 0x14, 0x0, HDA_INPUT), 3924 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3749 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x0, HDA_INPUT), 3925 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT),
3750 HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT), 3926 HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3751 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 3927 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3752 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 3928 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3753 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 3929 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -3888,9 +4064,9 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
3888 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 4064 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3889 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 4065 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3890 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 4066 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3891 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), 4067 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3892 HDA_CODEC_VOLUME("Internal Mic Boost", 0x15, 0x0, HDA_INPUT), 4068 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3893 HDA_CODEC_VOLUME("Dock Mic Boost", 0x25, 0x0, HDA_OUTPUT), 4069 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3894 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4070 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3895 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4071 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3896 { } /* end */ 4072 { } /* end */
@@ -4126,8 +4302,8 @@ static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4126 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 4302 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4127 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 4303 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4128 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 4304 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4129 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), 4305 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4130 HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT), 4306 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4131 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4307 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4132 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4308 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4133 { 4309 {
@@ -4255,8 +4431,8 @@ static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4255 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 4431 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4256 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4432 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4257 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4433 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4258 HDA_CODEC_VOLUME("Mic Boost", 0x25, 0x0, HDA_OUTPUT), 4434 HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4259 HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT), 4435 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4260 { } /* end */ 4436 { } /* end */
4261}; 4437};
4262 4438
@@ -4308,7 +4484,7 @@ enum {
4308 AD1884A_MODELS 4484 AD1884A_MODELS
4309}; 4485};
4310 4486
4311static const char *ad1884a_models[AD1884A_MODELS] = { 4487static const char * const ad1884a_models[AD1884A_MODELS] = {
4312 [AD1884A_DESKTOP] = "desktop", 4488 [AD1884A_DESKTOP] = "desktop",
4313 [AD1884A_LAPTOP] = "laptop", 4489 [AD1884A_LAPTOP] = "laptop",
4314 [AD1884A_MOBILE] = "mobile", 4490 [AD1884A_MOBILE] = "mobile",
@@ -4494,9 +4670,9 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = {
4494 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), 4670 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4495 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), 4671 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4496 4672
4497 HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), 4673 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
4498 HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), 4674 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
4499 HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT), 4675 HDA_CODEC_VOLUME("Line-In Boost Volume", 0x3a, 0x0, HDA_OUTPUT),
4500 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 4676 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4501 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 4677 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4502 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 4678 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
@@ -4547,7 +4723,7 @@ static struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4547 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT), 4723 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4548 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), 4724 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4549 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), 4725 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4550 HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT), 4726 HDA_CODEC_VOLUME("Digital Mic Boost Volume", 0x1f, 0x0, HDA_INPUT),
4551 { } /* end */ 4727 { } /* end */
4552}; 4728};
4553 4729
@@ -4696,7 +4872,7 @@ enum {
4696 AD1882_MODELS 4872 AD1882_MODELS
4697}; 4873};
4698 4874
4699static const char *ad1882_models[AD1986A_MODELS] = { 4875static const char * const ad1882_models[AD1986A_MODELS] = {
4700 [AD1882_3STACK] = "3stack", 4876 [AD1882_3STACK] = "3stack",
4701 [AD1882_6STACK] = "6stack", 4877 [AD1882_6STACK] = "6stack",
4702}; 4878};
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 18af38ebf757..a07b031090d8 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -490,7 +490,7 @@ static int parse_digital_input(struct hda_codec *codec)
490 * create mixer controls 490 * create mixer controls
491 */ 491 */
492 492
493static const char *dir_sfx[2] = { "Playback", "Capture" }; 493static const char * const dir_sfx[2] = { "Playback", "Capture" };
494 494
495static int add_mute(struct hda_codec *codec, const char *name, int index, 495static int add_mute(struct hda_codec *codec, const char *name, int index,
496 unsigned int pval, int dir, struct snd_kcontrol **kctlp) 496 unsigned int pval, int dir, struct snd_kcontrol **kctlp)
@@ -1156,7 +1156,7 @@ static int cs_parse_auto_config(struct hda_codec *codec)
1156 return 0; 1156 return 0;
1157} 1157}
1158 1158
1159static const char *cs420x_models[CS420X_MODELS] = { 1159static const char * const cs420x_models[CS420X_MODELS] = {
1160 [CS420X_MBP53] = "mbp53", 1160 [CS420X_MBP53] = "mbp53",
1161 [CS420X_MBP55] = "mbp55", 1161 [CS420X_MBP55] = "mbp55",
1162 [CS420X_IMAC27] = "imac27", 1162 [CS420X_IMAC27] = "imac27",
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index ff60908f4554..1f8bbcd0f802 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -608,7 +608,7 @@ static void cmi9880_free(struct hda_codec *codec)
608/* 608/*
609 */ 609 */
610 610
611static const char *cmi9880_models[CMI_MODELS] = { 611static const char * const cmi9880_models[CMI_MODELS] = {
612 [CMI_MINIMAL] = "minimal", 612 [CMI_MINIMAL] = "minimal",
613 [CMI_MIN_FP] = "min_fp", 613 [CMI_MIN_FP] = "min_fp",
614 [CMI_FULL] = "full", 614 [CMI_FULL] = "full",
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 846d1ead47fd..9bb030a469cd 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -537,13 +537,13 @@ static struct snd_kcontrol_new cxt_beep_mixer[] = {
537}; 537};
538#endif 538#endif
539 539
540static const char *slave_vols[] = { 540static const char * const slave_vols[] = {
541 "Headphone Playback Volume", 541 "Headphone Playback Volume",
542 "Speaker Playback Volume", 542 "Speaker Playback Volume",
543 NULL 543 NULL
544}; 544};
545 545
546static const char *slave_sws[] = { 546static const char * const slave_sws[] = {
547 "Headphone Playback Switch", 547 "Headphone Playback Switch",
548 "Speaker Playback Switch", 548 "Speaker Playback Switch",
549 NULL 549 NULL
@@ -869,16 +869,16 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec,
869} 869}
870 870
871static struct snd_kcontrol_new cxt5045_mixers[] = { 871static struct snd_kcontrol_new cxt5045_mixers[] = {
872 HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), 872 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
873 HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), 873 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
874 HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), 874 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
875 HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), 875 HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
876 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), 876 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
877 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), 877 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
878 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x1, HDA_INPUT), 878 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
879 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x1, HDA_INPUT), 879 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
880 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT), 880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
881 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT), 881 HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
882 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), 882 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
883 { 883 {
884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 884 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -910,16 +910,16 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = {
910}; 910};
911 911
912static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { 912static struct snd_kcontrol_new cxt5045_mixers_hp530[] = {
913 HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), 913 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT),
914 HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), 914 HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT),
915 HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), 915 HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT),
916 HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), 916 HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT),
917 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), 917 HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT),
918 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), 918 HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT),
919 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x2, HDA_INPUT), 919 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT),
920 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x2, HDA_INPUT), 920 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT),
921 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x1, HDA_INPUT), 921 HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT),
922 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x1, HDA_INPUT), 922 HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT),
923 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), 923 HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol),
924 { 924 {
925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 925 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -947,7 +947,7 @@ static struct hda_verb cxt5045_init_verbs[] = {
947 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 947 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
948 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 948 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
949 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 949 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
950 /* Record selector: Int mic */ 950 /* Record selector: Internal mic */
951 {0x1a, AC_VERB_SET_CONNECT_SEL,0x1}, 951 {0x1a, AC_VERB_SET_CONNECT_SEL,0x1},
952 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 952 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
953 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, 953 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
@@ -960,7 +960,7 @@ static struct hda_verb cxt5045_init_verbs[] = {
960}; 960};
961 961
962static struct hda_verb cxt5045_benq_init_verbs[] = { 962static struct hda_verb cxt5045_benq_init_verbs[] = {
963 /* Int Mic, Mic */ 963 /* Internal Mic, Mic */
964 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 964 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, 965 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 },
966 /* Line In,HP, Amp */ 966 /* Line In,HP, Amp */
@@ -973,7 +973,7 @@ static struct hda_verb cxt5045_benq_init_verbs[] = {
973 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 973 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
974 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 974 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
975 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 975 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
976 /* Record selector: Int mic */ 976 /* Record selector: Internal mic */
977 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1}, 977 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1},
978 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 978 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE,
979 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, 979 AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17},
@@ -1134,7 +1134,7 @@ enum {
1134 CXT5045_MODELS 1134 CXT5045_MODELS
1135}; 1135};
1136 1136
1137static const char *cxt5045_models[CXT5045_MODELS] = { 1137static const char * const cxt5045_models[CXT5045_MODELS] = {
1138 [CXT5045_LAPTOP_HPSENSE] = "laptop-hpsense", 1138 [CXT5045_LAPTOP_HPSENSE] = "laptop-hpsense",
1139 [CXT5045_LAPTOP_MICSENSE] = "laptop-micsense", 1139 [CXT5045_LAPTOP_MICSENSE] = "laptop-micsense",
1140 [CXT5045_LAPTOP_HPMICSENSE] = "laptop-hpmicsense", 1140 [CXT5045_LAPTOP_HPMICSENSE] = "laptop-hpmicsense",
@@ -1376,7 +1376,7 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec,
1376static struct snd_kcontrol_new cxt5047_base_mixers[] = { 1376static struct snd_kcontrol_new cxt5047_base_mixers[] = {
1377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT), 1377 HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT),
1378 HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT), 1378 HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT),
1379 HDA_CODEC_VOLUME("Mic Boost", 0x1a, 0x0, HDA_OUTPUT), 1379 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT),
1380 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT), 1380 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT),
1381 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), 1381 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT),
1382 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), 1382 HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT),
@@ -1579,7 +1579,7 @@ enum {
1579 CXT5047_MODELS 1579 CXT5047_MODELS
1580}; 1580};
1581 1581
1582static const char *cxt5047_models[CXT5047_MODELS] = { 1582static const char * const cxt5047_models[CXT5047_MODELS] = {
1583 [CXT5047_LAPTOP] = "laptop", 1583 [CXT5047_LAPTOP] = "laptop",
1584 [CXT5047_LAPTOP_HP] = "laptop-hp", 1584 [CXT5047_LAPTOP_HP] = "laptop-hp",
1585 [CXT5047_LAPTOP_EAPD] = "laptop-eapd", 1585 [CXT5047_LAPTOP_EAPD] = "laptop-eapd",
@@ -1796,8 +1796,8 @@ static struct snd_kcontrol_new cxt5051_playback_mixers[] = {
1796static struct snd_kcontrol_new cxt5051_capture_mixers[] = { 1796static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1797 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1797 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1798 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1798 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1799 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT), 1799 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1800 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT), 1800 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1801 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT), 1801 HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT),
1802 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT), 1802 HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT),
1803 {} 1803 {}
@@ -1806,8 +1806,8 @@ static struct snd_kcontrol_new cxt5051_capture_mixers[] = {
1806static struct snd_kcontrol_new cxt5051_hp_mixers[] = { 1806static struct snd_kcontrol_new cxt5051_hp_mixers[] = {
1807 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1807 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1808 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1808 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1809 HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT), 1809 HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT),
1810 HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT), 1810 HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT),
1811 {} 1811 {}
1812}; 1812};
1813 1813
@@ -1826,8 +1826,8 @@ static struct snd_kcontrol_new cxt5051_f700_mixers[] = {
1826static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { 1826static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = {
1827 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), 1827 HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT),
1828 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), 1828 HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT),
1829 HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT), 1829 HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT),
1830 HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT), 1830 HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT),
1831 {} 1831 {}
1832}; 1832};
1833 1833
@@ -1847,7 +1847,7 @@ static struct hda_verb cxt5051_init_verbs[] = {
1847 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1847 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1848 /* DAC1 */ 1848 /* DAC1 */
1849 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1849 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1850 /* Record selector: Int mic */ 1850 /* Record selector: Internal mic */
1851 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1851 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1852 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1853 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1853 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
@@ -1874,7 +1874,7 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = {
1874 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1874 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1875 /* DAC1 */ 1875 /* DAC1 */
1876 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1876 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1877 /* Record selector: Int mic */ 1877 /* Record selector: Internal mic */
1878 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1878 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1879 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, 1879 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1880 /* SPDIF route: PCM */ 1880 /* SPDIF route: PCM */
@@ -1904,7 +1904,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = {
1904 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, 1904 {0x19, AC_VERB_SET_CONNECT_SEL, 0x00},
1905 /* DAC1 */ 1905 /* DAC1 */
1906 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1906 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1907 /* Record selector: Int mic */ 1907 /* Record selector: Internal mic */
1908 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1908 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
1909 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1909 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1910 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, 1910 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44},
@@ -1932,7 +1932,7 @@ static struct hda_verb cxt5051_f700_init_verbs[] = {
1932 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, 1932 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
1933 /* DAC1 */ 1933 /* DAC1 */
1934 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1934 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1935 /* Record selector: Int mic */ 1935 /* Record selector: Internal mic */
1936 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, 1936 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44},
1937 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, 1937 {0x14, AC_VERB_SET_CONNECT_SEL, 0x1},
1938 /* SPDIF route: PCM */ 1938 /* SPDIF route: PCM */
@@ -1995,7 +1995,7 @@ enum {
1995 CXT5051_MODELS 1995 CXT5051_MODELS
1996}; 1996};
1997 1997
1998static const char *cxt5051_models[CXT5051_MODELS] = { 1998static const char *const cxt5051_models[CXT5051_MODELS] = {
1999 [CXT5051_LAPTOP] = "laptop", 1999 [CXT5051_LAPTOP] = "laptop",
2000 [CXT5051_HP] = "hp", 2000 [CXT5051_HP] = "hp",
2001 [CXT5051_HP_DV6736] = "hp-dv6736", 2001 [CXT5051_HP_DV6736] = "hp-dv6736",
@@ -2111,25 +2111,35 @@ static struct hda_channel_mode cxt5066_modes[1] = {
2111 { 2, NULL }, 2111 { 2, NULL },
2112}; 2112};
2113 2113
2114#define HP_PRESENT_PORT_A (1 << 0)
2115#define HP_PRESENT_PORT_D (1 << 1)
2116#define hp_port_a_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_A)
2117#define hp_port_d_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_D)
2118
2114static void cxt5066_update_speaker(struct hda_codec *codec) 2119static void cxt5066_update_speaker(struct hda_codec *codec)
2115{ 2120{
2116 struct conexant_spec *spec = codec->spec; 2121 struct conexant_spec *spec = codec->spec;
2117 unsigned int pinctl; 2122 unsigned int pinctl;
2118 2123
2119 snd_printdd("CXT5066: update speaker, hp_present=%d\n", 2124 snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n",
2120 spec->hp_present); 2125 spec->hp_present, spec->cur_eapd);
2121 2126
2122 /* Port A (HP) */ 2127 /* Port A (HP) */
2123 pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0; 2128 pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0;
2124 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2129 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2125 pinctl); 2130 pinctl);
2126 2131
2127 /* Port D (HP/LO) */ 2132 /* Port D (HP/LO) */
2128 pinctl = ((spec->hp_present & 2) && spec->cur_eapd) 2133 pinctl = spec->cur_eapd ? spec->port_d_mode : 0;
2129 ? spec->port_d_mode : 0; 2134 if (spec->dell_automute || spec->thinkpad) {
2130 /* Mute if Port A is connected on Thinkpad */ 2135 /* Mute if Port A is connected */
2131 if (spec->thinkpad && (spec->hp_present & 1)) 2136 if (hp_port_a_present(spec))
2132 pinctl = 0; 2137 pinctl = 0;
2138 } else {
2139 /* Thinkpad/Dell doesn't give pin-D status */
2140 if (!hp_port_d_present(spec))
2141 pinctl = 0;
2142 }
2133 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2143 snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2134 pinctl); 2144 pinctl);
2135 2145
@@ -2137,14 +2147,6 @@ static void cxt5066_update_speaker(struct hda_codec *codec)
2137 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; 2147 pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0;
2138 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 2148 snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
2139 pinctl); 2149 pinctl);
2140
2141 if (spec->dell_automute) {
2142 /* DELL AIO Port Rule: PortA > PortD > IntSpk */
2143 pinctl = (!(spec->hp_present & 1) && spec->cur_eapd)
2144 ? PIN_OUT : 0;
2145 snd_hda_codec_write(codec, 0x1c, 0,
2146 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl);
2147 }
2148} 2150}
2149 2151
2150/* turn on/off EAPD (+ mute HP) as a master switch */ 2152/* turn on/off EAPD (+ mute HP) as a master switch */
@@ -2378,8 +2380,8 @@ static void cxt5066_hp_automute(struct hda_codec *codec)
2378 /* Port D */ 2380 /* Port D */
2379 portD = snd_hda_jack_detect(codec, 0x1c); 2381 portD = snd_hda_jack_detect(codec, 0x1c);
2380 2382
2381 spec->hp_present = !!(portA); 2383 spec->hp_present = portA ? HP_PRESENT_PORT_A : 0;
2382 spec->hp_present |= portD ? 2 : 0; 2384 spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0;
2383 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", 2385 snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n",
2384 portA, portD, spec->hp_present); 2386 portA, portD, spec->hp_present);
2385 cxt5066_update_speaker(codec); 2387 cxt5066_update_speaker(codec);
@@ -2727,7 +2729,7 @@ static struct snd_kcontrol_new cxt5066_mixers[] = {
2727static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { 2729static struct snd_kcontrol_new cxt5066_vostro_mixers[] = {
2728 { 2730 {
2729 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 2731 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2730 .name = "Int Mic Boost Capture Enum", 2732 .name = "Internal Mic Boost Capture Enum",
2731 .info = cxt5066_mic_boost_mux_enum_info, 2733 .info = cxt5066_mic_boost_mux_enum_info,
2732 .get = cxt5066_mic_boost_mux_enum_get, 2734 .get = cxt5066_mic_boost_mux_enum_get,
2733 .put = cxt5066_mic_boost_mux_enum_put, 2735 .put = cxt5066_mic_boost_mux_enum_put,
@@ -2953,7 +2955,7 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = {
2953 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2955 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2954 2956
2955 /* internal microphone */ 2957 /* internal microphone */
2956 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */ 2958 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
2957 2959
2958 /* EAPD */ 2960 /* EAPD */
2959 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 2961 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -3008,7 +3010,7 @@ static struct hda_verb cxt5066_init_verbs_thinkpad[] = {
3008 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 3010 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3009 3011
3010 /* internal microphone */ 3012 /* internal microphone */
3011 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */ 3013 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */
3012 3014
3013 /* EAPD */ 3015 /* EAPD */
3014 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ 3016 {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */
@@ -3082,7 +3084,7 @@ enum {
3082 CXT5066_MODELS 3084 CXT5066_MODELS
3083}; 3085};
3084 3086
3085static const char *cxt5066_models[CXT5066_MODELS] = { 3087static const char * const cxt5066_models[CXT5066_MODELS] = {
3086 [CXT5066_LAPTOP] = "laptop", 3088 [CXT5066_LAPTOP] = "laptop",
3087 [CXT5066_DELL_LAPTOP] = "dell-laptop", 3089 [CXT5066_DELL_LAPTOP] = "dell-laptop",
3088 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5", 3090 [CXT5066_OLPC_XO_1_5] = "olpc-xo-1_5",
@@ -3095,8 +3097,8 @@ static const char *cxt5066_models[CXT5066_MODELS] = {
3095static struct snd_pci_quirk cxt5066_cfg_tbl[] = { 3097static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3096 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), 3098 SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD),
3097 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), 3099 SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO),
3098 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", 3100 SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD),
3099 CXT5066_DELL_LAPTOP), 3101 SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO),
3100 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), 3102 SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO),
3101 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), 3103 SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD),
3102 SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), 3104 SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP),
@@ -3108,15 +3110,9 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = {
3108 CXT5066_LAPTOP), 3110 CXT5066_LAPTOP),
3109 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), 3111 SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5),
3110 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), 3112 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD),
3111 SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), 3113 SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD),
3112 SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD),
3113 SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD),
3114 SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD),
3115 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), 3114 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD),
3116 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G series", CXT5066_IDEAPAD), 3115 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */
3117 SND_PCI_QUIRK(0x17aa, 0x390a, "Lenovo S10-3t", CXT5066_IDEAPAD),
3118 SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G series (AMD)", CXT5066_IDEAPAD),
3119 SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD),
3120 {} 3116 {}
3121}; 3117};
3122 3118
@@ -3421,6 +3417,9 @@ static void cx_auto_hp_automute(struct hda_codec *codec)
3421 AC_VERB_SET_PIN_WIDGET_CONTROL, 3417 AC_VERB_SET_PIN_WIDGET_CONTROL,
3422 present ? 0 : PIN_OUT); 3418 present ? 0 : PIN_OUT);
3423 } 3419 }
3420 for (i = 0; !present && i < cfg->line_outs; i++)
3421 if (snd_hda_jack_detect(codec, cfg->line_out_pins[i]))
3422 present = 1;
3424 for (i = 0; i < cfg->speaker_outs; i++) { 3423 for (i = 0; i < cfg->speaker_outs; i++) {
3425 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, 3424 snd_hda_codec_write(codec, cfg->speaker_pins[i], 0,
3426 AC_VERB_SET_PIN_WIDGET_CONTROL, 3425 AC_VERB_SET_PIN_WIDGET_CONTROL,
@@ -3747,7 +3746,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
3747 struct conexant_spec *spec = codec->spec; 3746 struct conexant_spec *spec = codec->spec;
3748 int i, err; 3747 int i, err;
3749 int num_line = 0, num_hp = 0, num_spk = 0; 3748 int num_line = 0, num_hp = 0, num_spk = 0;
3750 static const char *texts[3] = { "Front", "Surround", "CLFE" }; 3749 static const char * const texts[3] = { "Front", "Surround", "CLFE" };
3751 3750
3752 if (spec->dac_info_filled == 1) 3751 if (spec->dac_info_filled == 1)
3753 return cx_auto_add_pb_volume(codec, spec->dac_info[0].dac, 3752 return cx_auto_add_pb_volume(codec, spec->dac_info[0].dac,
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index d3e49aa5b9ec..2d5b83fa8d24 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -31,10 +31,15 @@
31#include <linux/init.h> 31#include <linux/init.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/moduleparam.h>
34#include <sound/core.h> 35#include <sound/core.h>
35#include "hda_codec.h" 36#include "hda_codec.h"
36#include "hda_local.h" 37#include "hda_local.h"
37 38
39static bool static_hdmi_pcm;
40module_param(static_hdmi_pcm, bool, 0644);
41MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
42
38/* 43/*
39 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device 44 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
40 * could support two independent pipes, each of them can be connected to one or 45 * could support two independent pipes, each of them can be connected to one or
@@ -812,6 +817,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
812 struct hdmi_spec *spec = codec->spec; 817 struct hdmi_spec *spec = codec->spec;
813 struct hdmi_eld *eld; 818 struct hdmi_eld *eld;
814 struct hda_pcm_stream *codec_pars; 819 struct hda_pcm_stream *codec_pars;
820 struct snd_pcm_runtime *runtime = substream->runtime;
815 unsigned int idx; 821 unsigned int idx;
816 822
817 for (idx = 0; idx < spec->num_cvts; idx++) 823 for (idx = 0; idx < spec->num_cvts; idx++)
@@ -827,19 +833,26 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
827 *codec_pars = *hinfo; 833 *codec_pars = *hinfo;
828 834
829 eld = &spec->sink_eld[idx]; 835 eld = &spec->sink_eld[idx];
830 if (eld->sad_count > 0) { 836 if (!static_hdmi_pcm && eld->eld_valid && eld->sad_count > 0) {
831 hdmi_eld_update_pcm_info(eld, hinfo, codec_pars); 837 hdmi_eld_update_pcm_info(eld, hinfo, codec_pars);
832 if (hinfo->channels_min > hinfo->channels_max || 838 if (hinfo->channels_min > hinfo->channels_max ||
833 !hinfo->rates || !hinfo->formats) 839 !hinfo->rates || !hinfo->formats)
834 return -ENODEV; 840 return -ENODEV;
835 } else { 841 } else {
836 /* fallback to the codec default */ 842 /* fallback to the codec default */
837 hinfo->channels_min = codec_pars->channels_min;
838 hinfo->channels_max = codec_pars->channels_max; 843 hinfo->channels_max = codec_pars->channels_max;
839 hinfo->rates = codec_pars->rates; 844 hinfo->rates = codec_pars->rates;
840 hinfo->formats = codec_pars->formats; 845 hinfo->formats = codec_pars->formats;
841 hinfo->maxbps = codec_pars->maxbps; 846 hinfo->maxbps = codec_pars->maxbps;
842 } 847 }
848 /* store the updated parameters */
849 runtime->hw.channels_min = hinfo->channels_min;
850 runtime->hw.channels_max = hinfo->channels_max;
851 runtime->hw.formats = hinfo->formats;
852 runtime->hw.rates = hinfo->rates;
853
854 snd_pcm_hw_constraint_step(substream->runtime, 0,
855 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
843 return 0; 856 return 0;
844} 857}
845 858
@@ -905,23 +918,28 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
905 spec->pin[spec->num_pins] = pin_nid; 918 spec->pin[spec->num_pins] = pin_nid;
906 spec->num_pins++; 919 spec->num_pins++;
907 920
908 /*
909 * It is assumed that converter nodes come first in the node list and
910 * hence have been registered and usable now.
911 */
912 return hdmi_read_pin_conn(codec, pin_nid); 921 return hdmi_read_pin_conn(codec, pin_nid);
913} 922}
914 923
915static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid) 924static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid)
916{ 925{
926 int i, found_pin = 0;
917 struct hdmi_spec *spec = codec->spec; 927 struct hdmi_spec *spec = codec->spec;
918 928
919 if (spec->num_cvts >= MAX_HDMI_CVTS) { 929 for (i = 0; i < spec->num_pins; i++)
920 snd_printk(KERN_WARNING 930 if (nid == spec->pin_cvt[i]) {
921 "HDMI: no space for converter %d\n", nid); 931 found_pin = 1;
922 return -E2BIG; 932 break;
933 }
934
935 if (!found_pin) {
936 snd_printdd("HDMI: Skipping node %d (no connection)\n", nid);
937 return -EINVAL;
923 } 938 }
924 939
940 if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS))
941 return -E2BIG;
942
925 spec->cvt[spec->num_cvts] = nid; 943 spec->cvt[spec->num_cvts] = nid;
926 spec->num_cvts++; 944 spec->num_cvts++;
927 945
@@ -932,6 +950,8 @@ static int hdmi_parse_codec(struct hda_codec *codec)
932{ 950{
933 hda_nid_t nid; 951 hda_nid_t nid;
934 int i, nodes; 952 int i, nodes;
953 int num_tmp_cvts = 0;
954 hda_nid_t tmp_cvt[MAX_HDMI_CVTS];
935 955
936 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); 956 nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid);
937 if (!nid || nodes < 0) { 957 if (!nid || nodes < 0) {
@@ -942,6 +962,7 @@ static int hdmi_parse_codec(struct hda_codec *codec)
942 for (i = 0; i < nodes; i++, nid++) { 962 for (i = 0; i < nodes; i++, nid++) {
943 unsigned int caps; 963 unsigned int caps;
944 unsigned int type; 964 unsigned int type;
965 unsigned int config;
945 966
946 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); 967 caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
947 type = get_wcaps_type(caps); 968 type = get_wcaps_type(caps);
@@ -951,17 +972,32 @@ static int hdmi_parse_codec(struct hda_codec *codec)
951 972
952 switch (type) { 973 switch (type) {
953 case AC_WID_AUD_OUT: 974 case AC_WID_AUD_OUT:
954 hdmi_add_cvt(codec, nid); 975 if (num_tmp_cvts >= MAX_HDMI_CVTS) {
976 snd_printk(KERN_WARNING
977 "HDMI: no space for converter %d\n", nid);
978 continue;
979 }
980 tmp_cvt[num_tmp_cvts] = nid;
981 num_tmp_cvts++;
955 break; 982 break;
956 case AC_WID_PIN: 983 case AC_WID_PIN:
957 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); 984 caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
958 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) 985 if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP)))
959 continue; 986 continue;
987
988 config = snd_hda_codec_read(codec, nid, 0,
989 AC_VERB_GET_CONFIG_DEFAULT, 0);
990 if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
991 continue;
992
960 hdmi_add_pin(codec, nid); 993 hdmi_add_pin(codec, nid);
961 break; 994 break;
962 } 995 }
963 } 996 }
964 997
998 for (i = 0; i < num_tmp_cvts; i++)
999 hdmi_add_cvt(codec, tmp_cvt[i]);
1000
965 /* 1001 /*
966 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event 1002 * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event
967 * can be lost and presence sense verb will become inaccurate if the 1003 * can be lost and presence sense verb will become inaccurate if the
@@ -1166,11 +1202,56 @@ static int nvhdmi_7x_init(struct hda_codec *codec)
1166 return 0; 1202 return 0;
1167} 1203}
1168 1204
1205static unsigned int channels_2_6_8[] = {
1206 2, 6, 8
1207};
1208
1209static unsigned int channels_2_8[] = {
1210 2, 8
1211};
1212
1213static struct snd_pcm_hw_constraint_list hw_constraints_2_6_8_channels = {
1214 .count = ARRAY_SIZE(channels_2_6_8),
1215 .list = channels_2_6_8,
1216 .mask = 0,
1217};
1218
1219static struct snd_pcm_hw_constraint_list hw_constraints_2_8_channels = {
1220 .count = ARRAY_SIZE(channels_2_8),
1221 .list = channels_2_8,
1222 .mask = 0,
1223};
1224
1169static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo, 1225static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo,
1170 struct hda_codec *codec, 1226 struct hda_codec *codec,
1171 struct snd_pcm_substream *substream) 1227 struct snd_pcm_substream *substream)
1172{ 1228{
1173 struct hdmi_spec *spec = codec->spec; 1229 struct hdmi_spec *spec = codec->spec;
1230 struct snd_pcm_hw_constraint_list *hw_constraints_channels = NULL;
1231
1232 switch (codec->preset->id) {
1233 case 0x10de0002:
1234 case 0x10de0003:
1235 case 0x10de0005:
1236 case 0x10de0006:
1237 hw_constraints_channels = &hw_constraints_2_8_channels;
1238 break;
1239 case 0x10de0007:
1240 hw_constraints_channels = &hw_constraints_2_6_8_channels;
1241 break;
1242 default:
1243 break;
1244 }
1245
1246 if (hw_constraints_channels != NULL) {
1247 snd_pcm_hw_constraint_list(substream->runtime, 0,
1248 SNDRV_PCM_HW_PARAM_CHANNELS,
1249 hw_constraints_channels);
1250 } else {
1251 snd_pcm_hw_constraint_step(substream->runtime, 0,
1252 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
1253 }
1254
1174 return snd_hda_multi_out_dig_open(codec, &spec->multiout); 1255 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
1175} 1256}
1176 1257
@@ -1533,7 +1614,7 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = {
1533{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi }, 1614{ .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi },
1534{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi }, 1615{ .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi },
1535{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi }, 1616{ .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi },
1536{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi }, 1617{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_generic_hdmi },
1537{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi }, 1618{ .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi },
1538{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi }, 1619{ .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi },
1539{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi }, 1620{ .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi },
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 8fddc9d08726..be4df4c6fd56 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -231,7 +231,6 @@ enum {
231 ALC888_ACER_ASPIRE_8930G, 231 ALC888_ACER_ASPIRE_8930G,
232 ALC888_ACER_ASPIRE_7730G, 232 ALC888_ACER_ASPIRE_7730G,
233 ALC883_MEDION, 233 ALC883_MEDION,
234 ALC883_MEDION_MD2,
235 ALC883_MEDION_WIM2160, 234 ALC883_MEDION_WIM2160,
236 ALC883_LAPTOP_EAPD, 235 ALC883_LAPTOP_EAPD,
237 ALC883_LENOVO_101E_2ch, 236 ALC883_LENOVO_101E_2ch,
@@ -304,6 +303,8 @@ struct alc_customize_define {
304 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ 303 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
305}; 304};
306 305
306struct alc_fixup;
307
307struct alc_spec { 308struct alc_spec {
308 /* codec parameterization */ 309 /* codec parameterization */
309 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 310 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -405,6 +406,11 @@ struct alc_spec {
405 /* for PLL fix */ 406 /* for PLL fix */
406 hda_nid_t pll_nid; 407 hda_nid_t pll_nid;
407 unsigned int pll_coef_idx, pll_coef_bit; 408 unsigned int pll_coef_idx, pll_coef_bit;
409
410 /* fix-up list */
411 int fixup_id;
412 const struct alc_fixup *fixup_list;
413 const char *fixup_name;
408}; 414};
409 415
410/* 416/*
@@ -1678,48 +1684,139 @@ struct alc_pincfg {
1678 u32 val; 1684 u32 val;
1679}; 1685};
1680 1686
1687struct alc_model_fixup {
1688 const int id;
1689 const char *name;
1690};
1691
1681struct alc_fixup { 1692struct alc_fixup {
1682 unsigned int sku; 1693 int type;
1683 const struct alc_pincfg *pins; 1694 bool chained;
1684 const struct hda_verb *verbs; 1695 int chain_id;
1696 union {
1697 unsigned int sku;
1698 const struct alc_pincfg *pins;
1699 const struct hda_verb *verbs;
1700 void (*func)(struct hda_codec *codec,
1701 const struct alc_fixup *fix,
1702 int action);
1703 } v;
1685}; 1704};
1686 1705
1687static void alc_pick_fixup(struct hda_codec *codec, 1706enum {
1688 const struct snd_pci_quirk *quirk, 1707 ALC_FIXUP_INVALID,
1689 const struct alc_fixup *fix, 1708 ALC_FIXUP_SKU,
1690 int pre_init) 1709 ALC_FIXUP_PINS,
1691{ 1710 ALC_FIXUP_VERBS,
1692 const struct alc_pincfg *cfg; 1711 ALC_FIXUP_FUNC,
1693 struct alc_spec *spec; 1712};
1694 1713
1695 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); 1714enum {
1696 if (!quirk) 1715 ALC_FIXUP_ACT_PRE_PROBE,
1697 return; 1716 ALC_FIXUP_ACT_PROBE,
1698 fix += quirk->value; 1717 ALC_FIXUP_ACT_INIT,
1699 cfg = fix->pins; 1718};
1700 if (pre_init && fix->sku) { 1719
1720static void alc_apply_fixup(struct hda_codec *codec, int action)
1721{
1722 struct alc_spec *spec = codec->spec;
1723 int id = spec->fixup_id;
1701#ifdef CONFIG_SND_DEBUG_VERBOSE 1724#ifdef CONFIG_SND_DEBUG_VERBOSE
1702 snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n", 1725 const char *modelname = spec->fixup_name;
1703 codec->chip_name, quirk->name);
1704#endif 1726#endif
1705 spec = codec->spec; 1727 int depth = 0;
1706 spec->cdefine.sku_cfg = fix->sku; 1728
1707 spec->cdefine.fixup = 1; 1729 if (!spec->fixup_list)
1730 return;
1731
1732 while (id >= 0) {
1733 const struct alc_fixup *fix = spec->fixup_list + id;
1734 const struct alc_pincfg *cfg;
1735
1736 switch (fix->type) {
1737 case ALC_FIXUP_SKU:
1738 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1739 break;;
1740 snd_printdd(KERN_INFO "hda_codec: %s: "
1741 "Apply sku override for %s\n",
1742 codec->chip_name, modelname);
1743 spec->cdefine.sku_cfg = fix->v.sku;
1744 spec->cdefine.fixup = 1;
1745 break;
1746 case ALC_FIXUP_PINS:
1747 cfg = fix->v.pins;
1748 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1749 break;
1750 snd_printdd(KERN_INFO "hda_codec: %s: "
1751 "Apply pincfg for %s\n",
1752 codec->chip_name, modelname);
1753 for (; cfg->nid; cfg++)
1754 snd_hda_codec_set_pincfg(codec, cfg->nid,
1755 cfg->val);
1756 break;
1757 case ALC_FIXUP_VERBS:
1758 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1759 break;
1760 snd_printdd(KERN_INFO "hda_codec: %s: "
1761 "Apply fix-verbs for %s\n",
1762 codec->chip_name, modelname);
1763 add_verb(codec->spec, fix->v.verbs);
1764 break;
1765 case ALC_FIXUP_FUNC:
1766 if (!fix->v.func)
1767 break;
1768 snd_printdd(KERN_INFO "hda_codec: %s: "
1769 "Apply fix-func for %s\n",
1770 codec->chip_name, modelname);
1771 fix->v.func(codec, fix, action);
1772 break;
1773 default:
1774 snd_printk(KERN_ERR "hda_codec: %s: "
1775 "Invalid fixup type %d\n",
1776 codec->chip_name, fix->type);
1777 break;
1778 }
1779 if (!fix[id].chained)
1780 break;
1781 if (++depth > 10)
1782 break;
1783 id = fix[id].chain_id;
1708 } 1784 }
1709 if (pre_init && cfg) { 1785}
1710#ifdef CONFIG_SND_DEBUG_VERBOSE 1786
1711 snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", 1787static void alc_pick_fixup(struct hda_codec *codec,
1712 codec->chip_name, quirk->name); 1788 const struct alc_model_fixup *models,
1713#endif 1789 const struct snd_pci_quirk *quirk,
1714 for (; cfg->nid; cfg++) 1790 const struct alc_fixup *fixlist)
1715 snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); 1791{
1792 struct alc_spec *spec = codec->spec;
1793 int id = -1;
1794 const char *name = NULL;
1795
1796 if (codec->modelname && models) {
1797 while (models->name) {
1798 if (!strcmp(codec->modelname, models->name)) {
1799 id = models->id;
1800 name = models->name;
1801 break;
1802 }
1803 models++;
1804 }
1716 } 1805 }
1717 if (!pre_init && fix->verbs) { 1806 if (id < 0) {
1807 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
1808 if (quirk) {
1809 id = quirk->value;
1718#ifdef CONFIG_SND_DEBUG_VERBOSE 1810#ifdef CONFIG_SND_DEBUG_VERBOSE
1719 snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", 1811 name = quirk->name;
1720 codec->chip_name, quirk->name);
1721#endif 1812#endif
1722 add_verb(codec->spec, fix->verbs); 1813 }
1814 }
1815
1816 spec->fixup_id = id;
1817 if (id >= 0) {
1818 spec->fixup_list = fixlist;
1819 spec->fixup_name = name;
1723 } 1820 }
1724} 1821}
1725 1822
@@ -1981,6 +2078,7 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
1981 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 2078 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
1982 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 2079 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
1983 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 2080 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2081 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
1984 { } 2082 { }
1985}; 2083};
1986 2084
@@ -2120,17 +2218,17 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2120 { 2218 {
2121 .num_items = 5, 2219 .num_items = 5,
2122 .items = { 2220 .items = {
2123 { "Ext Mic", 0x0 }, 2221 { "Mic", 0x0 },
2124 { "Line In", 0x2 }, 2222 { "Line In", 0x2 },
2125 { "CD", 0x4 }, 2223 { "CD", 0x4 },
2126 { "Input Mix", 0xa }, 2224 { "Input Mix", 0xa },
2127 { "Int Mic", 0xb }, 2225 { "Internal Mic", 0xb },
2128 }, 2226 },
2129 }, 2227 },
2130 { 2228 {
2131 .num_items = 4, 2229 .num_items = 4,
2132 .items = { 2230 .items = {
2133 { "Ext Mic", 0x0 }, 2231 { "Mic", 0x0 },
2134 { "Line In", 0x2 }, 2232 { "Line In", 0x2 },
2135 { "CD", 0x4 }, 2233 { "CD", 0x4 },
2136 { "Input Mix", 0xa }, 2234 { "Input Mix", 0xa },
@@ -2187,7 +2285,7 @@ static struct snd_kcontrol_new alc888_base_mixer[] = {
2187 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2285 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2188 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2286 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2189 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2287 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2190 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 2288 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2191 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2289 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2192 { } /* end */ 2290 { } /* end */
2193}; 2291};
@@ -2205,7 +2303,7 @@ static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2205 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 2303 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2206 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 2304 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2207 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2208 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 2306 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2209 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2307 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2210 { } /* end */ 2308 { } /* end */
2211}; 2309};
@@ -2796,10 +2894,10 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
2796 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 2894 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
2797 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 2895 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2798 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 2896 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2799 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 2897 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2800 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 2898 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2801 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 2899 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2802 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 2900 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2803 { } /* end */ 2901 { } /* end */
2804}; 2902};
2805 2903
@@ -2820,7 +2918,7 @@ static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
2820/* 2918/*
2821 * slave controls for virtual master 2919 * slave controls for virtual master
2822 */ 2920 */
2823static const char *alc_slave_vols[] = { 2921static const char * const alc_slave_vols[] = {
2824 "Front Playback Volume", 2922 "Front Playback Volume",
2825 "Surround Playback Volume", 2923 "Surround Playback Volume",
2826 "Center Playback Volume", 2924 "Center Playback Volume",
@@ -2834,7 +2932,7 @@ static const char *alc_slave_vols[] = {
2834 NULL, 2932 NULL,
2835}; 2933};
2836 2934
2837static const char *alc_slave_sws[] = { 2935static const char * const alc_slave_sws[] = {
2838 "Front Playback Switch", 2936 "Front Playback Switch",
2839 "Surround Playback Switch", 2937 "Surround Playback Switch",
2840 "Center Playback Switch", 2938 "Center Playback Switch",
@@ -3307,7 +3405,7 @@ static struct hda_verb alc880_beep_init_verbs[] = {
3307}; 3405};
3308 3406
3309/* auto-toggle front mic */ 3407/* auto-toggle front mic */
3310static void alc880_uniwill_mic_automute(struct hda_codec *codec) 3408static void alc88x_simple_mic_automute(struct hda_codec *codec)
3311{ 3409{
3312 unsigned int present; 3410 unsigned int present;
3313 unsigned char bits; 3411 unsigned char bits;
@@ -3329,7 +3427,7 @@ static void alc880_uniwill_setup(struct hda_codec *codec)
3329static void alc880_uniwill_init_hook(struct hda_codec *codec) 3427static void alc880_uniwill_init_hook(struct hda_codec *codec)
3330{ 3428{
3331 alc_automute_amp(codec); 3429 alc_automute_amp(codec);
3332 alc880_uniwill_mic_automute(codec); 3430 alc88x_simple_mic_automute(codec);
3333} 3431}
3334 3432
3335static void alc880_uniwill_unsol_event(struct hda_codec *codec, 3433static void alc880_uniwill_unsol_event(struct hda_codec *codec,
@@ -3340,7 +3438,7 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3340 */ 3438 */
3341 switch (res >> 28) { 3439 switch (res >> 28) {
3342 case ALC880_MIC_EVENT: 3440 case ALC880_MIC_EVENT:
3343 alc880_uniwill_mic_automute(codec); 3441 alc88x_simple_mic_automute(codec);
3344 break; 3442 break;
3345 default: 3443 default:
3346 alc_automute_amp_unsol_event(codec, res); 3444 alc_automute_amp_unsol_event(codec, res);
@@ -3815,6 +3913,8 @@ static int alc_init(struct hda_codec *codec)
3815 if (spec->init_hook) 3913 if (spec->init_hook)
3816 spec->init_hook(codec); 3914 spec->init_hook(codec);
3817 3915
3916 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
3917
3818 hda_call_check_power_status(codec, 0x01); 3918 hda_call_check_power_status(codec, 0x01);
3819 return 0; 3919 return 0;
3820} 3920}
@@ -4513,7 +4613,7 @@ static struct hda_verb alc880_test_init_verbs[] = {
4513/* 4613/*
4514 */ 4614 */
4515 4615
4516static const char *alc880_models[ALC880_MODEL_LAST] = { 4616static const char * const alc880_models[ALC880_MODEL_LAST] = {
4517 [ALC880_3ST] = "3stack", 4617 [ALC880_3ST] = "3stack",
4518 [ALC880_TCL_S700] = "tcl", 4618 [ALC880_TCL_S700] = "tcl",
4519 [ALC880_3ST_DIG] = "3stack-digout", 4619 [ALC880_3ST_DIG] = "3stack-digout",
@@ -4595,6 +4695,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = {
4595 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), 4695 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4596 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), 4696 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4597 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), 4697 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4698 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4598 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), 4699 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4599 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), 4700 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4600 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), 4701 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
@@ -5022,13 +5123,33 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5022 return 0; 5123 return 0;
5023} 5124}
5024 5125
5126static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg,
5127 bool can_be_master)
5128{
5129 if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5130 return "Master";
5131
5132 switch (cfg->line_out_type) {
5133 case AUTO_PIN_SPEAKER_OUT:
5134 return "Speaker";
5135 case AUTO_PIN_HP_OUT:
5136 return "Headphone";
5137 default:
5138 if (cfg->line_outs == 1)
5139 return "PCM";
5140 break;
5141 }
5142 return NULL;
5143}
5144
5025/* add playback controls from the parsed DAC table */ 5145/* add playback controls from the parsed DAC table */
5026static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, 5146static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5027 const struct auto_pin_cfg *cfg) 5147 const struct auto_pin_cfg *cfg)
5028{ 5148{
5029 static const char *chname[4] = { 5149 static const char * const chname[4] = {
5030 "Front", "Surround", NULL /*CLFE*/, "Side" 5150 "Front", "Surround", NULL /*CLFE*/, "Side"
5031 }; 5151 };
5152 const char *pfx = alc_get_line_out_pfx(cfg, false);
5032 hda_nid_t nid; 5153 hda_nid_t nid;
5033 int i, err; 5154 int i, err;
5034 5155
@@ -5036,7 +5157,7 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5036 if (!spec->multiout.dac_nids[i]) 5157 if (!spec->multiout.dac_nids[i])
5037 continue; 5158 continue;
5038 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); 5159 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5039 if (i == 2) { 5160 if (!pfx && i == 2) {
5040 /* Center/LFE */ 5161 /* Center/LFE */
5041 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 5162 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5042 "Center", 5163 "Center",
@@ -5063,18 +5184,17 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5063 if (err < 0) 5184 if (err < 0)
5064 return err; 5185 return err;
5065 } else { 5186 } else {
5066 const char *pfx; 5187 const char *name = pfx;
5067 if (cfg->line_outs == 1 && 5188 if (!name)
5068 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 5189 name = chname[i];
5069 pfx = "Speaker"; 5190 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5070 else 5191 name, i,
5071 pfx = chname[i];
5072 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5073 HDA_COMPOSE_AMP_VAL(nid, 3, 0, 5192 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5074 HDA_OUTPUT)); 5193 HDA_OUTPUT));
5075 if (err < 0) 5194 if (err < 0)
5076 return err; 5195 return err;
5077 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, 5196 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5197 name, i,
5078 HDA_COMPOSE_AMP_VAL(nid, 3, 2, 5198 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5079 HDA_INPUT)); 5199 HDA_INPUT));
5080 if (err < 0) 5200 if (err < 0)
@@ -5154,7 +5274,8 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec,
5154{ 5274{
5155 struct alc_spec *spec = codec->spec; 5275 struct alc_spec *spec = codec->spec;
5156 struct hda_input_mux *imux = &spec->private_imux[0]; 5276 struct hda_input_mux *imux = &spec->private_imux[0];
5157 int i, err, idx, type, type_idx = 0; 5277 int i, err, idx, type_idx = 0;
5278 const char *prev_label = NULL;
5158 5279
5159 for (i = 0; i < cfg->num_inputs; i++) { 5280 for (i = 0; i < cfg->num_inputs; i++) {
5160 hda_nid_t pin; 5281 hda_nid_t pin;
@@ -5164,12 +5285,13 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec,
5164 if (!alc_is_input_pin(codec, pin)) 5285 if (!alc_is_input_pin(codec, pin))
5165 continue; 5286 continue;
5166 5287
5167 type = cfg->inputs[i].type; 5288 label = hda_get_autocfg_input_label(codec, cfg, i);
5168 if (i > 0 && type == cfg->inputs[i - 1].type) 5289 if (prev_label && !strcmp(label, prev_label))
5169 type_idx++; 5290 type_idx++;
5170 else 5291 else
5171 type_idx = 0; 5292 type_idx = 0;
5172 label = hda_get_autocfg_input_label(codec, cfg, i); 5293 prev_label = label;
5294
5173 if (mixer) { 5295 if (mixer) {
5174 idx = get_connection_index(codec, mixer, pin); 5296 idx = get_connection_index(codec, mixer, pin);
5175 if (idx >= 0) { 5297 if (idx >= 0) {
@@ -7022,7 +7144,8 @@ enum {
7022 7144
7023static const struct alc_fixup alc260_fixups[] = { 7145static const struct alc_fixup alc260_fixups[] = {
7024 [PINFIX_HP_DC5750] = { 7146 [PINFIX_HP_DC5750] = {
7025 .pins = (const struct alc_pincfg[]) { 7147 .type = ALC_FIXUP_PINS,
7148 .v.pins = (const struct alc_pincfg[]) {
7026 { 0x11, 0x90130110 }, /* speaker */ 7149 { 0x11, 0x90130110 }, /* speaker */
7027 { } 7150 { }
7028 } 7151 }
@@ -7037,7 +7160,7 @@ static struct snd_pci_quirk alc260_fixup_tbl[] = {
7037/* 7160/*
7038 * ALC260 configurations 7161 * ALC260 configurations
7039 */ 7162 */
7040static const char *alc260_models[ALC260_MODEL_LAST] = { 7163static const char * const alc260_models[ALC260_MODEL_LAST] = {
7041 [ALC260_BASIC] = "basic", 7164 [ALC260_BASIC] = "basic",
7042 [ALC260_HP] = "hp", 7165 [ALC260_HP] = "hp",
7043 [ALC260_HP_3013] = "hp-3013", 7166 [ALC260_HP_3013] = "hp-3013",
@@ -7233,8 +7356,10 @@ static int patch_alc260(struct hda_codec *codec)
7233 board_config = ALC260_AUTO; 7356 board_config = ALC260_AUTO;
7234 } 7357 }
7235 7358
7236 if (board_config == ALC260_AUTO) 7359 if (board_config == ALC260_AUTO) {
7237 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 1); 7360 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7361 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7362 }
7238 7363
7239 if (board_config == ALC260_AUTO) { 7364 if (board_config == ALC260_AUTO) {
7240 /* automatic parse from the BIOS config */ 7365 /* automatic parse from the BIOS config */
@@ -7282,8 +7407,7 @@ static int patch_alc260(struct hda_codec *codec)
7282 set_capture_mixer(codec); 7407 set_capture_mixer(codec);
7283 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); 7408 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7284 7409
7285 if (board_config == ALC260_AUTO) 7410 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7286 alc_pick_fixup(codec, alc260_fixup_tbl, alc260_fixups, 0);
7287 7411
7288 spec->vmaster_nid = 0x08; 7412 spec->vmaster_nid = 0x08;
7289 7413
@@ -7405,7 +7529,7 @@ static struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7405 .num_items = 4, 7529 .num_items = 4,
7406 .items = { 7530 .items = {
7407 { "Mic", 0x0 }, 7531 { "Mic", 0x0 },
7408 { "Int Mic", 0x1 }, 7532 { "Internal Mic", 0x1 },
7409 { "Line", 0x2 }, 7533 { "Line", 0x2 },
7410 { "CD", 0x4 }, 7534 { "CD", 0x4 },
7411 }, 7535 },
@@ -7415,7 +7539,7 @@ static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7415 .num_items = 2, 7539 .num_items = 2,
7416 .items = { 7540 .items = {
7417 { "Mic", 0x0 }, 7541 { "Mic", 0x0 },
7418 { "Int Mic", 0x1 }, 7542 { "Internal Mic", 0x1 },
7419 }, 7543 },
7420}; 7544};
7421 7545
@@ -7850,10 +7974,10 @@ static struct snd_kcontrol_new alc882_base_mixer[] = {
7850 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 7974 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7851 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 7975 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7852 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 7976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7853 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 7977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7854 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 7978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7855 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 7979 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7856 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 7980 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
7857 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 7981 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7858 { } /* end */ 7982 { } /* end */
7859}; 7983};
@@ -7877,8 +8001,8 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = {
7877 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8001 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7878 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 8002 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
7879 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 8003 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
7880 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 8004 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
7881 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 8005 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
7882 { } /* end */ 8006 { } /* end */
7883}; 8007};
7884 8008
@@ -7895,8 +8019,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = {
7895 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 8019 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7896 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 8020 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
7897 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 8021 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
7898 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 8022 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7899 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0x00, HDA_INPUT), 8023 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
7900 { } /* end */ 8024 { } /* end */
7901}; 8025};
7902 8026
@@ -7911,7 +8035,7 @@ static struct snd_kcontrol_new alc885_macmini3_mixer[] = {
7911 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), 8035 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
7912 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), 8036 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
7913 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), 8037 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
7914 HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), 8038 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
7915 { } /* end */ 8039 { } /* end */
7916}; 8040};
7917 8041
@@ -7930,7 +8054,7 @@ static struct snd_kcontrol_new alc882_w2jc_mixer[] = {
7930 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8054 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7931 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8055 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7932 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8056 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7933 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8057 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7934 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8058 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7935 { } /* end */ 8059 { } /* end */
7936}; 8060};
@@ -7945,10 +8069,10 @@ static struct snd_kcontrol_new alc882_targa_mixer[] = {
7945 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8069 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7946 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8070 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7947 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8071 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7948 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8072 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7949 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8073 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
7950 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8074 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
7951 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8075 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
7952 { } /* end */ 8076 { } /* end */
7953}; 8077};
7954 8078
@@ -7968,7 +8092,7 @@ static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
7968 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT), 8092 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
7969 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8093 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7970 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8094 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7971 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8095 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7972 { } /* end */ 8096 { } /* end */
7973}; 8097};
7974 8098
@@ -7981,7 +8105,7 @@ static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
7981 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8105 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
7982 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8106 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
7983 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8107 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
7984 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8108 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
7985 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8109 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
7986 { } /* end */ 8110 { } /* end */
7987}; 8111};
@@ -8762,10 +8886,10 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = {
8762 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT), 8886 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8763 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 8887 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8764 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8888 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8765 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8889 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8766 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8890 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8767 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8891 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8768 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8892 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8769 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8893 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8770 { } /* end */ 8894 { } /* end */
8771}; 8895};
@@ -8776,11 +8900,11 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8776 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8900 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8777 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8901 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8778 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8902 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8779 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8903 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8780 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8904 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8781 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8905 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8782 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8906 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8783 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8907 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8784 { } /* end */ 8908 { } /* end */
8785}; 8909};
8786 8910
@@ -8790,11 +8914,11 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8790 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 8914 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8791 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 8915 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8792 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8916 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8793 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8917 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8794 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8918 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8795 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8919 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8796 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 8920 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8797 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8921 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8798 { } /* end */ 8922 { } /* end */
8799}; 8923};
8800 8924
@@ -8807,10 +8931,10 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8807 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8931 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8808 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8932 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8809 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8933 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8810 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8934 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8811 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8935 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8812 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8936 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8813 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8937 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8814 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8938 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8815 { } /* end */ 8939 { } /* end */
8816}; 8940};
@@ -8830,10 +8954,10 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
8830 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8954 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8831 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8955 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8832 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8956 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8833 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 8957 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8834 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8958 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8835 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8959 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8836 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 8960 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8837 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8961 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8838 { } /* end */ 8962 { } /* end */
8839}; 8963};
@@ -8854,10 +8978,10 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
8854 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 8978 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8855 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 8979 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8856 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 8980 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8857 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 8981 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
8858 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 8982 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8859 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 8983 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8860 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 8984 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
8861 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 8985 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8862 { } /* end */ 8986 { } /* end */
8863}; 8987};
@@ -8878,10 +9002,10 @@ static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
8878 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9002 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8879 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9003 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8880 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT), 9004 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
8881 HDA_CODEC_VOLUME("Mic Boost", 0x1b, 0, HDA_INPUT), 9005 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
8882 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT), 9006 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
8883 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9007 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8884 HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), 9008 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
8885 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9009 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8886 { } /* end */ 9010 { } /* end */
8887}; 9011};
@@ -8901,10 +9025,10 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = {
8901 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9025 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8902 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9026 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8903 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9027 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8904 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9028 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8905 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9029 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8906 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9030 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8907 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9031 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8908 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9032 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8909 { } /* end */ 9033 { } /* end */
8910}; 9034};
@@ -8925,7 +9049,7 @@ static struct snd_kcontrol_new alc883_targa_mixer[] = {
8925 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9049 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8926 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9050 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8927 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8928 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9052 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8929 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8930 { } /* end */ 9054 { } /* end */
8931}; 9055};
@@ -8938,20 +9062,20 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
8938 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9062 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8939 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9063 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8940 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9064 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8941 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9065 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8942 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8943 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9067 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8944 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 9068 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8945 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9069 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8946 { } /* end */ 9070 { } /* end */
8947}; 9071};
8948 9072
8949static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { 9073static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
8950 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), 9074 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8951 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), 9075 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8952 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9076 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8953 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 9077 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8954 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9078 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8955 { } /* end */ 9079 { } /* end */
8956}; 9080};
8957 9081
@@ -8962,7 +9086,7 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
8962 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), 9086 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8963 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 9087 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8964 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9088 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8965 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9089 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8966 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9090 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8967 { } /* end */ 9091 { } /* end */
8968}; 9092};
@@ -8975,21 +9099,8 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
8975 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9099 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9100 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8977 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9101 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8978 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9102 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8979 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9103 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8980 { } /* end */
8981};
8982
8983static struct snd_kcontrol_new alc883_medion_md2_mixer[] = {
8984 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8985 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8986 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8987 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8988 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8990 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8991 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8992 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8993 { } /* end */ 9104 { } /* end */
8994}; 9105};
8995 9106
@@ -9036,7 +9147,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9036 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9147 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9037 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9148 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9038 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9039 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9150 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9040 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9151 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9041 { } /* end */ 9152 { } /* end */
9042}; 9153};
@@ -9049,7 +9160,7 @@ static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9049 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 9160 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9050 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 9161 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9051 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9052 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9163 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9164 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9054 { } /* end */ 9165 { } /* end */
9055}; 9166};
@@ -9071,10 +9182,10 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9071 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9182 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9072 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9183 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9073 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9184 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9074 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9185 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9075 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9186 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9076 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9187 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9077 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 9188 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9078 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9189 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9079 { } /* end */ 9190 { } /* end */
9080}; 9191};
@@ -9095,8 +9206,8 @@ static struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9095 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT), 9206 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9096 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT), 9207 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9097 /* Boost mixers */ 9208 /* Boost mixers */
9098 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0x00, HDA_INPUT), 9209 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9099 HDA_CODEC_VOLUME("Line Boost", 0x1a, 0x00, HDA_INPUT), 9210 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9100 /* Input mixers */ 9211 /* Input mixers */
9101 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT), 9212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9102 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT), 9213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
@@ -9110,7 +9221,7 @@ static struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9110 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 9221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9111 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 9222 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 9223 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9113 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 9224 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9114 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 9225 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9115 { } /* end */ 9226 { } /* end */
9116}; 9227};
@@ -9140,7 +9251,7 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9140 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 9251 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9141 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 9252 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9142 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 9253 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9143 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 9254 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9144 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 9255 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9145 { } /* end */ 9256 { } /* end */
9146}; 9257};
@@ -9181,16 +9292,6 @@ static void alc883_mitac_setup(struct hda_codec *codec)
9181 spec->autocfg.speaker_pins[1] = 0x17; 9292 spec->autocfg.speaker_pins[1] = 0x17;
9182} 9293}
9183 9294
9184/* auto-toggle front mic */
9185/*
9186static void alc883_mitac_mic_automute(struct hda_codec *codec)
9187{
9188 unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0;
9189
9190 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
9191}
9192*/
9193
9194static struct hda_verb alc883_mitac_verbs[] = { 9295static struct hda_verb alc883_mitac_verbs[] = {
9195 /* HP */ 9296 /* HP */
9196 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, 9297 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
@@ -9434,18 +9535,8 @@ static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec,
9434 alc888_lenovo_ms7195_rca_automute(codec); 9535 alc888_lenovo_ms7195_rca_automute(codec);
9435} 9536}
9436 9537
9437static struct hda_verb alc883_medion_md2_verbs[] = {
9438 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9439 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9440
9441 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9442
9443 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9444 { } /* end */
9445};
9446
9447/* toggle speaker-output according to the hp-jack state */ 9538/* toggle speaker-output according to the hp-jack state */
9448static void alc883_medion_md2_setup(struct hda_codec *codec) 9539static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9449{ 9540{
9450 struct alc_spec *spec = codec->spec; 9541 struct alc_spec *spec = codec->spec;
9451 9542
@@ -9457,15 +9548,6 @@ static void alc883_medion_md2_setup(struct hda_codec *codec)
9457#define alc883_targa_init_hook alc882_targa_init_hook 9548#define alc883_targa_init_hook alc882_targa_init_hook
9458#define alc883_targa_unsol_event alc882_targa_unsol_event 9549#define alc883_targa_unsol_event alc882_targa_unsol_event
9459 9550
9460static void alc883_clevo_m720_mic_automute(struct hda_codec *codec)
9461{
9462 unsigned int present;
9463
9464 present = snd_hda_jack_detect(codec, 0x18);
9465 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
9466 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9467}
9468
9469static void alc883_clevo_m720_setup(struct hda_codec *codec) 9551static void alc883_clevo_m720_setup(struct hda_codec *codec)
9470{ 9552{
9471 struct alc_spec *spec = codec->spec; 9553 struct alc_spec *spec = codec->spec;
@@ -9477,7 +9559,7 @@ static void alc883_clevo_m720_setup(struct hda_codec *codec)
9477static void alc883_clevo_m720_init_hook(struct hda_codec *codec) 9559static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9478{ 9560{
9479 alc_automute_amp(codec); 9561 alc_automute_amp(codec);
9480 alc883_clevo_m720_mic_automute(codec); 9562 alc88x_simple_mic_automute(codec);
9481} 9563}
9482 9564
9483static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, 9565static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
@@ -9485,7 +9567,7 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9485{ 9567{
9486 switch (res >> 26) { 9568 switch (res >> 26) {
9487 case ALC880_MIC_EVENT: 9569 case ALC880_MIC_EVENT:
9488 alc883_clevo_m720_mic_automute(codec); 9570 alc88x_simple_mic_automute(codec);
9489 break; 9571 break;
9490 default: 9572 default:
9491 alc_automute_amp_unsol_event(codec, res); 9573 alc_automute_amp_unsol_event(codec, res);
@@ -9701,7 +9783,7 @@ static hda_nid_t alc1200_slave_dig_outs[] = {
9701/* 9783/*
9702 * configuration and preset 9784 * configuration and preset
9703 */ 9785 */
9704static const char *alc882_models[ALC882_MODEL_LAST] = { 9786static const char * const alc882_models[ALC882_MODEL_LAST] = {
9705 [ALC882_3ST_DIG] = "3stack-dig", 9787 [ALC882_3ST_DIG] = "3stack-dig",
9706 [ALC882_6ST_DIG] = "6stack-dig", 9788 [ALC882_6ST_DIG] = "6stack-dig",
9707 [ALC882_ARIMA] = "arima", 9789 [ALC882_ARIMA] = "arima",
@@ -9730,7 +9812,6 @@ static const char *alc882_models[ALC882_MODEL_LAST] = {
9730 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", 9812 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9731 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", 9813 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9732 [ALC883_MEDION] = "medion", 9814 [ALC883_MEDION] = "medion",
9733 [ALC883_MEDION_MD2] = "medion-md2",
9734 [ALC883_MEDION_WIM2160] = "medion-wim2160", 9815 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9735 [ALC883_LAPTOP_EAPD] = "laptop-eapd", 9816 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9736 [ALC883_LENOVO_101E_2ch] = "lenovo-101e", 9817 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
@@ -10378,19 +10459,6 @@ static struct alc_config_preset alc882_presets[] = {
10378 .channel_mode = alc883_sixstack_modes, 10459 .channel_mode = alc883_sixstack_modes,
10379 .input_mux = &alc883_capture_source, 10460 .input_mux = &alc883_capture_source,
10380 }, 10461 },
10381 [ALC883_MEDION_MD2] = {
10382 .mixers = { alc883_medion_md2_mixer},
10383 .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs},
10384 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10385 .dac_nids = alc883_dac_nids,
10386 .dig_out_nid = ALC883_DIGOUT_NID,
10387 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10388 .channel_mode = alc883_3ST_2ch_modes,
10389 .input_mux = &alc883_capture_source,
10390 .unsol_event = alc_automute_amp_unsol_event,
10391 .setup = alc883_medion_md2_setup,
10392 .init_hook = alc_automute_amp,
10393 },
10394 [ALC883_MEDION_WIM2160] = { 10462 [ALC883_MEDION_WIM2160] = {
10395 .mixers = { alc883_medion_wim2160_mixer }, 10463 .mixers = { alc883_medion_wim2160_mixer },
10396 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, 10464 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
@@ -10467,7 +10535,7 @@ static struct alc_config_preset alc882_presets[] = {
10467 .need_dac_fix = 1, 10535 .need_dac_fix = 1,
10468 .input_mux = &alc883_lenovo_nb0763_capture_source, 10536 .input_mux = &alc883_lenovo_nb0763_capture_source,
10469 .unsol_event = alc_automute_amp_unsol_event, 10537 .unsol_event = alc_automute_amp_unsol_event,
10470 .setup = alc883_medion_md2_setup, 10538 .setup = alc883_lenovo_nb0763_setup,
10471 .init_hook = alc_automute_amp, 10539 .init_hook = alc_automute_amp,
10472 }, 10540 },
10473 [ALC888_LENOVO_MS7195_DIG] = { 10541 [ALC888_LENOVO_MS7195_DIG] = {
@@ -10666,7 +10734,8 @@ enum {
10666 10734
10667static const struct alc_fixup alc882_fixups[] = { 10735static const struct alc_fixup alc882_fixups[] = {
10668 [PINFIX_ABIT_AW9D_MAX] = { 10736 [PINFIX_ABIT_AW9D_MAX] = {
10669 .pins = (const struct alc_pincfg[]) { 10737 .type = ALC_FIXUP_PINS,
10738 .v.pins = (const struct alc_pincfg[]) {
10670 { 0x15, 0x01080104 }, /* side */ 10739 { 0x15, 0x01080104 }, /* side */
10671 { 0x16, 0x01011012 }, /* rear */ 10740 { 0x16, 0x01011012 }, /* rear */
10672 { 0x17, 0x01016011 }, /* clfe */ 10741 { 0x17, 0x01016011 }, /* clfe */
@@ -10674,13 +10743,15 @@ static const struct alc_fixup alc882_fixups[] = {
10674 } 10743 }
10675 }, 10744 },
10676 [PINFIX_PB_M5210] = { 10745 [PINFIX_PB_M5210] = {
10677 .verbs = (const struct hda_verb[]) { 10746 .type = ALC_FIXUP_VERBS,
10747 .v.verbs = (const struct hda_verb[]) {
10678 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 }, 10748 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
10679 {} 10749 {}
10680 } 10750 }
10681 }, 10751 },
10682 [PINFIX_ACER_ASPIRE_7736] = { 10752 [PINFIX_ACER_ASPIRE_7736] = {
10683 .sku = ALC_FIXUP_SKU_IGNORE, 10753 .type = ALC_FIXUP_SKU,
10754 .v.sku = ALC_FIXUP_SKU_IGNORE,
10684 }, 10755 },
10685}; 10756};
10686 10757
@@ -10830,17 +10901,29 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec)
10830 struct alc_spec *spec = codec->spec; 10901 struct alc_spec *spec = codec->spec;
10831 struct auto_pin_cfg *cfg = &spec->autocfg; 10902 struct auto_pin_cfg *cfg = &spec->autocfg;
10832 int i, err; 10903 int i, err;
10904 int type_idx = 0;
10833 hda_nid_t nid; 10905 hda_nid_t nid;
10906 const char *prev_label = NULL;
10834 10907
10835 for (i = 0; i < cfg->num_inputs; i++) { 10908 for (i = 0; i < cfg->num_inputs; i++) {
10836 if (cfg->inputs[i].type > AUTO_PIN_MIC) 10909 if (cfg->inputs[i].type > AUTO_PIN_MIC)
10837 break; 10910 break;
10838 nid = cfg->inputs[i].pin; 10911 nid = cfg->inputs[i].pin;
10839 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { 10912 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10840 char label[32]; 10913 const char *label;
10841 snprintf(label, sizeof(label), "%s Boost", 10914 char boost_label[32];
10842 hda_get_autocfg_input_label(codec, cfg, i)); 10915
10843 err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0, 10916 label = hda_get_autocfg_input_label(codec, cfg, i);
10917 if (prev_label && !strcmp(label, prev_label))
10918 type_idx++;
10919 else
10920 type_idx = 0;
10921 prev_label = label;
10922
10923 snprintf(boost_label, sizeof(boost_label),
10924 "%s Boost Volume", label);
10925 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10926 boost_label, type_idx,
10844 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); 10927 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10845 if (err < 0) 10928 if (err < 0)
10846 return err; 10929 return err;
@@ -10954,8 +11037,10 @@ static int patch_alc882(struct hda_codec *codec)
10954 board_config = ALC882_AUTO; 11037 board_config = ALC882_AUTO;
10955 } 11038 }
10956 11039
10957 if (board_config == ALC882_AUTO) 11040 if (board_config == ALC882_AUTO) {
10958 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); 11041 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11042 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11043 }
10959 11044
10960 alc_auto_parse_customize_define(codec); 11045 alc_auto_parse_customize_define(codec);
10961 11046
@@ -11031,8 +11116,7 @@ static int patch_alc882(struct hda_codec *codec)
11031 if (has_cdefine_beep(codec)) 11116 if (has_cdefine_beep(codec))
11032 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 11117 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11033 11118
11034 if (board_config == ALC882_AUTO) 11119 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11035 alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0);
11036 11120
11037 spec->vmaster_nid = 0x0c; 11121 spec->vmaster_nid = 0x0c;
11038 11122
@@ -11082,10 +11166,10 @@ static struct snd_kcontrol_new alc262_base_mixer[] = {
11082 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11166 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11083 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11167 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11084 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11168 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11085 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11169 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11086 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11170 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11087 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11171 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11088 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11172 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11089 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), 11173 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11090 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11091 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), 11175 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
@@ -11186,10 +11270,10 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11186 HDA_OUTPUT), 11270 HDA_OUTPUT),
11187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11271 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11188 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11272 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11189 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11190 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11274 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11191 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11275 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11192 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11276 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11193 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 11277 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11194 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11278 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11195 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11279 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -11211,7 +11295,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11211 HDA_OUTPUT), 11295 HDA_OUTPUT),
11212 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT), 11296 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11213 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT), 11297 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11214 HDA_CODEC_VOLUME("Front Mic Boost", 0x1a, 0, HDA_INPUT), 11298 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11215 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT), 11299 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11216 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), 11300 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11217 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11301 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
@@ -11222,7 +11306,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11222static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { 11306static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11223 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11307 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11224 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11308 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11225 HDA_CODEC_VOLUME("Rear Mic Boost", 0x18, 0, HDA_INPUT), 11309 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11226 { } /* end */ 11310 { } /* end */
11227}; 11311};
11228 11312
@@ -11242,7 +11326,7 @@ static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11242 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11326 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11243 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11327 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11244 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11328 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11245 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11329 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11246 { } /* end */ 11330 { } /* end */
11247}; 11331};
11248 11332
@@ -11349,10 +11433,10 @@ static struct snd_kcontrol_new alc262_hippo_mixer[] = {
11349 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11433 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11350 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11434 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11351 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11435 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11352 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11436 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11353 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11437 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11354 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11438 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11355 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11439 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11356 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11440 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11357 { } /* end */ 11441 { } /* end */
11358}; 11442};
@@ -11366,10 +11450,10 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11366 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11450 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11367 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11451 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11368 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11452 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11369 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11453 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11370 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11454 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11371 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11455 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11372 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11456 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11373 { } /* end */ 11457 { } /* end */
11374}; 11458};
11375 11459
@@ -11437,10 +11521,10 @@ static struct snd_kcontrol_new alc262_tyan_mixer[] = {
11437 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 11521 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11438 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11522 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11439 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11523 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11440 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11524 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11441 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11525 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11442 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11526 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11443 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11527 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11444 { } /* end */ 11528 { } /* end */
11445}; 11529};
11446 11530
@@ -11624,7 +11708,7 @@ static struct snd_kcontrol_new alc262_nec_mixer[] = {
11624 11708
11625 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11709 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11626 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11710 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11627 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11711 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11628 11712
11629 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), 11713 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11630 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 11714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
@@ -11679,7 +11763,7 @@ static struct hda_input_mux alc262_fujitsu_capture_source = {
11679 .num_items = 3, 11763 .num_items = 3,
11680 .items = { 11764 .items = {
11681 { "Mic", 0x0 }, 11765 { "Mic", 0x0 },
11682 { "Int Mic", 0x1 }, 11766 { "Internal Mic", 0x1 },
11683 { "CD", 0x4 }, 11767 { "CD", 0x4 },
11684 }, 11768 },
11685}; 11769};
@@ -11831,12 +11915,12 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11831 }, 11915 },
11832 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11916 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11833 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11917 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11834 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11918 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11835 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11919 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11836 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11920 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11837 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11921 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11838 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11922 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11839 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11923 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11840 { } /* end */ 11924 { } /* end */
11841}; 11925};
11842 11926
@@ -11867,12 +11951,12 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11867 }, 11951 },
11868 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), 11952 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11869 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), 11953 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11870 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11954 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11871 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11955 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11872 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11956 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11873 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 11957 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11874 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 11958 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11875 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 11959 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11876 { } /* end */ 11960 { } /* end */
11877}; 11961};
11878 11962
@@ -11881,10 +11965,10 @@ static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11881 ALC262_HIPPO_MASTER_SWITCH, 11965 ALC262_HIPPO_MASTER_SWITCH,
11882 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 11966 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11883 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 11967 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11884 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 11968 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11885 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11969 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11886 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11970 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11887 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 11971 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11888 { } /* end */ 11972 { } /* end */
11889}; 11973};
11890 11974
@@ -11910,8 +11994,8 @@ static struct snd_kcontrol_new alc262_ultra_mixer[] = {
11910 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), 11994 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11911 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 11995 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11912 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 11996 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11913 HDA_CODEC_VOLUME("Mic Boost", 0x19, 0, HDA_INPUT), 11997 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11914 HDA_CODEC_VOLUME("Headphone Mic Boost", 0x15, 0, HDA_INPUT), 11998 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
11915 { } /* end */ 11999 { } /* end */
11916}; 12000};
11917 12001
@@ -12081,13 +12165,8 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12081 spec->multiout.dac_nids = spec->private_dac_nids; 12165 spec->multiout.dac_nids = spec->private_dac_nids;
12082 spec->multiout.dac_nids[0] = 2; 12166 spec->multiout.dac_nids[0] = 2;
12083 12167
12084 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0]) 12168 pfx = alc_get_line_out_pfx(cfg, true);
12085 pfx = "Master"; 12169 if (!pfx)
12086 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
12087 pfx = "Speaker";
12088 else if (cfg->line_out_type == AUTO_PIN_HP_OUT)
12089 pfx = "Headphone";
12090 else
12091 pfx = "Front"; 12170 pfx = "Front";
12092 for (i = 0; i < 2; i++) { 12171 for (i = 0; i < 2; i++) {
12093 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i); 12172 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
@@ -12427,19 +12506,14 @@ enum {
12427 12506
12428static const struct alc_fixup alc262_fixups[] = { 12507static const struct alc_fixup alc262_fixups[] = {
12429 [PINFIX_FSC_H270] = { 12508 [PINFIX_FSC_H270] = {
12430 .pins = (const struct alc_pincfg[]) { 12509 .type = ALC_FIXUP_PINS,
12510 .v.pins = (const struct alc_pincfg[]) {
12431 { 0x14, 0x99130110 }, /* speaker */ 12511 { 0x14, 0x99130110 }, /* speaker */
12432 { 0x15, 0x0221142f }, /* front HP */ 12512 { 0x15, 0x0221142f }, /* front HP */
12433 { 0x1b, 0x0121141f }, /* rear HP */ 12513 { 0x1b, 0x0121141f }, /* rear HP */
12434 { } 12514 { }
12435 } 12515 }
12436 }, 12516 },
12437 [PINFIX_PB_M5210] = {
12438 .verbs = (const struct hda_verb[]) {
12439 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
12440 {}
12441 }
12442 },
12443}; 12517};
12444 12518
12445static struct snd_pci_quirk alc262_fixup_tbl[] = { 12519static struct snd_pci_quirk alc262_fixup_tbl[] = {
@@ -12529,7 +12603,7 @@ static void alc262_auto_init(struct hda_codec *codec)
12529/* 12603/*
12530 * configuration and preset 12604 * configuration and preset
12531 */ 12605 */
12532static const char *alc262_models[ALC262_MODEL_LAST] = { 12606static const char * const alc262_models[ALC262_MODEL_LAST] = {
12533 [ALC262_BASIC] = "basic", 12607 [ALC262_BASIC] = "basic",
12534 [ALC262_HIPPO] = "hippo", 12608 [ALC262_HIPPO] = "hippo",
12535 [ALC262_HIPPO_1] = "hippo_1", 12609 [ALC262_HIPPO_1] = "hippo_1",
@@ -12557,6 +12631,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
12557 ALC262_HP_BPC), 12631 ALC262_HP_BPC),
12558 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", 12632 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12559 ALC262_HP_BPC), 12633 ALC262_HP_BPC),
12634 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12635 ALC262_HP_BPC),
12560 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", 12636 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12561 ALC262_HP_BPC), 12637 ALC262_HP_BPC),
12562 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), 12638 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
@@ -12870,8 +12946,10 @@ static int patch_alc262(struct hda_codec *codec)
12870 board_config = ALC262_AUTO; 12946 board_config = ALC262_AUTO;
12871 } 12947 }
12872 12948
12873 if (board_config == ALC262_AUTO) 12949 if (board_config == ALC262_AUTO) {
12874 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 1); 12950 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12951 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12952 }
12875 12953
12876 if (board_config == ALC262_AUTO) { 12954 if (board_config == ALC262_AUTO) {
12877 /* automatic parse from the BIOS config */ 12955 /* automatic parse from the BIOS config */
@@ -12941,8 +13019,7 @@ static int patch_alc262(struct hda_codec *codec)
12941 if (!spec->no_analog && has_cdefine_beep(codec)) 13019 if (!spec->no_analog && has_cdefine_beep(codec))
12942 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); 13020 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
12943 13021
12944 if (board_config == ALC262_AUTO) 13022 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
12945 alc_pick_fixup(codec, alc262_fixup_tbl, alc262_fixups, 0);
12946 13023
12947 spec->vmaster_nid = 0x0c; 13024 spec->vmaster_nid = 0x0c;
12948 13025
@@ -12988,9 +13065,9 @@ static struct snd_kcontrol_new alc268_base_mixer[] = {
12988 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13065 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12989 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13066 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12990 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13067 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12991 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13068 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12992 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 13069 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12993 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13070 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12994 { } 13071 { }
12995}; 13072};
12996 13073
@@ -12999,9 +13076,9 @@ static struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12999 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), 13076 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13000 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), 13077 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13001 ALC262_HIPPO_MASTER_SWITCH, 13078 ALC262_HIPPO_MASTER_SWITCH,
13002 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13079 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13003 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 13080 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13004 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13081 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13005 { } 13082 { }
13006}; 13083};
13007 13084
@@ -13105,9 +13182,9 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = {
13105 .put = alc268_acer_master_sw_put, 13182 .put = alc268_acer_master_sw_put,
13106 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13183 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13107 }, 13184 },
13108 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13185 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13109 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13186 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13110 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13187 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13111 { } 13188 { }
13112}; 13189};
13113 13190
@@ -13123,8 +13200,8 @@ static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13123 .put = alc268_acer_master_sw_put, 13200 .put = alc268_acer_master_sw_put,
13124 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), 13201 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13125 }, 13202 },
13126 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13203 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13127 HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), 13204 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13128 { } 13205 { }
13129}; 13206};
13130 13207
@@ -13216,8 +13293,8 @@ static struct snd_kcontrol_new alc268_dell_mixer[] = {
13216 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), 13293 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13217 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 13294 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13218 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13295 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13219 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 13296 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13220 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 13297 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13221 { } 13298 { }
13222}; 13299};
13223 13300
@@ -13250,8 +13327,8 @@ static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13250 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 13327 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13251 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), 13328 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13252 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), 13329 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13253 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 13330 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13254 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 13331 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13255 { } 13332 { }
13256}; 13333};
13257 13334
@@ -13716,7 +13793,7 @@ static void alc268_auto_init(struct hda_codec *codec)
13716/* 13793/*
13717 * configuration and preset 13794 * configuration and preset
13718 */ 13795 */
13719static const char *alc268_models[ALC268_MODEL_LAST] = { 13796static const char * const alc268_models[ALC268_MODEL_LAST] = {
13720 [ALC267_QUANTA_IL1] = "quanta-il1", 13797 [ALC267_QUANTA_IL1] = "quanta-il1",
13721 [ALC268_3ST] = "3stack", 13798 [ALC268_3ST] = "3stack",
13722 [ALC268_TOSHIBA] = "toshiba", 13799 [ALC268_TOSHIBA] = "toshiba",
@@ -14074,10 +14151,10 @@ static struct snd_kcontrol_new alc269_base_mixer[] = {
14074 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 14151 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14075 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14152 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14076 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14153 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14077 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14154 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14078 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14155 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14079 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14156 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14080 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 14157 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14081 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), 14158 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14082 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), 14159 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14083 { } /* end */ 14160 { } /* end */
@@ -14097,10 +14174,10 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14097 }, 14174 },
14098 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14175 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14099 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14176 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14100 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14177 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14101 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14178 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14102 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14179 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14103 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 14180 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14104 { } 14181 { }
14105}; 14182};
14106 14183
@@ -14118,13 +14195,13 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14118 }, 14195 },
14119 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 14196 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14120 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 14197 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14121 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14198 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14122 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), 14199 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14123 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), 14200 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14124 HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), 14201 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14125 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), 14202 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14126 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), 14203 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14127 HDA_CODEC_VOLUME("Dock Mic Boost", 0x1b, 0, HDA_INPUT), 14204 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14128 { } 14205 { }
14129}; 14206};
14130 14207
@@ -14154,30 +14231,30 @@ static struct snd_kcontrol_new alc269_asus_mixer[] = {
14154static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { 14231static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14155 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14232 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14156 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14233 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14157 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14234 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14158 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 14235 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14159 { } /* end */ 14236 { } /* end */
14160}; 14237};
14161 14238
14162static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { 14239static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14163 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), 14240 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14164 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), 14241 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14165 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14242 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14166 { } /* end */ 14243 { } /* end */
14167}; 14244};
14168 14245
14169static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { 14246static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14170 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14247 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14171 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14248 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14172 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14249 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14173 HDA_CODEC_VOLUME("IntMic Boost", 0x19, 0, HDA_INPUT), 14250 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14174 { } /* end */ 14251 { } /* end */
14175}; 14252};
14176 14253
14177static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { 14254static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14178 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), 14255 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14179 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), 14256 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14180 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 14257 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14181 { } /* end */ 14258 { } /* end */
14182}; 14259};
14183 14260
@@ -14796,31 +14873,92 @@ static int alc269_resume(struct hda_codec *codec)
14796} 14873}
14797#endif /* SND_HDA_NEEDS_RESUME */ 14874#endif /* SND_HDA_NEEDS_RESUME */
14798 14875
14876static void alc269_fixup_hweq(struct hda_codec *codec,
14877 const struct alc_fixup *fix, int action)
14878{
14879 int coef;
14880
14881 if (action != ALC_FIXUP_ACT_INIT)
14882 return;
14883 coef = alc_read_coef_idx(codec, 0x1e);
14884 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14885}
14886
14799enum { 14887enum {
14800 ALC269_FIXUP_SONY_VAIO, 14888 ALC269_FIXUP_SONY_VAIO,
14889 ALC275_FIXUP_SONY_VAIO_GPIO2,
14801 ALC269_FIXUP_DELL_M101Z, 14890 ALC269_FIXUP_DELL_M101Z,
14891 ALC269_FIXUP_SKU_IGNORE,
14892 ALC269_FIXUP_ASUS_G73JW,
14893 ALC269_FIXUP_LENOVO_EAPD,
14894 ALC275_FIXUP_SONY_HWEQ,
14802}; 14895};
14803 14896
14804static const struct alc_fixup alc269_fixups[] = { 14897static const struct alc_fixup alc269_fixups[] = {
14805 [ALC269_FIXUP_SONY_VAIO] = { 14898 [ALC269_FIXUP_SONY_VAIO] = {
14806 .verbs = (const struct hda_verb[]) { 14899 .type = ALC_FIXUP_VERBS,
14900 .v.verbs = (const struct hda_verb[]) {
14807 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, 14901 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14808 {} 14902 {}
14809 } 14903 }
14810 }, 14904 },
14905 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14906 .type = ALC_FIXUP_VERBS,
14907 .v.verbs = (const struct hda_verb[]) {
14908 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14909 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14910 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14911 { }
14912 },
14913 .chained = true,
14914 .chain_id = ALC269_FIXUP_SONY_VAIO
14915 },
14811 [ALC269_FIXUP_DELL_M101Z] = { 14916 [ALC269_FIXUP_DELL_M101Z] = {
14812 .verbs = (const struct hda_verb[]) { 14917 .type = ALC_FIXUP_VERBS,
14918 .v.verbs = (const struct hda_verb[]) {
14813 /* Enables internal speaker */ 14919 /* Enables internal speaker */
14814 {0x20, AC_VERB_SET_COEF_INDEX, 13}, 14920 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14815 {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, 14921 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14816 {} 14922 {}
14817 } 14923 }
14818 }, 14924 },
14925 [ALC269_FIXUP_SKU_IGNORE] = {
14926 .type = ALC_FIXUP_SKU,
14927 .v.sku = ALC_FIXUP_SKU_IGNORE,
14928 },
14929 [ALC269_FIXUP_ASUS_G73JW] = {
14930 .type = ALC_FIXUP_PINS,
14931 .v.pins = (const struct alc_pincfg[]) {
14932 { 0x17, 0x99130111 }, /* subwoofer */
14933 { }
14934 }
14935 },
14936 [ALC269_FIXUP_LENOVO_EAPD] = {
14937 .type = ALC_FIXUP_VERBS,
14938 .v.verbs = (const struct hda_verb[]) {
14939 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14940 {}
14941 }
14942 },
14943 [ALC275_FIXUP_SONY_HWEQ] = {
14944 .type = ALC_FIXUP_FUNC,
14945 .v.func = alc269_fixup_hweq,
14946 .chained = true,
14947 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14948 }
14819}; 14949};
14820 14950
14821static struct snd_pci_quirk alc269_fixup_tbl[] = { 14951static struct snd_pci_quirk alc269_fixup_tbl[] = {
14952 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14953 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14954 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14822 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 14955 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14823 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 14956 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14957 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14958 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14959 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14960 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14961 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14824 {} 14962 {}
14825}; 14963};
14826 14964
@@ -14828,7 +14966,7 @@ static struct snd_pci_quirk alc269_fixup_tbl[] = {
14828/* 14966/*
14829 * configuration and preset 14967 * configuration and preset
14830 */ 14968 */
14831static const char *alc269_models[ALC269_MODEL_LAST] = { 14969static const char * const alc269_models[ALC269_MODEL_LAST] = {
14832 [ALC269_BASIC] = "basic", 14970 [ALC269_BASIC] = "basic",
14833 [ALC269_QUANTA_FL1] = "quanta", 14971 [ALC269_QUANTA_FL1] = "quanta",
14834 [ALC269_AMIC] = "laptop-amic", 14972 [ALC269_AMIC] = "laptop-amic",
@@ -15070,28 +15208,29 @@ static int patch_alc269(struct hda_codec *codec)
15070 15208
15071 alc_auto_parse_customize_define(codec); 15209 alc_auto_parse_customize_define(codec);
15072 15210
15073 coef = alc_read_coef_idx(codec, 0); 15211 if (codec->vendor_id == 0x10ec0269) {
15074 if ((coef & 0x00f0) == 0x0010) { 15212 coef = alc_read_coef_idx(codec, 0);
15075 if (codec->bus->pci->subsystem_vendor == 0x1025 && 15213 if ((coef & 0x00f0) == 0x0010) {
15076 spec->cdefine.platform_type == 1) { 15214 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15077 alc_codec_rename(codec, "ALC271X"); 15215 spec->cdefine.platform_type == 1) {
15078 spec->codec_variant = ALC269_TYPE_ALC271X; 15216 alc_codec_rename(codec, "ALC271X");
15079 } else if ((coef & 0xf000) == 0x1000) { 15217 spec->codec_variant = ALC269_TYPE_ALC271X;
15080 spec->codec_variant = ALC269_TYPE_ALC270; 15218 } else if ((coef & 0xf000) == 0x1000) {
15081 } else if ((coef & 0xf000) == 0x2000) { 15219 spec->codec_variant = ALC269_TYPE_ALC270;
15082 alc_codec_rename(codec, "ALC259"); 15220 } else if ((coef & 0xf000) == 0x2000) {
15083 spec->codec_variant = ALC269_TYPE_ALC259; 15221 alc_codec_rename(codec, "ALC259");
15084 } else if ((coef & 0xf000) == 0x3000) { 15222 spec->codec_variant = ALC269_TYPE_ALC259;
15085 alc_codec_rename(codec, "ALC258"); 15223 } else if ((coef & 0xf000) == 0x3000) {
15086 spec->codec_variant = ALC269_TYPE_ALC258; 15224 alc_codec_rename(codec, "ALC258");
15087 } else { 15225 spec->codec_variant = ALC269_TYPE_ALC258;
15088 alc_codec_rename(codec, "ALC269VB"); 15226 } else {
15089 spec->codec_variant = ALC269_TYPE_ALC269VB; 15227 alc_codec_rename(codec, "ALC269VB");
15090 } 15228 spec->codec_variant = ALC269_TYPE_ALC269VB;
15091 } else 15229 }
15092 alc_fix_pll_init(codec, 0x20, 0x04, 15); 15230 } else
15093 15231 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15094 alc269_fill_coef(codec); 15232 alc269_fill_coef(codec);
15233 }
15095 15234
15096 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 15235 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15097 alc269_models, 15236 alc269_models,
@@ -15103,8 +15242,10 @@ static int patch_alc269(struct hda_codec *codec)
15103 board_config = ALC269_AUTO; 15242 board_config = ALC269_AUTO;
15104 } 15243 }
15105 15244
15106 if (board_config == ALC269_AUTO) 15245 if (board_config == ALC269_AUTO) {
15107 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); 15246 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15247 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15248 }
15108 15249
15109 if (board_config == ALC269_AUTO) { 15250 if (board_config == ALC269_AUTO) {
15110 /* automatic parse from the BIOS config */ 15251 /* automatic parse from the BIOS config */
@@ -15165,8 +15306,7 @@ static int patch_alc269(struct hda_codec *codec)
15165 if (has_cdefine_beep(codec)) 15306 if (has_cdefine_beep(codec))
15166 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); 15307 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
15167 15308
15168 if (board_config == ALC269_AUTO) 15309 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15169 alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0);
15170 15310
15171 spec->vmaster_nid = 0x02; 15311 spec->vmaster_nid = 0x02;
15172 15312
@@ -15854,41 +15994,33 @@ static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15854 return 0; 15994 return 0;
15855} 15995}
15856 15996
15857static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, 15997static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
15858 hda_nid_t nid, unsigned int chs) 15998 hda_nid_t nid, int idx, unsigned int chs)
15859{ 15999{
15860 return add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, 16000 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
15861 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 16001 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
15862} 16002}
15863 16003
16004#define alc861_create_out_sw(codec, pfx, nid, chs) \
16005 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
16006
15864/* add playback controls from the parsed DAC table */ 16007/* add playback controls from the parsed DAC table */
15865static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, 16008static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15866 const struct auto_pin_cfg *cfg) 16009 const struct auto_pin_cfg *cfg)
15867{ 16010{
15868 struct alc_spec *spec = codec->spec; 16011 struct alc_spec *spec = codec->spec;
15869 static const char *chname[4] = { 16012 static const char * const chname[4] = {
15870 "Front", "Surround", NULL /*CLFE*/, "Side" 16013 "Front", "Surround", NULL /*CLFE*/, "Side"
15871 }; 16014 };
16015 const char *pfx = alc_get_line_out_pfx(cfg, true);
15872 hda_nid_t nid; 16016 hda_nid_t nid;
15873 int i, err; 16017 int i, err;
15874 16018
15875 if (cfg->line_outs == 1) {
15876 const char *pfx = NULL;
15877 if (!cfg->hp_outs)
15878 pfx = "Master";
15879 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
15880 pfx = "Speaker";
15881 if (pfx) {
15882 nid = spec->multiout.dac_nids[0];
15883 return alc861_create_out_sw(codec, pfx, nid, 3);
15884 }
15885 }
15886
15887 for (i = 0; i < cfg->line_outs; i++) { 16019 for (i = 0; i < cfg->line_outs; i++) {
15888 nid = spec->multiout.dac_nids[i]; 16020 nid = spec->multiout.dac_nids[i];
15889 if (!nid) 16021 if (!nid)
15890 continue; 16022 continue;
15891 if (i == 2) { 16023 if (!pfx && i == 2) {
15892 /* Center/LFE */ 16024 /* Center/LFE */
15893 err = alc861_create_out_sw(codec, "Center", nid, 1); 16025 err = alc861_create_out_sw(codec, "Center", nid, 1);
15894 if (err < 0) 16026 if (err < 0)
@@ -15897,7 +16029,10 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
15897 if (err < 0) 16029 if (err < 0)
15898 return err; 16030 return err;
15899 } else { 16031 } else {
15900 err = alc861_create_out_sw(codec, chname[i], nid, 3); 16032 const char *name = pfx;
16033 if (!name)
16034 name = chname[i];
16035 err = __alc861_create_out_sw(codec, name, nid, i, 3);
15901 if (err < 0) 16036 if (err < 0)
15902 return err; 16037 return err;
15903 } 16038 }
@@ -16080,7 +16215,7 @@ static struct hda_amp_list alc861_loopbacks[] = {
16080/* 16215/*
16081 * configuration and preset 16216 * configuration and preset
16082 */ 16217 */
16083static const char *alc861_models[ALC861_MODEL_LAST] = { 16218static const char * const alc861_models[ALC861_MODEL_LAST] = {
16084 [ALC861_3ST] = "3stack", 16219 [ALC861_3ST] = "3stack",
16085 [ALC660_3ST] = "3stack-660", 16220 [ALC660_3ST] = "3stack-660",
16086 [ALC861_3ST_DIG] = "3stack-dig", 16221 [ALC861_3ST_DIG] = "3stack-dig",
@@ -16230,7 +16365,8 @@ enum {
16230 16365
16231static const struct alc_fixup alc861_fixups[] = { 16366static const struct alc_fixup alc861_fixups[] = {
16232 [PINFIX_FSC_AMILO_PI1505] = { 16367 [PINFIX_FSC_AMILO_PI1505] = {
16233 .pins = (const struct alc_pincfg[]) { 16368 .type = ALC_FIXUP_PINS,
16369 .v.pins = (const struct alc_pincfg[]) {
16234 { 0x0b, 0x0221101f }, /* HP */ 16370 { 0x0b, 0x0221101f }, /* HP */
16235 { 0x0f, 0x90170310 }, /* speaker */ 16371 { 0x0f, 0x90170310 }, /* speaker */
16236 { } 16372 { }
@@ -16265,8 +16401,10 @@ static int patch_alc861(struct hda_codec *codec)
16265 board_config = ALC861_AUTO; 16401 board_config = ALC861_AUTO;
16266 } 16402 }
16267 16403
16268 if (board_config == ALC861_AUTO) 16404 if (board_config == ALC861_AUTO) {
16269 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1); 16405 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16406 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16407 }
16270 16408
16271 if (board_config == ALC861_AUTO) { 16409 if (board_config == ALC861_AUTO) {
16272 /* automatic parse from the BIOS config */ 16410 /* automatic parse from the BIOS config */
@@ -16303,8 +16441,7 @@ static int patch_alc861(struct hda_codec *codec)
16303 16441
16304 spec->vmaster_nid = 0x03; 16442 spec->vmaster_nid = 0x03;
16305 16443
16306 if (board_config == ALC861_AUTO) 16444 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16307 alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0);
16308 16445
16309 codec->patch_ops = alc_patch_ops; 16446 codec->patch_ops = alc_patch_ops;
16310 if (board_config == ALC861_AUTO) { 16447 if (board_config == ALC861_AUTO) {
@@ -16369,8 +16506,8 @@ static struct hda_input_mux alc861vd_capture_source = {
16369static struct hda_input_mux alc861vd_dallas_capture_source = { 16506static struct hda_input_mux alc861vd_dallas_capture_source = {
16370 .num_items = 2, 16507 .num_items = 2,
16371 .items = { 16508 .items = {
16372 { "Ext Mic", 0x0 }, 16509 { "Mic", 0x0 },
16373 { "Int Mic", 0x1 }, 16510 { "Internal Mic", 0x1 },
16374 }, 16511 },
16375}; 16512};
16376 16513
@@ -16449,11 +16586,11 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16449 16586
16450 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16587 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16451 16588
16452 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16589 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16453 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16590 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16454 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16591 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16455 16592
16456 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16593 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16457 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16594 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16458 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16595 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16459 16596
@@ -16472,11 +16609,11 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16472 16609
16473 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16610 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16474 16611
16475 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16612 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16476 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16613 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16477 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16614 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16478 16615
16479 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16616 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16480 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16617 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16481 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16618 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16482 16619
@@ -16496,11 +16633,11 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16496 16633
16497 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 16634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16498 16635
16499 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 16636 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16500 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16501 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16502 16639
16503 HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), 16640 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16504 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16641 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16505 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16642 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16506 16643
@@ -16511,19 +16648,19 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16511}; 16648};
16512 16649
16513/* Pin assignment: Speaker=0x14, HP = 0x15, 16650/* Pin assignment: Speaker=0x14, HP = 0x15,
16514 * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d 16651 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16515 */ 16652 */
16516static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { 16653static struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16517 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), 16654 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16518 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), 16655 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16519 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 16656 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16520 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), 16657 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16521 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 16658 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16522 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 16659 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16523 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 16660 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16524 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 16661 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16525 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 16662 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16526 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 16663 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16527 { } /* end */ 16664 { } /* end */
16528}; 16665};
16529 16666
@@ -16688,18 +16825,6 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16688 {} 16825 {}
16689}; 16826};
16690 16827
16691static void alc861vd_lenovo_mic_automute(struct hda_codec *codec)
16692{
16693 unsigned int present;
16694 unsigned char bits;
16695
16696 present = snd_hda_jack_detect(codec, 0x18);
16697 bits = present ? HDA_AMP_MUTE : 0;
16698
16699 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1,
16700 HDA_AMP_MUTE, bits);
16701}
16702
16703static void alc861vd_lenovo_setup(struct hda_codec *codec) 16828static void alc861vd_lenovo_setup(struct hda_codec *codec)
16704{ 16829{
16705 struct alc_spec *spec = codec->spec; 16830 struct alc_spec *spec = codec->spec;
@@ -16710,7 +16835,7 @@ static void alc861vd_lenovo_setup(struct hda_codec *codec)
16710static void alc861vd_lenovo_init_hook(struct hda_codec *codec) 16835static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16711{ 16836{
16712 alc_automute_amp(codec); 16837 alc_automute_amp(codec);
16713 alc861vd_lenovo_mic_automute(codec); 16838 alc88x_simple_mic_automute(codec);
16714} 16839}
16715 16840
16716static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, 16841static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
@@ -16718,7 +16843,7 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16718{ 16843{
16719 switch (res >> 26) { 16844 switch (res >> 26) {
16720 case ALC880_MIC_EVENT: 16845 case ALC880_MIC_EVENT:
16721 alc861vd_lenovo_mic_automute(codec); 16846 alc88x_simple_mic_automute(codec);
16722 break; 16847 break;
16723 default: 16848 default:
16724 alc_automute_amp_unsol_event(codec, res); 16849 alc_automute_amp_unsol_event(codec, res);
@@ -16793,7 +16918,7 @@ static void alc861vd_dallas_setup(struct hda_codec *codec)
16793/* 16918/*
16794 * configuration and preset 16919 * configuration and preset
16795 */ 16920 */
16796static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { 16921static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16797 [ALC660VD_3ST] = "3stack-660", 16922 [ALC660VD_3ST] = "3stack-660",
16798 [ALC660VD_3ST_DIG] = "3stack-660-digout", 16923 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16799 [ALC660VD_ASUS_V1S] = "asus-v1s", 16924 [ALC660VD_ASUS_V1S] = "asus-v1s",
@@ -17013,7 +17138,10 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17013static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, 17138static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17014 const struct auto_pin_cfg *cfg) 17139 const struct auto_pin_cfg *cfg)
17015{ 17140{
17016 static const char *chname[4] = {"Front", "Surround", "CLFE", "Side"}; 17141 static const char * const chname[4] = {
17142 "Front", "Surround", "CLFE", "Side"
17143 };
17144 const char *pfx = alc_get_line_out_pfx(cfg, true);
17017 hda_nid_t nid_v, nid_s; 17145 hda_nid_t nid_v, nid_s;
17018 int i, err; 17146 int i, err;
17019 17147
@@ -17027,7 +17155,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17027 alc880_dac_to_idx( 17155 alc880_dac_to_idx(
17028 spec->multiout.dac_nids[i])); 17156 spec->multiout.dac_nids[i]));
17029 17157
17030 if (i == 2) { 17158 if (!pfx && i == 2) {
17031 /* Center/LFE */ 17159 /* Center/LFE */
17032 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, 17160 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17033 "Center", 17161 "Center",
@@ -17054,24 +17182,17 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17054 if (err < 0) 17182 if (err < 0)
17055 return err; 17183 return err;
17056 } else { 17184 } else {
17057 const char *pfx; 17185 const char *name = pfx;
17058 if (cfg->line_outs == 1 && 17186 if (!name)
17059 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 17187 name = chname[i];
17060 if (!cfg->hp_pins) 17188 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17061 pfx = "Speaker"; 17189 name, i,
17062 else
17063 pfx = "PCM";
17064 } else
17065 pfx = chname[i];
17066 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17067 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, 17190 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17068 HDA_OUTPUT)); 17191 HDA_OUTPUT));
17069 if (err < 0) 17192 if (err < 0)
17070 return err; 17193 return err;
17071 if (cfg->line_outs == 1 && 17194 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17072 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 17195 name, i,
17073 pfx = "Speaker";
17074 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17075 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, 17196 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17076 HDA_INPUT)); 17197 HDA_INPUT));
17077 if (err < 0) 17198 if (err < 0)
@@ -17204,7 +17325,8 @@ enum {
17204/* reset GPIO1 */ 17325/* reset GPIO1 */
17205static const struct alc_fixup alc861vd_fixups[] = { 17326static const struct alc_fixup alc861vd_fixups[] = {
17206 [ALC660VD_FIX_ASUS_GPIO1] = { 17327 [ALC660VD_FIX_ASUS_GPIO1] = {
17207 .verbs = (const struct hda_verb[]) { 17328 .type = ALC_FIXUP_VERBS,
17329 .v.verbs = (const struct hda_verb[]) {
17208 {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, 17330 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17209 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, 17331 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17210 {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, 17332 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
@@ -17239,8 +17361,10 @@ static int patch_alc861vd(struct hda_codec *codec)
17239 board_config = ALC861VD_AUTO; 17361 board_config = ALC861VD_AUTO;
17240 } 17362 }
17241 17363
17242 if (board_config == ALC861VD_AUTO) 17364 if (board_config == ALC861VD_AUTO) {
17243 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1); 17365 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17366 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17367 }
17244 17368
17245 if (board_config == ALC861VD_AUTO) { 17369 if (board_config == ALC861VD_AUTO) {
17246 /* automatic parse from the BIOS config */ 17370 /* automatic parse from the BIOS config */
@@ -17288,8 +17412,7 @@ static int patch_alc861vd(struct hda_codec *codec)
17288 17412
17289 spec->vmaster_nid = 0x02; 17413 spec->vmaster_nid = 0x02;
17290 17414
17291 if (board_config == ALC861VD_AUTO) 17415 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
17292 alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0);
17293 17416
17294 codec->patch_ops = alc_patch_ops; 17417 codec->patch_ops = alc_patch_ops;
17295 17418
@@ -17535,13 +17658,13 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17535 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 17658 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17536 ALC262_HIPPO_MASTER_SWITCH, 17659 ALC262_HIPPO_MASTER_SWITCH,
17537 17660
17538 HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), 17661 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17539 HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17662 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17540 HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17663 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17541 17664
17542 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 17665 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17543 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17666 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17544 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17667 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17545 { } /* end */ 17668 { } /* end */
17546}; 17669};
17547 17670
@@ -17685,8 +17808,8 @@ static struct snd_kcontrol_new alc663_g71v_mixer[] = {
17685 17808
17686 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17809 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17687 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17810 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17688 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17811 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17689 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17812 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17690 { } /* end */ 17813 { } /* end */
17691}; 17814};
17692 17815
@@ -17697,8 +17820,8 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = {
17697 17820
17698 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 17821 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17699 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 17822 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17700 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 17823 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17701 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 17824 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17702 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), 17825 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17703 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), 17826 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17704 { } /* end */ 17827 { } /* end */
@@ -18531,13 +18654,13 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = {
18531 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), 18654 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18532 ALC262_HIPPO_MASTER_SWITCH, 18655 ALC262_HIPPO_MASTER_SWITCH,
18533 18656
18534 HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), 18657 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18535 HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), 18658 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18536 HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), 18659 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18537 18660
18538 HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), 18661 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18539 HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18662 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18540 HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18663 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18541 { } /* end */ 18664 { } /* end */
18542}; 18665};
18543 18666
@@ -18548,13 +18671,13 @@ static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18548 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 18671 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18549 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), 18672 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18550 18673
18551 HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), 18674 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18552 HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), 18675 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18553 HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), 18676 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18554 18677
18555 HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), 18678 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18556 HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), 18679 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18557 HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), 18680 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18558 { } /* end */ 18681 { } /* end */
18559}; 18682};
18560 18683
@@ -18572,7 +18695,7 @@ static struct snd_kcontrol_new alc272_nc10_mixer[] = {
18572/* 18695/*
18573 * configuration and preset 18696 * configuration and preset
18574 */ 18697 */
18575static const char *alc662_models[ALC662_MODEL_LAST] = { 18698static const char * const alc662_models[ALC662_MODEL_LAST] = {
18576 [ALC662_3ST_2ch_DIG] = "3stack-dig", 18699 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18577 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", 18700 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18578 [ALC662_3ST_6ch] = "3stack-6ch", 18701 [ALC662_3ST_6ch] = "3stack-6ch",
@@ -19059,20 +19182,24 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
19059 return 0; 19182 return 0;
19060} 19183}
19061 19184
19062static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, 19185static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
19063 hda_nid_t nid, unsigned int chs) 19186 hda_nid_t nid, int idx, unsigned int chs)
19064{ 19187{
19065 return add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 19188 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
19066 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); 19189 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
19067} 19190}
19068 19191
19069static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, 19192static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19070 hda_nid_t nid, unsigned int chs) 19193 hda_nid_t nid, int idx, unsigned int chs)
19071{ 19194{
19072 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 19195 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
19073 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); 19196 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19074} 19197}
19075 19198
19199#define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19200 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19201#define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19202 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
19076#define alc662_add_stereo_vol(spec, pfx, nid) \ 19203#define alc662_add_stereo_vol(spec, pfx, nid) \
19077 alc662_add_vol_ctl(spec, pfx, nid, 3) 19204 alc662_add_vol_ctl(spec, pfx, nid, 3)
19078#define alc662_add_stereo_sw(spec, pfx, nid) \ 19205#define alc662_add_stereo_sw(spec, pfx, nid) \
@@ -19083,9 +19210,10 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19083 const struct auto_pin_cfg *cfg) 19210 const struct auto_pin_cfg *cfg)
19084{ 19211{
19085 struct alc_spec *spec = codec->spec; 19212 struct alc_spec *spec = codec->spec;
19086 static const char *chname[4] = { 19213 static const char * const chname[4] = {
19087 "Front", "Surround", NULL /*CLFE*/, "Side" 19214 "Front", "Surround", NULL /*CLFE*/, "Side"
19088 }; 19215 };
19216 const char *pfx = alc_get_line_out_pfx(cfg, true);
19089 hda_nid_t nid, mix; 19217 hda_nid_t nid, mix;
19090 int i, err; 19218 int i, err;
19091 19219
@@ -19096,7 +19224,7 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19096 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); 19224 mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid);
19097 if (!mix) 19225 if (!mix)
19098 continue; 19226 continue;
19099 if (i == 2) { 19227 if (!pfx && i == 2) {
19100 /* Center/LFE */ 19228 /* Center/LFE */
19101 err = alc662_add_vol_ctl(spec, "Center", nid, 1); 19229 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19102 if (err < 0) 19230 if (err < 0)
@@ -19111,22 +19239,13 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19111 if (err < 0) 19239 if (err < 0)
19112 return err; 19240 return err;
19113 } else { 19241 } else {
19114 const char *pfx; 19242 const char *name = pfx;
19115 if (cfg->line_outs == 1 && 19243 if (!name)
19116 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { 19244 name = chname[i];
19117 if (cfg->hp_outs) 19245 err = __alc662_add_vol_ctl(spec, name, nid, i, 3);
19118 pfx = "Speaker";
19119 else
19120 pfx = "PCM";
19121 } else
19122 pfx = chname[i];
19123 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19124 if (err < 0) 19246 if (err < 0)
19125 return err; 19247 return err;
19126 if (cfg->line_outs == 1 && 19248 err = __alc662_add_sw_ctl(spec, name, mix, i, 3);
19127 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19128 pfx = "Speaker";
19129 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19130 if (err < 0) 19249 if (err < 0)
19131 return err; 19250 return err;
19132 } 19251 }
@@ -19323,24 +19442,53 @@ static void alc662_auto_init(struct hda_codec *codec)
19323 alc_inithook(codec); 19442 alc_inithook(codec);
19324} 19443}
19325 19444
19445static void alc272_fixup_mario(struct hda_codec *codec,
19446 const struct alc_fixup *fix, int action)
19447{
19448 if (action != ALC_FIXUP_ACT_PROBE)
19449 return;
19450 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19451 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19452 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19453 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19454 (0 << AC_AMPCAP_MUTE_SHIFT)))
19455 printk(KERN_WARNING
19456 "hda_codec: failed to override amp caps for NID 0x2\n");
19457}
19458
19326enum { 19459enum {
19327 ALC662_FIXUP_ASPIRE, 19460 ALC662_FIXUP_ASPIRE,
19328 ALC662_FIXUP_IDEAPAD, 19461 ALC662_FIXUP_IDEAPAD,
19462 ALC272_FIXUP_MARIO,
19463 ALC662_FIXUP_CZC_P10T,
19329}; 19464};
19330 19465
19331static const struct alc_fixup alc662_fixups[] = { 19466static const struct alc_fixup alc662_fixups[] = {
19332 [ALC662_FIXUP_ASPIRE] = { 19467 [ALC662_FIXUP_ASPIRE] = {
19333 .pins = (const struct alc_pincfg[]) { 19468 .type = ALC_FIXUP_PINS,
19469 .v.pins = (const struct alc_pincfg[]) {
19334 { 0x15, 0x99130112 }, /* subwoofer */ 19470 { 0x15, 0x99130112 }, /* subwoofer */
19335 { } 19471 { }
19336 } 19472 }
19337 }, 19473 },
19338 [ALC662_FIXUP_IDEAPAD] = { 19474 [ALC662_FIXUP_IDEAPAD] = {
19339 .pins = (const struct alc_pincfg[]) { 19475 .type = ALC_FIXUP_PINS,
19476 .v.pins = (const struct alc_pincfg[]) {
19340 { 0x17, 0x99130112 }, /* subwoofer */ 19477 { 0x17, 0x99130112 }, /* subwoofer */
19341 { } 19478 { }
19342 } 19479 }
19343 }, 19480 },
19481 [ALC272_FIXUP_MARIO] = {
19482 .type = ALC_FIXUP_FUNC,
19483 .v.func = alc272_fixup_mario,
19484 },
19485 [ALC662_FIXUP_CZC_P10T] = {
19486 .type = ALC_FIXUP_VERBS,
19487 .v.verbs = (const struct hda_verb[]) {
19488 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19489 {}
19490 }
19491 },
19344}; 19492};
19345 19493
19346static struct snd_pci_quirk alc662_fixup_tbl[] = { 19494static struct snd_pci_quirk alc662_fixup_tbl[] = {
@@ -19348,9 +19496,14 @@ static struct snd_pci_quirk alc662_fixup_tbl[] = {
19348 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), 19496 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19349 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), 19497 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19350 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), 19498 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19499 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
19351 {} 19500 {}
19352}; 19501};
19353 19502
19503static const struct alc_model_fixup alc662_fixup_models[] = {
19504 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19505 {}
19506};
19354 19507
19355 19508
19356static int patch_alc662(struct hda_codec *codec) 19509static int patch_alc662(struct hda_codec *codec)
@@ -19389,7 +19542,9 @@ static int patch_alc662(struct hda_codec *codec)
19389 } 19542 }
19390 19543
19391 if (board_config == ALC662_AUTO) { 19544 if (board_config == ALC662_AUTO) {
19392 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 1); 19545 alc_pick_fixup(codec, alc662_fixup_models,
19546 alc662_fixup_tbl, alc662_fixups);
19547 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
19393 /* automatic parse from the BIOS config */ 19548 /* automatic parse from the BIOS config */
19394 err = alc662_parse_auto_config(codec); 19549 err = alc662_parse_auto_config(codec);
19395 if (err < 0) { 19550 if (err < 0) {
@@ -19447,11 +19602,11 @@ static int patch_alc662(struct hda_codec *codec)
19447 } 19602 }
19448 spec->vmaster_nid = 0x02; 19603 spec->vmaster_nid = 0x02;
19449 19604
19605 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19606
19450 codec->patch_ops = alc_patch_ops; 19607 codec->patch_ops = alc_patch_ops;
19451 if (board_config == ALC662_AUTO) { 19608 if (board_config == ALC662_AUTO)
19452 spec->init_hook = alc662_auto_init; 19609 spec->init_hook = alc662_auto_init;
19453 alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0);
19454 }
19455 19610
19456 alc_init_jacks(codec); 19611 alc_init_jacks(codec);
19457 19612
@@ -19577,9 +19732,9 @@ static struct snd_kcontrol_new alc680_base_mixer[] = {
19577 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), 19732 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19578 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), 19733 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19579 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), 19734 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19580 HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT), 19735 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19581 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), 19736 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19582 HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT), 19737 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19583 { } 19738 { }
19584}; 19739};
19585 19740
@@ -19839,7 +19994,7 @@ static void alc680_auto_init(struct hda_codec *codec)
19839/* 19994/*
19840 * configuration and preset 19995 * configuration and preset
19841 */ 19996 */
19842static const char *alc680_models[ALC680_MODEL_LAST] = { 19997static const char * const alc680_models[ALC680_MODEL_LAST] = {
19843 [ALC680_BASE] = "base", 19998 [ALC680_BASE] = "base",
19844 [ALC680_AUTO] = "auto", 19999 [ALC680_AUTO] = "auto",
19845}; 20000};
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index efa4225f5fd6..9ea48b425d0b 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -266,7 +266,7 @@ struct sigmatel_spec {
266 struct sigmatel_mic_route int_mic; 266 struct sigmatel_mic_route int_mic;
267 struct sigmatel_mic_route dock_mic; 267 struct sigmatel_mic_route dock_mic;
268 268
269 const char **spdif_labels; 269 const char * const *spdif_labels;
270 270
271 hda_nid_t dig_in_nid; 271 hda_nid_t dig_in_nid;
272 hda_nid_t mono_nid; 272 hda_nid_t mono_nid;
@@ -389,6 +389,9 @@ static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = {
389 0x11, 0x20, 0 389 0x11, 0x20, 0
390}; 390};
391 391
392#define STAC92HD88XXX_NUM_DMICS STAC92HD83XXX_NUM_DMICS
393#define stac92hd88xxx_dmic_nids stac92hd83xxx_dmic_nids
394
392#define STAC92HD87B_NUM_DMICS 1 395#define STAC92HD87B_NUM_DMICS 1
393static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = { 396static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = {
394 0x11, 0 397 0x11, 0
@@ -521,7 +524,7 @@ static unsigned long stac927x_capsws[] = {
521 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), 524 HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT),
522}; 525};
523 526
524static const char *stac927x_spdif_labels[5] = { 527static const char * const stac927x_spdif_labels[5] = {
525 "Digital Playback", "ADAT", "Analog Mux 1", 528 "Digital Playback", "ADAT", "Analog Mux 1",
526 "Analog Mux 2", "Analog Mux 3" 529 "Analog Mux 2", "Analog Mux 3"
527}; 530};
@@ -1059,7 +1062,7 @@ static struct snd_kcontrol_new stac_smux_mixer = {
1059 .put = stac92xx_smux_enum_put, 1062 .put = stac92xx_smux_enum_put,
1060}; 1063};
1061 1064
1062static const char *slave_vols[] = { 1065static const char * const slave_vols[] = {
1063 "Front Playback Volume", 1066 "Front Playback Volume",
1064 "Surround Playback Volume", 1067 "Surround Playback Volume",
1065 "Center Playback Volume", 1068 "Center Playback Volume",
@@ -1070,7 +1073,7 @@ static const char *slave_vols[] = {
1070 NULL 1073 NULL
1071}; 1074};
1072 1075
1073static const char *slave_sws[] = { 1076static const char * const slave_sws[] = {
1074 "Front Playback Switch", 1077 "Front Playback Switch",
1075 "Surround Playback Switch", 1078 "Surround Playback Switch",
1076 "Center Playback Switch", 1079 "Center Playback Switch",
@@ -1351,7 +1354,7 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = {
1351 [STAC_9200_PANASONIC] = ref9200_pin_configs, 1354 [STAC_9200_PANASONIC] = ref9200_pin_configs,
1352}; 1355};
1353 1356
1354static const char *stac9200_models[STAC_9200_MODELS] = { 1357static const char * const stac9200_models[STAC_9200_MODELS] = {
1355 [STAC_AUTO] = "auto", 1358 [STAC_AUTO] = "auto",
1356 [STAC_REF] = "ref", 1359 [STAC_REF] = "ref",
1357 [STAC_9200_OQO] = "oqo", 1360 [STAC_9200_OQO] = "oqo",
@@ -1497,7 +1500,7 @@ static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = {
1497 [STAC_M6] = stac925xM6_pin_configs, 1500 [STAC_M6] = stac925xM6_pin_configs,
1498}; 1501};
1499 1502
1500static const char *stac925x_models[STAC_925x_MODELS] = { 1503static const char * const stac925x_models[STAC_925x_MODELS] = {
1501 [STAC_925x_AUTO] = "auto", 1504 [STAC_925x_AUTO] = "auto",
1502 [STAC_REF] = "ref", 1505 [STAC_REF] = "ref",
1503 [STAC_M1] = "m1", 1506 [STAC_M1] = "m1",
@@ -1571,7 +1574,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = {
1571 [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs, 1574 [STAC_92HD73XX_INTEL] = intel_dg45id_pin_configs,
1572}; 1575};
1573 1576
1574static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { 1577static const char * const stac92hd73xx_models[STAC_92HD73XX_MODELS] = {
1575 [STAC_92HD73XX_AUTO] = "auto", 1578 [STAC_92HD73XX_AUTO] = "auto",
1576 [STAC_92HD73XX_NO_JD] = "no-jd", 1579 [STAC_92HD73XX_NO_JD] = "no-jd",
1577 [STAC_92HD73XX_REF] = "ref", 1580 [STAC_92HD73XX_REF] = "ref",
@@ -1657,7 +1660,7 @@ static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = {
1657 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs, 1660 [STAC_HP_DV7_4000] = hp_dv7_4000_pin_configs,
1658}; 1661};
1659 1662
1660static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { 1663static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = {
1661 [STAC_92HD83XXX_AUTO] = "auto", 1664 [STAC_92HD83XXX_AUTO] = "auto",
1662 [STAC_92HD83XXX_REF] = "ref", 1665 [STAC_92HD83XXX_REF] = "ref",
1663 [STAC_92HD83XXX_PWR_REF] = "mic-ref", 1666 [STAC_92HD83XXX_PWR_REF] = "mic-ref",
@@ -1719,7 +1722,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = {
1719 [STAC_HP_DV4_1222NR] = NULL, 1722 [STAC_HP_DV4_1222NR] = NULL,
1720}; 1723};
1721 1724
1722static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { 1725static const char * const stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = {
1723 [STAC_92HD71BXX_AUTO] = "auto", 1726 [STAC_92HD71BXX_AUTO] = "auto",
1724 [STAC_92HD71BXX_REF] = "ref", 1727 [STAC_92HD71BXX_REF] = "ref",
1725 [STAC_DELL_M4_1] = "dell-m4-1", 1728 [STAC_DELL_M4_1] = "dell-m4-1",
@@ -1912,7 +1915,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = {
1912 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs, 1915 [STAC_922X_DELL_M82] = dell_922x_m82_pin_configs,
1913}; 1916};
1914 1917
1915static const char *stac922x_models[STAC_922X_MODELS] = { 1918static const char * const stac922x_models[STAC_922X_MODELS] = {
1916 [STAC_922X_AUTO] = "auto", 1919 [STAC_922X_AUTO] = "auto",
1917 [STAC_D945_REF] = "ref", 1920 [STAC_D945_REF] = "ref",
1918 [STAC_D945GTP5] = "5stack", 1921 [STAC_D945GTP5] = "5stack",
@@ -2074,7 +2077,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = {
2074 [STAC_927X_VOLKNOB] = NULL, 2077 [STAC_927X_VOLKNOB] = NULL,
2075}; 2078};
2076 2079
2077static const char *stac927x_models[STAC_927X_MODELS] = { 2080static const char * const stac927x_models[STAC_927X_MODELS] = {
2078 [STAC_927X_AUTO] = "auto", 2081 [STAC_927X_AUTO] = "auto",
2079 [STAC_D965_REF_NO_JD] = "ref-no-jd", 2082 [STAC_D965_REF_NO_JD] = "ref-no-jd",
2080 [STAC_D965_REF] = "ref", 2083 [STAC_D965_REF] = "ref",
@@ -2177,7 +2180,7 @@ static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = {
2177 [STAC_9205_EAPD] = NULL, 2180 [STAC_9205_EAPD] = NULL,
2178}; 2181};
2179 2182
2180static const char *stac9205_models[STAC_9205_MODELS] = { 2183static const char * const stac9205_models[STAC_9205_MODELS] = {
2181 [STAC_9205_AUTO] = "auto", 2184 [STAC_9205_AUTO] = "auto",
2182 [STAC_9205_REF] = "ref", 2185 [STAC_9205_REF] = "ref",
2183 [STAC_9205_DELL_M42] = "dell-m42", 2186 [STAC_9205_DELL_M42] = "dell-m42",
@@ -3120,7 +3123,7 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs,
3120 int type) 3123 int type)
3121{ 3124{
3122 struct sigmatel_spec *spec = codec->spec; 3125 struct sigmatel_spec *spec = codec->spec;
3123 static const char *chname[4] = { 3126 static const char * const chname[4] = {
3124 "Front", "Surround", NULL /*CLFE*/, "Side" 3127 "Front", "Surround", NULL /*CLFE*/, "Side"
3125 }; 3128 };
3126 hda_nid_t nid; 3129 hda_nid_t nid;
@@ -3253,7 +3256,7 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec,
3253} 3256}
3254 3257
3255/* labels for mono mux outputs */ 3258/* labels for mono mux outputs */
3256static const char *stac92xx_mono_labels[4] = { 3259static const char * const stac92xx_mono_labels[4] = {
3257 "DAC0", "DAC1", "Mixer", "DAC2" 3260 "DAC0", "DAC1", "Mixer", "DAC2"
3258}; 3261};
3259 3262
@@ -3377,7 +3380,7 @@ static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec)
3377 return 0; 3380 return 0;
3378}; 3381};
3379 3382
3380static const char *stac92xx_spdif_labels[3] = { 3383static const char * const stac92xx_spdif_labels[3] = {
3381 "Digital Playback", "Analog Mux 1", "Analog Mux 2", 3384 "Digital Playback", "Analog Mux 1", "Analog Mux 2",
3382}; 3385};
3383 3386
@@ -3385,7 +3388,7 @@ static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
3385{ 3388{
3386 struct sigmatel_spec *spec = codec->spec; 3389 struct sigmatel_spec *spec = codec->spec;
3387 struct hda_input_mux *spdif_mux = &spec->private_smux; 3390 struct hda_input_mux *spdif_mux = &spec->private_smux;
3388 const char **labels = spec->spdif_labels; 3391 const char * const *labels = spec->spdif_labels;
3389 int i, num_cons; 3392 int i, num_cons;
3390 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; 3393 hda_nid_t con_lst[HDA_MAX_NUM_INPUTS];
3391 3394
@@ -3406,7 +3409,7 @@ static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec)
3406} 3409}
3407 3410
3408/* labels for dmic mux inputs */ 3411/* labels for dmic mux inputs */
3409static const char *stac92xx_dmic_labels[5] = { 3412static const char * const stac92xx_dmic_labels[5] = {
3410 "Analog Inputs", "Digital Mic 1", "Digital Mic 2", 3413 "Analog Inputs", "Digital Mic 1", "Digital Mic 2",
3411 "Digital Mic 3", "Digital Mic 4" 3414 "Digital Mic 3", "Digital Mic 4"
3412}; 3415};
@@ -3481,6 +3484,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3481 3484
3482 label = hda_get_input_pin_label(codec, nid, 1); 3485 label = hda_get_input_pin_label(codec, nid, 1);
3483 snd_hda_add_imux_item(dimux, label, index, &type_idx); 3486 snd_hda_add_imux_item(dimux, label, index, &type_idx);
3487 if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
3488 snd_hda_add_imux_item(imux, label, index, &type_idx);
3484 3489
3485 err = create_elem_capture_vol(codec, nid, label, type_idx, 3490 err = create_elem_capture_vol(codec, nid, label, type_idx,
3486 HDA_INPUT); 3491 HDA_INPUT);
@@ -3492,9 +3497,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec,
3492 if (err < 0) 3497 if (err < 0)
3493 return err; 3498 return err;
3494 } 3499 }
3495
3496 if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1)
3497 snd_hda_add_imux_item(imux, label, index, NULL);
3498 } 3500 }
3499 3501
3500 return 0; 3502 return 0;
@@ -3592,7 +3594,7 @@ static int stac_check_auto_mic(struct hda_codec *codec)
3592 if (check_mic_pin(codec, spec->dmic_nids[i], 3594 if (check_mic_pin(codec, spec->dmic_nids[i],
3593 &fixed, &ext, &dock)) 3595 &fixed, &ext, &dock))
3594 return 0; 3596 return 0;
3595 if (!fixed && !ext && !dock) 3597 if (!fixed || (!ext && !dock))
3596 return 0; /* no input to switch */ 3598 return 0; /* no input to switch */
3597 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) 3599 if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP))
3598 return 0; /* no unsol support */ 3600 return 0; /* no unsol support */
@@ -5331,7 +5333,7 @@ again:
5331 return 0; 5333 return 0;
5332} 5334}
5333 5335
5334static int stac92hd83xxx_set_system_btl_amp(struct hda_codec *codec) 5336static int hp_bnb2011_with_dock(struct hda_codec *codec)
5335{ 5337{
5336 if (codec->vendor_id != 0x111d7605 && 5338 if (codec->vendor_id != 0x111d7605 &&
5337 codec->vendor_id != 0x111d76d1) 5339 codec->vendor_id != 0x111d76d1)
@@ -5346,10 +5348,6 @@ static int stac92hd83xxx_set_system_btl_amp(struct hda_codec *codec)
5346 case 0x103c161d: 5348 case 0x103c161d:
5347 case 0x103c161e: 5349 case 0x103c161e:
5348 case 0x103c161f: 5350 case 0x103c161f:
5349 case 0x103c1620:
5350 case 0x103c1621:
5351 case 0x103c1622:
5352 case 0x103c1623:
5353 5351
5354 case 0x103c162a: 5352 case 0x103c162a:
5355 case 0x103c162b: 5353 case 0x103c162b:
@@ -5358,41 +5356,9 @@ static int stac92hd83xxx_set_system_btl_amp(struct hda_codec *codec)
5358 case 0x103c1631: 5356 case 0x103c1631:
5359 5357
5360 case 0x103c1633: 5358 case 0x103c1633:
5361 5359 case 0x103c1634:
5362 case 0x103c1635: 5360 case 0x103c1635:
5363 5361
5364 case 0x103c164f:
5365
5366 case 0x103c1676:
5367 case 0x103c1677:
5368 case 0x103c1678:
5369 case 0x103c1679:
5370 case 0x103c167a:
5371 case 0x103c167b:
5372 case 0x103c167c:
5373 case 0x103c167d:
5374 case 0x103c167e:
5375 case 0x103c167f:
5376 case 0x103c1680:
5377 case 0x103c1681:
5378 case 0x103c1682:
5379 case 0x103c1683:
5380 case 0x103c1684:
5381 case 0x103c1685:
5382 case 0x103c1686:
5383 case 0x103c1687:
5384 case 0x103c1688:
5385 case 0x103c1689:
5386 case 0x103c168a:
5387 case 0x103c168b:
5388 case 0x103c168c:
5389 case 0x103c168d:
5390 case 0x103c168e:
5391 case 0x103c168f:
5392 case 0x103c1690:
5393 case 0x103c1691:
5394 case 0x103c1692:
5395
5396 case 0x103c3587: 5362 case 0x103c3587:
5397 case 0x103c3588: 5363 case 0x103c3588:
5398 case 0x103c3589: 5364 case 0x103c3589:
@@ -5400,9 +5366,9 @@ static int stac92hd83xxx_set_system_btl_amp(struct hda_codec *codec)
5400 5366
5401 case 0x103c3667: 5367 case 0x103c3667:
5402 case 0x103c3668: 5368 case 0x103c3668:
5403 /* set BTL amp level to 13.43dB for louder speaker output */ 5369 case 0x103c3669:
5404 return snd_hda_codec_write_cache(codec, codec->afg, 0, 5370
5405 0x7F4, 0x14); 5371 return 1;
5406 } 5372 }
5407 return 0; 5373 return 0;
5408} 5374}
@@ -5418,12 +5384,17 @@ static int patch_stac92hd83xxx(struct hda_codec *codec)
5418 if (spec == NULL) 5384 if (spec == NULL)
5419 return -ENOMEM; 5385 return -ENOMEM;
5420 5386
5387 if (hp_bnb2011_with_dock(codec)) {
5388 snd_hda_codec_set_pincfg(codec, 0xa, 0x2101201f);
5389 snd_hda_codec_set_pincfg(codec, 0xf, 0x2181205e);
5390 }
5391
5421 /* reset pin power-down; Windows may leave these bits after reboot */ 5392 /* reset pin power-down; Windows may leave these bits after reboot */
5422 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7EC, 0); 5393 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7EC, 0);
5423 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); 5394 snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0);
5424 codec->no_trigger_sense = 1; 5395 codec->no_trigger_sense = 1;
5425 codec->spec = spec; 5396 codec->spec = spec;
5426 spec->linear_tone_beep = 1; 5397 spec->linear_tone_beep = 0;
5427 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; 5398 codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs;
5428 spec->digbeep_nid = 0x21; 5399 spec->digbeep_nid = 0x21;
5429 spec->dmic_nids = stac92hd83xxx_dmic_nids; 5400 spec->dmic_nids = stac92hd83xxx_dmic_nids;
@@ -5463,15 +5434,21 @@ again:
5463 spec->num_dmics = stac92xx_connected_ports(codec, 5434 spec->num_dmics = stac92xx_connected_ports(codec,
5464 stac92hd87b_dmic_nids, 5435 stac92hd87b_dmic_nids,
5465 STAC92HD87B_NUM_DMICS); 5436 STAC92HD87B_NUM_DMICS);
5466 /* Fall through */ 5437 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5438 spec->pin_nids = stac92hd88xxx_pin_nids;
5439 spec->mono_nid = 0;
5440 spec->num_pwrs = 0;
5441 break;
5467 case 0x111d7666: 5442 case 0x111d7666:
5468 case 0x111d7667: 5443 case 0x111d7667:
5469 case 0x111d7668: 5444 case 0x111d7668:
5470 case 0x111d7669: 5445 case 0x111d7669:
5446 spec->num_dmics = stac92xx_connected_ports(codec,
5447 stac92hd88xxx_dmic_nids,
5448 STAC92HD88XXX_NUM_DMICS);
5471 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); 5449 spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids);
5472 spec->pin_nids = stac92hd88xxx_pin_nids; 5450 spec->pin_nids = stac92hd88xxx_pin_nids;
5473 spec->mono_nid = 0; 5451 spec->mono_nid = 0;
5474 spec->digbeep_nid = 0;
5475 spec->num_pwrs = 0; 5452 spec->num_pwrs = 0;
5476 break; 5453 break;
5477 case 0x111d7604: 5454 case 0x111d7604:
@@ -5538,8 +5515,6 @@ again:
5538 AC_VERB_SET_CONNECT_SEL, num_dacs); 5515 AC_VERB_SET_CONNECT_SEL, num_dacs);
5539 } 5516 }
5540 5517
5541 stac92hd83xxx_set_system_btl_amp(codec);
5542
5543 codec->proc_widget_hook = stac92hd_proc_hook; 5518 codec->proc_widget_hook = stac92hd_proc_hook;
5544 5519
5545 return 0; 5520 return 0;
@@ -6262,7 +6237,7 @@ static unsigned int stac9872_vaio_pin_configs[9] = {
6262 0x90a7013e 6237 0x90a7013e
6263}; 6238};
6264 6239
6265static const char *stac9872_models[STAC_9872_MODELS] = { 6240static const char * const stac9872_models[STAC_9872_MODELS] = {
6266 [STAC_9872_AUTO] = "auto", 6241 [STAC_9872_AUTO] = "auto",
6267 [STAC_9872_VAIO] = "vaio", 6242 [STAC_9872_VAIO] = "vaio",
6268}; 6243};
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 7f4852a478a1..a76c3260d941 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -2281,7 +2281,9 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec,
2281 const struct auto_pin_cfg *cfg) 2281 const struct auto_pin_cfg *cfg)
2282{ 2282{
2283 char name[32]; 2283 char name[32];
2284 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 2284 static const char * const chname[4] = {
2285 "Front", "Surround", "C/LFE", "Side"
2286 };
2285 hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b}; 2287 hda_nid_t nid, nid_vol, nid_vols[] = {0x17, 0x19, 0x1a, 0x1b};
2286 int i, err; 2288 int i, err;
2287 2289
@@ -2370,7 +2372,7 @@ static void create_hp_imux(struct via_spec *spec)
2370{ 2372{
2371 int i; 2373 int i;
2372 struct hda_input_mux *imux = &spec->private_imux[1]; 2374 struct hda_input_mux *imux = &spec->private_imux[1];
2373 static const char *texts[] = { "OFF", "ON", NULL}; 2375 static const char * const texts[] = { "OFF", "ON", NULL};
2374 2376
2375 /* for hp mode select */ 2377 /* for hp mode select */
2376 for (i = 0; texts[i]; i++) 2378 for (i = 0; texts[i]; i++)
@@ -2890,7 +2892,9 @@ static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec,
2890 const struct auto_pin_cfg *cfg) 2892 const struct auto_pin_cfg *cfg)
2891{ 2893{
2892 char name[32]; 2894 char name[32];
2893 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 2895 static const char * const chname[4] = {
2896 "Front", "Surround", "C/LFE", "Side"
2897 };
2894 hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29}; 2898 hda_nid_t nid, nid_vol, nid_vols[] = {0x18, 0x1a, 0x1b, 0x29};
2895 int i, err; 2899 int i, err;
2896 2900
@@ -3433,7 +3437,9 @@ static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec,
3433 const struct auto_pin_cfg *cfg) 3437 const struct auto_pin_cfg *cfg)
3434{ 3438{
3435 char name[32]; 3439 char name[32];
3436 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 3440 static const char * const chname[4] = {
3441 "Front", "Surround", "C/LFE", "Side"
3442 };
3437 hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27}; 3443 hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27};
3438 hda_nid_t nid, nid_vol = 0; 3444 hda_nid_t nid, nid_vol = 0;
3439 int i, err; 3445 int i, err;
@@ -3861,7 +3867,9 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
3861 const struct auto_pin_cfg *cfg) 3867 const struct auto_pin_cfg *cfg)
3862{ 3868{
3863 char name[32]; 3869 char name[32];
3864 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 3870 static const char * const chname[4] = {
3871 "Front", "Surround", "C/LFE", "Side"
3872 };
3865 hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25}; 3873 hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25};
3866 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27}; 3874 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27};
3867 hda_nid_t nid, nid_vol, nid_mute; 3875 hda_nid_t nid, nid_vol, nid_mute;
@@ -4304,7 +4312,7 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin)
4304{ 4312{
4305 int err, i; 4313 int err, i;
4306 struct hda_input_mux *imux; 4314 struct hda_input_mux *imux;
4307 static const char *texts[] = { "ON", "OFF", NULL}; 4315 static const char * const texts[] = { "ON", "OFF", NULL};
4308 if (!pin) 4316 if (!pin)
4309 return 0; 4317 return 0;
4310 spec->multiout.hp_nid = 0x1D; 4318 spec->multiout.hp_nid = 0x1D;
@@ -4615,7 +4623,9 @@ static int vt1718S_auto_create_multi_out_ctls(struct via_spec *spec,
4615 const struct auto_pin_cfg *cfg) 4623 const struct auto_pin_cfg *cfg)
4616{ 4624{
4617 char name[32]; 4625 char name[32];
4618 static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; 4626 static const char * const chname[4] = {
4627 "Front", "Surround", "C/LFE", "Side"
4628 };
4619 hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb}; 4629 hda_nid_t nid_vols[] = {0x8, 0x9, 0xa, 0xb};
4620 hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27}; 4630 hda_nid_t nid_mutes[] = {0x24, 0x25, 0x26, 0x27};
4621 hda_nid_t nid, nid_vol, nid_mute = 0; 4631 hda_nid_t nid, nid_vol, nid_mute = 0;
@@ -5064,7 +5074,9 @@ static int vt1716S_auto_create_multi_out_ctls(struct via_spec *spec,
5064 const struct auto_pin_cfg *cfg) 5074 const struct auto_pin_cfg *cfg)
5065{ 5075{
5066 char name[32]; 5076 char name[32];
5067 static const char *chname[3] = { "Front", "Surround", "C/LFE" }; 5077 static const char * const chname[3] = {
5078 "Front", "Surround", "C/LFE"
5079 };
5068 hda_nid_t nid_vols[] = {0x10, 0x11, 0x25}; 5080 hda_nid_t nid_vols[] = {0x10, 0x11, 0x25};
5069 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27}; 5081 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x27};
5070 hda_nid_t nid, nid_vol, nid_mute; 5082 hda_nid_t nid, nid_vol, nid_mute;
diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c
index 712c1710f9a2..20c6b079d0df 100644
--- a/sound/pci/ice1712/delta.c
+++ b/sound/pci/ice1712/delta.c
@@ -96,6 +96,11 @@ static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice)
96 tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC; 96 tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC;
97 tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL; 97 tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL;
98 break; 98 break;
99 case ICE1712_SUBDEVICE_DELTA66E:
100 tmp |= ICE1712_DELTA_66E_CCLK | ICE1712_DELTA_66E_CS_CHIP_A |
101 ICE1712_DELTA_66E_CS_CHIP_B;
102 tmp &= ~ICE1712_DELTA_66E_CS_CS8427;
103 break;
99 case ICE1712_SUBDEVICE_VX442: 104 case ICE1712_SUBDEVICE_VX442:
100 tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B; 105 tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B;
101 tmp &= ~ICE1712_VX442_CS_DIGITAL; 106 tmp &= ~ICE1712_VX442_CS_DIGITAL;
@@ -119,6 +124,9 @@ static void ap_cs8427_codec_deassert(struct snd_ice1712 *ice, unsigned char tmp)
119 case ICE1712_SUBDEVICE_DELTA410: 124 case ICE1712_SUBDEVICE_DELTA410:
120 tmp |= ICE1712_DELTA_AP_CS_DIGITAL; 125 tmp |= ICE1712_DELTA_AP_CS_DIGITAL;
121 break; 126 break;
127 case ICE1712_SUBDEVICE_DELTA66E:
128 tmp |= ICE1712_DELTA_66E_CS_CS8427;
129 break;
122 case ICE1712_SUBDEVICE_VX442: 130 case ICE1712_SUBDEVICE_VX442:
123 tmp |= ICE1712_VX442_CS_DIGITAL; 131 tmp |= ICE1712_VX442_CS_DIGITAL;
124 break; 132 break;
@@ -276,6 +284,20 @@ static void delta1010lt_ak4524_lock(struct snd_akm4xxx *ak, int chip)
276} 284}
277 285
278/* 286/*
287 * AK4524 on Delta66 rev E to choose the chip address
288 */
289static void delta66e_ak4524_lock(struct snd_akm4xxx *ak, int chip)
290{
291 struct snd_ak4xxx_private *priv = (void *)ak->private_value[0];
292 struct snd_ice1712 *ice = ak->private_data[0];
293
294 snd_ice1712_save_gpio_status(ice);
295 priv->cs_mask =
296 priv->cs_addr = chip == 0 ? ICE1712_DELTA_66E_CS_CHIP_A :
297 ICE1712_DELTA_66E_CS_CHIP_B;
298}
299
300/*
279 * AK4528 on VX442 to choose the chip mask 301 * AK4528 on VX442 to choose the chip mask
280 */ 302 */
281static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip) 303static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip)
@@ -487,6 +509,29 @@ static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = {
487 .mask_flags = 0, 509 .mask_flags = 0,
488}; 510};
489 511
512static struct snd_akm4xxx akm_delta66e __devinitdata = {
513 .type = SND_AK4524,
514 .num_adcs = 4,
515 .num_dacs = 4,
516 .ops = {
517 .lock = delta66e_ak4524_lock,
518 .set_rate_val = delta_ak4524_set_rate_val
519 }
520};
521
522static struct snd_ak4xxx_private akm_delta66e_priv __devinitdata = {
523 .caddr = 2,
524 .cif = 0, /* the default level of the CIF pin from AK4524 */
525 .data_mask = ICE1712_DELTA_66E_DOUT,
526 .clk_mask = ICE1712_DELTA_66E_CCLK,
527 .cs_mask = 0,
528 .cs_addr = 0, /* set later */
529 .cs_none = 0,
530 .add_flags = 0,
531 .mask_flags = 0,
532};
533
534
490static struct snd_akm4xxx akm_delta44 __devinitdata = { 535static struct snd_akm4xxx akm_delta44 __devinitdata = {
491 .type = SND_AK4524, 536 .type = SND_AK4524,
492 .num_adcs = 4, 537 .num_adcs = 4,
@@ -535,6 +580,7 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
535{ 580{
536 int err; 581 int err;
537 struct snd_akm4xxx *ak; 582 struct snd_akm4xxx *ak;
583 unsigned char tmp;
538 584
539 if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA1010 && 585 if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_DELTA1010 &&
540 ice->eeprom.gpiodir == 0x7b) 586 ice->eeprom.gpiodir == 0x7b)
@@ -577,6 +623,12 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
577 break; 623 break;
578 } 624 }
579 625
626 /* initialize the SPI clock to high */
627 tmp = snd_ice1712_read(ice, ICE1712_IREG_GPIO_DATA);
628 tmp |= ICE1712_DELTA_AP_CCLK;
629 snd_ice1712_write(ice, ICE1712_IREG_GPIO_DATA, tmp);
630 udelay(5);
631
580 /* initialize spdif */ 632 /* initialize spdif */
581 switch (ice->eeprom.subvendor) { 633 switch (ice->eeprom.subvendor) {
582 case ICE1712_SUBDEVICE_AUDIOPHILE: 634 case ICE1712_SUBDEVICE_AUDIOPHILE:
@@ -644,9 +696,11 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice)
644 err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice); 696 err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice);
645 break; 697 break;
646 case ICE1712_SUBDEVICE_VX442: 698 case ICE1712_SUBDEVICE_VX442:
647 case ICE1712_SUBDEVICE_DELTA66E:
648 err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice); 699 err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice);
649 break; 700 break;
701 case ICE1712_SUBDEVICE_DELTA66E:
702 err = snd_ice1712_akm4xxx_init(ak, &akm_delta66e, &akm_delta66e_priv, ice);
703 break;
650 default: 704 default:
651 snd_BUG(); 705 snd_BUG();
652 return -EINVAL; 706 return -EINVAL;
diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h
index 1a0ac6cd6501..11a9c3a76507 100644
--- a/sound/pci/ice1712/delta.h
+++ b/sound/pci/ice1712/delta.h
@@ -144,6 +144,17 @@ extern struct snd_ice1712_card_info snd_ice1712_delta_cards[];
144#define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */ 144#define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */
145#define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */ 145#define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */
146 146
147/* M-Audio Delta 66 rev. E definitions.
148 * Newer revisions of Delta 66 have CS8427 over SPI for
149 * S/PDIF transceiver instead of CS8404/CS8414. */
150/* 0x01 = DFS */
151#define ICE1712_DELTA_66E_CCLK 0x02 /* SPI clock */
152#define ICE1712_DELTA_66E_DIN 0x04 /* data input */
153#define ICE1712_DELTA_66E_DOUT 0x08 /* data output */
154#define ICE1712_DELTA_66E_CS_CS8427 0x10 /* chip select, low = CS8427 */
155#define ICE1712_DELTA_66E_CS_CHIP_A 0x20 /* AK4524 #0 */
156#define ICE1712_DELTA_66E_CS_CHIP_B 0x40 /* AK4524 #1 */
157
147/* Digigram VX442 definitions */ 158/* Digigram VX442 definitions */
148#define ICE1712_VX442_CCLK 0x02 /* SPI clock */ 159#define ICE1712_VX442_CCLK 0x02 /* SPI clock */
149#define ICE1712_VX442_DIN 0x04 /* data input */ 160#define ICE1712_VX442_DIN 0x04 /* data input */
diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile
index acd8f15f7bff..0f8726551fde 100644
--- a/sound/pci/oxygen/Makefile
+++ b/sound/pci/oxygen/Makefile
@@ -1,10 +1,8 @@
1snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o 1snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o
2snd-hifier-objs := hifier.o 2snd-oxygen-objs := oxygen.o xonar_dg.o
3snd-oxygen-objs := oxygen.o
4snd-virtuoso-objs := virtuoso.o xonar_lib.o \ 3snd-virtuoso-objs := virtuoso.o xonar_lib.o \
5 xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o 4 xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o
6 5
7obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o 6obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o
8obj-$(CONFIG_SND_HIFIER) += snd-hifier.o
9obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o 7obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o
10obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o 8obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o
diff --git a/sound/pci/oxygen/cs4245.h b/sound/pci/oxygen/cs4245.h
new file mode 100644
index 000000000000..5e0197e07dd1
--- /dev/null
+++ b/sound/pci/oxygen/cs4245.h
@@ -0,0 +1,107 @@
1#define CS4245_CHIP_ID 0x01
2#define CS4245_POWER_CTRL 0x02
3#define CS4245_DAC_CTRL_1 0x03
4#define CS4245_ADC_CTRL 0x04
5#define CS4245_MCLK_FREQ 0x05
6#define CS4245_SIGNAL_SEL 0x06
7#define CS4245_PGA_B_CTRL 0x07
8#define CS4245_PGA_A_CTRL 0x08
9#define CS4245_ANALOG_IN 0x09
10#define CS4245_DAC_A_CTRL 0x0a
11#define CS4245_DAC_B_CTRL 0x0b
12#define CS4245_DAC_CTRL_2 0x0c
13#define CS4245_INT_STATUS 0x0d
14#define CS4245_INT_MASK 0x0e
15#define CS4245_INT_MODE_MSB 0x0f
16#define CS4245_INT_MODE_LSB 0x10
17
18/* Chip ID */
19#define CS4245_CHIP_PART_MASK 0xf0
20#define CS4245_CHIP_REV_MASK 0x0f
21
22/* Power Control */
23#define CS4245_FREEZE 0x80
24#define CS4245_PDN_MIC 0x08
25#define CS4245_PDN_ADC 0x04
26#define CS4245_PDN_DAC 0x02
27#define CS4245_PDN 0x01
28
29/* DAC Control */
30#define CS4245_DAC_FM_MASK 0xc0
31#define CS4245_DAC_FM_SINGLE 0x00
32#define CS4245_DAC_FM_DOUBLE 0x40
33#define CS4245_DAC_FM_QUAD 0x80
34#define CS4245_DAC_DIF_MASK 0x30
35#define CS4245_DAC_DIF_LJUST 0x00
36#define CS4245_DAC_DIF_I2S 0x10
37#define CS4245_DAC_DIF_RJUST_16 0x20
38#define CS4245_DAC_DIF_RJUST_24 0x30
39#define CS4245_RESERVED_1 0x08
40#define CS4245_MUTE_DAC 0x04
41#define CS4245_DEEMPH 0x02
42#define CS4245_DAC_MASTER 0x01
43
44/* ADC Control */
45#define CS4245_ADC_FM_MASK 0xc0
46#define CS4245_ADC_FM_SINGLE 0x00
47#define CS4245_ADC_FM_DOUBLE 0x40
48#define CS4245_ADC_FM_QUAD 0x80
49#define CS4245_ADC_DIF_MASK 0x10
50#define CS4245_ADC_DIF_LJUST 0x00
51#define CS4245_ADC_DIF_I2S 0x10
52#define CS4245_MUTE_ADC 0x04
53#define CS4245_HPF_FREEZE 0x02
54#define CS4245_ADC_MASTER 0x01
55
56/* MCLK Frequency */
57#define CS4245_MCLK1_MASK 0x70
58#define CS4245_MCLK1_SHIFT 4
59#define CS4245_MCLK2_MASK 0x07
60#define CS4245_MCLK2_SHIFT 0
61#define CS4245_MCLK_1 0
62#define CS4245_MCLK_1_5 1
63#define CS4245_MCLK_2 2
64#define CS4245_MCLK_3 3
65#define CS4245_MCLK_4 4
66
67/* Signal Selection */
68#define CS4245_A_OUT_SEL_MASK 0x60
69#define CS4245_A_OUT_SEL_HIZ 0x00
70#define CS4245_A_OUT_SEL_DAC 0x20
71#define CS4245_A_OUT_SEL_PGA 0x40
72#define CS4245_LOOP 0x02
73#define CS4245_ASYNCH 0x01
74
75/* Channel B/A PGA Control */
76#define CS4245_PGA_GAIN_MASK 0x3f
77
78/* ADC Input Control */
79#define CS4245_PGA_SOFT 0x10
80#define CS4245_PGA_ZERO 0x08
81#define CS4245_SEL_MASK 0x07
82#define CS4245_SEL_MIC 0x00
83#define CS4245_SEL_INPUT_1 0x01
84#define CS4245_SEL_INPUT_2 0x02
85#define CS4245_SEL_INPUT_3 0x03
86#define CS4245_SEL_INPUT_4 0x04
87#define CS4245_SEL_INPUT_5 0x05
88#define CS4245_SEL_INPUT_6 0x06
89
90/* DAC Channel A/B Volume Control */
91#define CS4245_VOL_MASK 0xff
92
93/* DAC Control 2 */
94#define CS4245_DAC_SOFT 0x80
95#define CS4245_DAC_ZERO 0x40
96#define CS4245_INVERT_DAC 0x20
97#define CS4245_INT_ACTIVE_HIGH 0x01
98
99/* Interrupt Status/Mask/Mode */
100#define CS4245_ADC_CLK_ERR 0x08
101#define CS4245_DAC_CLK_ERR 0x04
102#define CS4245_ADC_OVFL 0x02
103#define CS4245_ADC_UNDRFL 0x01
104
105
106#define CS4245_SPI_ADDRESS (0x9e << 16)
107#define CS4245_SPI_WRITE (0 << 16)
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
deleted file mode 100644
index 5a87d683691f..000000000000
--- a/sound/pci/oxygen/hifier.c
+++ /dev/null
@@ -1,239 +0,0 @@
1/*
2 * C-Media CMI8788 driver for the MediaTek/TempoTec HiFier Fantasia
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
9 *
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20/*
21 * CMI8788:
22 *
23 * SPI 0 -> AK4396
24 */
25
26#include <linux/delay.h>
27#include <linux/pci.h>
28#include <sound/control.h>
29#include <sound/core.h>
30#include <sound/initval.h>
31#include <sound/pcm.h>
32#include <sound/tlv.h>
33#include "oxygen.h"
34#include "ak4396.h"
35
36MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
37MODULE_DESCRIPTION("TempoTec HiFier driver");
38MODULE_LICENSE("GPL v2");
39
40static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
41static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
42static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
43
44module_param_array(index, int, NULL, 0444);
45MODULE_PARM_DESC(index, "card index");
46module_param_array(id, charp, NULL, 0444);
47MODULE_PARM_DESC(id, "ID string");
48module_param_array(enable, bool, NULL, 0444);
49MODULE_PARM_DESC(enable, "enable card");
50
51static DEFINE_PCI_DEVICE_TABLE(hifier_ids) = {
52 { OXYGEN_PCI_SUBID(0x14c3, 0x1710) },
53 { OXYGEN_PCI_SUBID(0x14c3, 0x1711) },
54 { OXYGEN_PCI_SUBID_BROKEN_EEPROM },
55 { }
56};
57MODULE_DEVICE_TABLE(pci, hifier_ids);
58
59struct hifier_data {
60 u8 ak4396_regs[5];
61};
62
63static void ak4396_write(struct oxygen *chip, u8 reg, u8 value)
64{
65 struct hifier_data *data = chip->model_data;
66
67 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
68 OXYGEN_SPI_DATA_LENGTH_2 |
69 OXYGEN_SPI_CLOCK_160 |
70 (0 << OXYGEN_SPI_CODEC_SHIFT) |
71 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
72 AK4396_WRITE | (reg << 8) | value);
73 data->ak4396_regs[reg] = value;
74}
75
76static void ak4396_write_cached(struct oxygen *chip, u8 reg, u8 value)
77{
78 struct hifier_data *data = chip->model_data;
79
80 if (value != data->ak4396_regs[reg])
81 ak4396_write(chip, reg, value);
82}
83
84static void hifier_registers_init(struct oxygen *chip)
85{
86 struct hifier_data *data = chip->model_data;
87
88 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
89 ak4396_write(chip, AK4396_CONTROL_2,
90 data->ak4396_regs[AK4396_CONTROL_2]);
91 ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM);
92 ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
93 ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
94}
95
96static void hifier_init(struct oxygen *chip)
97{
98 struct hifier_data *data = chip->model_data;
99
100 data->ak4396_regs[AK4396_CONTROL_2] =
101 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
102 hifier_registers_init(chip);
103
104 snd_component_add(chip->card, "AK4396");
105 snd_component_add(chip->card, "CS5340");
106}
107
108static void hifier_cleanup(struct oxygen *chip)
109{
110}
111
112static void hifier_resume(struct oxygen *chip)
113{
114 hifier_registers_init(chip);
115}
116
117static void set_ak4396_params(struct oxygen *chip,
118 struct snd_pcm_hw_params *params)
119{
120 struct hifier_data *data = chip->model_data;
121 u8 value;
122
123 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_DFS_MASK;
124 if (params_rate(params) <= 54000)
125 value |= AK4396_DFS_NORMAL;
126 else if (params_rate(params) <= 108000)
127 value |= AK4396_DFS_DOUBLE;
128 else
129 value |= AK4396_DFS_QUAD;
130
131 msleep(1); /* wait for the new MCLK to become stable */
132
133 if (value != data->ak4396_regs[AK4396_CONTROL_2]) {
134 ak4396_write(chip, AK4396_CONTROL_1,
135 AK4396_DIF_24_MSB);
136 ak4396_write(chip, AK4396_CONTROL_2, value);
137 ak4396_write(chip, AK4396_CONTROL_1,
138 AK4396_DIF_24_MSB | AK4396_RSTN);
139 }
140}
141
142static void update_ak4396_volume(struct oxygen *chip)
143{
144 ak4396_write_cached(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
145 ak4396_write_cached(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
146}
147
148static void update_ak4396_mute(struct oxygen *chip)
149{
150 struct hifier_data *data = chip->model_data;
151 u8 value;
152
153 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_SMUTE;
154 if (chip->dac_mute)
155 value |= AK4396_SMUTE;
156 ak4396_write_cached(chip, AK4396_CONTROL_2, value);
157}
158
159static void set_cs5340_params(struct oxygen *chip,
160 struct snd_pcm_hw_params *params)
161{
162}
163
164static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
165
166static const struct oxygen_model model_hifier = {
167 .shortname = "C-Media CMI8787",
168 .longname = "C-Media Oxygen HD Audio",
169 .chip = "CMI8788",
170 .init = hifier_init,
171 .cleanup = hifier_cleanup,
172 .resume = hifier_resume,
173 .get_i2s_mclk = oxygen_default_i2s_mclk,
174 .set_dac_params = set_ak4396_params,
175 .set_adc_params = set_cs5340_params,
176 .update_dac_volume = update_ak4396_volume,
177 .update_dac_mute = update_ak4396_mute,
178 .dac_tlv = ak4396_db_scale,
179 .model_data_size = sizeof(struct hifier_data),
180 .device_config = PLAYBACK_0_TO_I2S |
181 PLAYBACK_1_TO_SPDIF |
182 CAPTURE_0_FROM_I2S_1,
183 .dac_channels = 2,
184 .dac_volume_min = 0,
185 .dac_volume_max = 255,
186 .function_flags = OXYGEN_FUNCTION_SPI,
187 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
188 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
189};
190
191static int __devinit get_hifier_model(struct oxygen *chip,
192 const struct pci_device_id *id)
193{
194 chip->model = model_hifier;
195 return 0;
196}
197
198static int __devinit hifier_probe(struct pci_dev *pci,
199 const struct pci_device_id *pci_id)
200{
201 static int dev;
202 int err;
203
204 if (dev >= SNDRV_CARDS)
205 return -ENODEV;
206 if (!enable[dev]) {
207 ++dev;
208 return -ENOENT;
209 }
210 err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE,
211 hifier_ids, get_hifier_model);
212 if (err >= 0)
213 ++dev;
214 return err;
215}
216
217static struct pci_driver hifier_driver = {
218 .name = "CMI8787HiFier",
219 .id_table = hifier_ids,
220 .probe = hifier_probe,
221 .remove = __devexit_p(oxygen_pci_remove),
222#ifdef CONFIG_PM
223 .suspend = oxygen_pci_suspend,
224 .resume = oxygen_pci_resume,
225#endif
226};
227
228static int __init alsa_card_hifier_init(void)
229{
230 return pci_register_driver(&hifier_driver);
231}
232
233static void __exit alsa_card_hifier_exit(void)
234{
235 pci_unregister_driver(&hifier_driver);
236}
237
238module_init(alsa_card_hifier_init)
239module_exit(alsa_card_hifier_exit)
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 98a8eb3c92f7..d7e8ddd9a67b 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -20,19 +20,32 @@
20/* 20/*
21 * CMI8788: 21 * CMI8788:
22 * 22 *
23 * SPI 0 -> 1st AK4396 (front) 23 * SPI 0 -> 1st AK4396 (front)
24 * SPI 1 -> 2nd AK4396 (surround) 24 * SPI 1 -> 2nd AK4396 (surround)
25 * SPI 2 -> 3rd AK4396 (center/LFE) 25 * SPI 2 -> 3rd AK4396 (center/LFE)
26 * SPI 3 -> WM8785 26 * SPI 3 -> WM8785
27 * SPI 4 -> 4th AK4396 (back) 27 * SPI 4 -> 4th AK4396 (back)
28 * 28 *
29 * GPIO 0 -> DFS0 of AK5385 29 * GPIO 0 -> DFS0 of AK5385
30 * GPIO 1 -> DFS1 of AK5385 30 * GPIO 1 -> DFS1 of AK5385
31 * GPIO 8 -> enable headphone amplifier on HT-Omega models 31 *
32 * X-Meridian models:
33 * GPIO 4 -> enable extension S/PDIF input
34 * GPIO 6 -> enable on-board S/PDIF input
35 *
36 * Claro models:
37 * GPIO 6 -> S/PDIF from optical (0) or coaxial (1) input
38 * GPIO 8 -> enable headphone amplifier
32 * 39 *
33 * CM9780: 40 * CM9780:
34 * 41 *
35 * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input 42 * LINE_OUT -> input of ADC
43 *
44 * AUX_IN <- aux
45 * CD_IN <- CD
46 * MIC_IN <- mic
47 *
48 * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input
36 */ 49 */
37 50
38#include <linux/delay.h> 51#include <linux/delay.h>
@@ -41,18 +54,22 @@
41#include <sound/ac97_codec.h> 54#include <sound/ac97_codec.h>
42#include <sound/control.h> 55#include <sound/control.h>
43#include <sound/core.h> 56#include <sound/core.h>
57#include <sound/info.h>
44#include <sound/initval.h> 58#include <sound/initval.h>
45#include <sound/pcm.h> 59#include <sound/pcm.h>
46#include <sound/pcm_params.h> 60#include <sound/pcm_params.h>
47#include <sound/tlv.h> 61#include <sound/tlv.h>
48#include "oxygen.h" 62#include "oxygen.h"
63#include "xonar_dg.h"
49#include "ak4396.h" 64#include "ak4396.h"
50#include "wm8785.h" 65#include "wm8785.h"
51 66
52MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); 67MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>");
53MODULE_DESCRIPTION("C-Media CMI8788 driver"); 68MODULE_DESCRIPTION("C-Media CMI8788 driver");
54MODULE_LICENSE("GPL v2"); 69MODULE_LICENSE("GPL v2");
55MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8788}}"); 70MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8786}"
71 ",{C-Media,CMI8787}"
72 ",{C-Media,CMI8788}}");
56 73
57static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 74static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
58static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 75static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
@@ -66,24 +83,46 @@ module_param_array(enable, bool, NULL, 0444);
66MODULE_PARM_DESC(enable, "enable card"); 83MODULE_PARM_DESC(enable, "enable card");
67 84
68enum { 85enum {
69 MODEL_CMEDIA_REF, /* C-Media's reference design */ 86 MODEL_CMEDIA_REF,
70 MODEL_MERIDIAN, /* AuzenTech X-Meridian */ 87 MODEL_MERIDIAN,
71 MODEL_CLARO, /* HT-Omega Claro */ 88 MODEL_MERIDIAN_2G,
72 MODEL_CLARO_HALO, /* HT-Omega Claro halo */ 89 MODEL_CLARO,
90 MODEL_CLARO_HALO,
91 MODEL_FANTASIA,
92 MODEL_SERENADE,
93 MODEL_2CH_OUTPUT,
94 MODEL_HG2PCI,
95 MODEL_XONAR_DG,
73}; 96};
74 97
75static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { 98static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = {
99 /* C-Media's reference design */
76 { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF }, 100 { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF },
101 { OXYGEN_PCI_SUBID(0x10b0, 0x0217), .driver_data = MODEL_CMEDIA_REF },
77 { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF }, 102 { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF },
78 { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF }, 103 { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF },
79 { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, 104 { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF },
80 { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF }, 105 { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF },
81 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, 106 { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF },
82 { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF },
83 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, 107 { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF },
84 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, 108 { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF },
109 /* Asus Xonar DG */
110 { OXYGEN_PCI_SUBID(0x1043, 0x8467), .driver_data = MODEL_XONAR_DG },
111 /* PCI 2.0 HD Audio */
112 { OXYGEN_PCI_SUBID(0x13f6, 0x8782), .driver_data = MODEL_2CH_OUTPUT },
113 /* Kuroutoshikou CMI8787-HG2PCI */
114 { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI },
115 /* TempoTec HiFier Fantasia */
116 { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_FANTASIA },
117 /* TempoTec HiFier Serenade */
118 { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_SERENADE },
119 /* AuzenTech X-Meridian */
85 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, 120 { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN },
121 /* AuzenTech X-Meridian 2G */
122 { OXYGEN_PCI_SUBID(0x5431, 0x017a), .driver_data = MODEL_MERIDIAN_2G },
123 /* HT-Omega Claro */
86 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO }, 124 { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO },
125 /* HT-Omega Claro halo */
87 { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO }, 126 { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO },
88 { } 127 { }
89}; 128};
@@ -95,9 +134,15 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids);
95#define GPIO_AK5385_DFS_DOUBLE 0x0001 134#define GPIO_AK5385_DFS_DOUBLE 0x0001
96#define GPIO_AK5385_DFS_QUAD 0x0002 135#define GPIO_AK5385_DFS_QUAD 0x0002
97 136
137#define GPIO_MERIDIAN_DIG_MASK 0x0050
138#define GPIO_MERIDIAN_DIG_EXT 0x0010
139#define GPIO_MERIDIAN_DIG_BOARD 0x0040
140
141#define GPIO_CLARO_DIG_COAX 0x0040
98#define GPIO_CLARO_HP 0x0100 142#define GPIO_CLARO_HP 0x0100
99 143
100struct generic_data { 144struct generic_data {
145 unsigned int dacs;
101 u8 ak4396_regs[4][5]; 146 u8 ak4396_regs[4][5];
102 u16 wm8785_regs[3]; 147 u16 wm8785_regs[3];
103}; 148};
@@ -148,7 +193,7 @@ static void ak4396_registers_init(struct oxygen *chip)
148 struct generic_data *data = chip->model_data; 193 struct generic_data *data = chip->model_data;
149 unsigned int i; 194 unsigned int i;
150 195
151 for (i = 0; i < 4; ++i) { 196 for (i = 0; i < data->dacs; ++i) {
152 ak4396_write(chip, i, AK4396_CONTROL_1, 197 ak4396_write(chip, i, AK4396_CONTROL_1,
153 AK4396_DIF_24_MSB | AK4396_RSTN); 198 AK4396_DIF_24_MSB | AK4396_RSTN);
154 ak4396_write(chip, i, AK4396_CONTROL_2, 199 ak4396_write(chip, i, AK4396_CONTROL_2,
@@ -166,6 +211,7 @@ static void ak4396_init(struct oxygen *chip)
166{ 211{
167 struct generic_data *data = chip->model_data; 212 struct generic_data *data = chip->model_data;
168 213
214 data->dacs = chip->model.dac_channels_pcm / 2;
169 data->ak4396_regs[0][AK4396_CONTROL_2] = 215 data->ak4396_regs[0][AK4396_CONTROL_2] =
170 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; 216 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
171 ak4396_registers_init(chip); 217 ak4396_registers_init(chip);
@@ -207,6 +253,10 @@ static void generic_init(struct oxygen *chip)
207 253
208static void meridian_init(struct oxygen *chip) 254static void meridian_init(struct oxygen *chip)
209{ 255{
256 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
257 GPIO_MERIDIAN_DIG_MASK);
258 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
259 GPIO_MERIDIAN_DIG_BOARD, GPIO_MERIDIAN_DIG_MASK);
210 ak4396_init(chip); 260 ak4396_init(chip);
211 ak5385_init(chip); 261 ak5385_init(chip);
212} 262}
@@ -220,6 +270,8 @@ static void claro_enable_hp(struct oxygen *chip)
220 270
221static void claro_init(struct oxygen *chip) 271static void claro_init(struct oxygen *chip)
222{ 272{
273 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX);
274 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX);
223 ak4396_init(chip); 275 ak4396_init(chip);
224 wm8785_init(chip); 276 wm8785_init(chip);
225 claro_enable_hp(chip); 277 claro_enable_hp(chip);
@@ -227,11 +279,24 @@ static void claro_init(struct oxygen *chip)
227 279
228static void claro_halo_init(struct oxygen *chip) 280static void claro_halo_init(struct oxygen *chip)
229{ 281{
282 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_DIG_COAX);
283 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_DIG_COAX);
230 ak4396_init(chip); 284 ak4396_init(chip);
231 ak5385_init(chip); 285 ak5385_init(chip);
232 claro_enable_hp(chip); 286 claro_enable_hp(chip);
233} 287}
234 288
289static void fantasia_init(struct oxygen *chip)
290{
291 ak4396_init(chip);
292 snd_component_add(chip->card, "CS5340");
293}
294
295static void stereo_output_init(struct oxygen *chip)
296{
297 ak4396_init(chip);
298}
299
235static void generic_cleanup(struct oxygen *chip) 300static void generic_cleanup(struct oxygen *chip)
236{ 301{
237} 302}
@@ -268,6 +333,11 @@ static void claro_resume(struct oxygen *chip)
268 claro_enable_hp(chip); 333 claro_enable_hp(chip);
269} 334}
270 335
336static void stereo_resume(struct oxygen *chip)
337{
338 ak4396_registers_init(chip);
339}
340
271static void set_ak4396_params(struct oxygen *chip, 341static void set_ak4396_params(struct oxygen *chip,
272 struct snd_pcm_hw_params *params) 342 struct snd_pcm_hw_params *params)
273{ 343{
@@ -286,7 +356,7 @@ static void set_ak4396_params(struct oxygen *chip,
286 msleep(1); /* wait for the new MCLK to become stable */ 356 msleep(1); /* wait for the new MCLK to become stable */
287 357
288 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) { 358 if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) {
289 for (i = 0; i < 4; ++i) { 359 for (i = 0; i < data->dacs; ++i) {
290 ak4396_write(chip, i, AK4396_CONTROL_1, 360 ak4396_write(chip, i, AK4396_CONTROL_1,
291 AK4396_DIF_24_MSB); 361 AK4396_DIF_24_MSB);
292 ak4396_write(chip, i, AK4396_CONTROL_2, value); 362 ak4396_write(chip, i, AK4396_CONTROL_2, value);
@@ -298,9 +368,10 @@ static void set_ak4396_params(struct oxygen *chip,
298 368
299static void update_ak4396_volume(struct oxygen *chip) 369static void update_ak4396_volume(struct oxygen *chip)
300{ 370{
371 struct generic_data *data = chip->model_data;
301 unsigned int i; 372 unsigned int i;
302 373
303 for (i = 0; i < 4; ++i) { 374 for (i = 0; i < data->dacs; ++i) {
304 ak4396_write_cached(chip, i, AK4396_LCH_ATT, 375 ak4396_write_cached(chip, i, AK4396_LCH_ATT,
305 chip->dac_volume[i * 2]); 376 chip->dac_volume[i * 2]);
306 ak4396_write_cached(chip, i, AK4396_RCH_ATT, 377 ak4396_write_cached(chip, i, AK4396_RCH_ATT,
@@ -317,7 +388,7 @@ static void update_ak4396_mute(struct oxygen *chip)
317 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE; 388 value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE;
318 if (chip->dac_mute) 389 if (chip->dac_mute)
319 value |= AK4396_SMUTE; 390 value |= AK4396_SMUTE;
320 for (i = 0; i < 4; ++i) 391 for (i = 0; i < data->dacs; ++i)
321 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value); 392 ak4396_write_cached(chip, i, AK4396_CONTROL_2, value);
322} 393}
323 394
@@ -356,6 +427,10 @@ static void set_ak5385_params(struct oxygen *chip,
356 value, GPIO_AK5385_DFS_MASK); 427 value, GPIO_AK5385_DFS_MASK);
357} 428}
358 429
430static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params)
431{
432}
433
359static int rolloff_info(struct snd_kcontrol *ctl, 434static int rolloff_info(struct snd_kcontrol *ctl,
360 struct snd_ctl_elem_info *info) 435 struct snd_ctl_elem_info *info)
361{ 436{
@@ -363,13 +438,7 @@ static int rolloff_info(struct snd_kcontrol *ctl,
363 "Sharp Roll-off", "Slow Roll-off" 438 "Sharp Roll-off", "Slow Roll-off"
364 }; 439 };
365 440
366 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 441 return snd_ctl_enum_info(info, 1, 2, names);
367 info->count = 1;
368 info->value.enumerated.items = 2;
369 if (info->value.enumerated.item >= 2)
370 info->value.enumerated.item = 1;
371 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
372 return 0;
373} 442}
374 443
375static int rolloff_get(struct snd_kcontrol *ctl, 444static int rolloff_get(struct snd_kcontrol *ctl,
@@ -400,7 +469,7 @@ static int rolloff_put(struct snd_kcontrol *ctl,
400 reg &= ~AK4396_SLOW; 469 reg &= ~AK4396_SLOW;
401 changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2]; 470 changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2];
402 if (changed) { 471 if (changed) {
403 for (i = 0; i < 4; ++i) 472 for (i = 0; i < data->dacs; ++i)
404 ak4396_write(chip, i, AK4396_CONTROL_2, reg); 473 ak4396_write(chip, i, AK4396_CONTROL_2, reg);
405 } 474 }
406 mutex_unlock(&chip->mutex); 475 mutex_unlock(&chip->mutex);
@@ -421,13 +490,7 @@ static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
421 "None", "High-pass Filter" 490 "None", "High-pass Filter"
422 }; 491 };
423 492
424 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 493 return snd_ctl_enum_info(info, 1, 2, names);
425 info->count = 1;
426 info->value.enumerated.items = 2;
427 if (info->value.enumerated.item >= 2)
428 info->value.enumerated.item = 1;
429 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
430 return 0;
431} 494}
432 495
433static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 496static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
@@ -466,6 +529,100 @@ static const struct snd_kcontrol_new hpf_control = {
466 .put = hpf_put, 529 .put = hpf_put,
467}; 530};
468 531
532static int meridian_dig_source_info(struct snd_kcontrol *ctl,
533 struct snd_ctl_elem_info *info)
534{
535 static const char *const names[2] = { "On-board", "Extension" };
536
537 return snd_ctl_enum_info(info, 1, 2, names);
538}
539
540static int claro_dig_source_info(struct snd_kcontrol *ctl,
541 struct snd_ctl_elem_info *info)
542{
543 static const char *const names[2] = { "Optical", "Coaxial" };
544
545 return snd_ctl_enum_info(info, 1, 2, names);
546}
547
548static int meridian_dig_source_get(struct snd_kcontrol *ctl,
549 struct snd_ctl_elem_value *value)
550{
551 struct oxygen *chip = ctl->private_data;
552
553 value->value.enumerated.item[0] =
554 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
555 GPIO_MERIDIAN_DIG_EXT);
556 return 0;
557}
558
559static int claro_dig_source_get(struct snd_kcontrol *ctl,
560 struct snd_ctl_elem_value *value)
561{
562 struct oxygen *chip = ctl->private_data;
563
564 value->value.enumerated.item[0] =
565 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) &
566 GPIO_CLARO_DIG_COAX);
567 return 0;
568}
569
570static int meridian_dig_source_put(struct snd_kcontrol *ctl,
571 struct snd_ctl_elem_value *value)
572{
573 struct oxygen *chip = ctl->private_data;
574 u16 old_reg, new_reg;
575 int changed;
576
577 mutex_lock(&chip->mutex);
578 old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
579 new_reg = old_reg & ~GPIO_MERIDIAN_DIG_MASK;
580 if (value->value.enumerated.item[0] == 0)
581 new_reg |= GPIO_MERIDIAN_DIG_BOARD;
582 else
583 new_reg |= GPIO_MERIDIAN_DIG_EXT;
584 changed = new_reg != old_reg;
585 if (changed)
586 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
587 mutex_unlock(&chip->mutex);
588 return changed;
589}
590
591static int claro_dig_source_put(struct snd_kcontrol *ctl,
592 struct snd_ctl_elem_value *value)
593{
594 struct oxygen *chip = ctl->private_data;
595 u16 old_reg, new_reg;
596 int changed;
597
598 mutex_lock(&chip->mutex);
599 old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA);
600 new_reg = old_reg & ~GPIO_CLARO_DIG_COAX;
601 if (value->value.enumerated.item[0])
602 new_reg |= GPIO_CLARO_DIG_COAX;
603 changed = new_reg != old_reg;
604 if (changed)
605 oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg);
606 mutex_unlock(&chip->mutex);
607 return changed;
608}
609
610static const struct snd_kcontrol_new meridian_dig_source_control = {
611 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
612 .name = "IEC958 Source Capture Enum",
613 .info = meridian_dig_source_info,
614 .get = meridian_dig_source_get,
615 .put = meridian_dig_source_put,
616};
617
618static const struct snd_kcontrol_new claro_dig_source_control = {
619 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
620 .name = "IEC958 Source Capture Enum",
621 .info = claro_dig_source_info,
622 .get = claro_dig_source_get,
623 .put = claro_dig_source_put,
624};
625
469static int generic_mixer_init(struct oxygen *chip) 626static int generic_mixer_init(struct oxygen *chip)
470{ 627{
471 return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); 628 return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip));
@@ -484,6 +641,81 @@ static int generic_wm8785_mixer_init(struct oxygen *chip)
484 return 0; 641 return 0;
485} 642}
486 643
644static int meridian_mixer_init(struct oxygen *chip)
645{
646 int err;
647
648 err = generic_mixer_init(chip);
649 if (err < 0)
650 return err;
651 err = snd_ctl_add(chip->card,
652 snd_ctl_new1(&meridian_dig_source_control, chip));
653 if (err < 0)
654 return err;
655 return 0;
656}
657
658static int claro_mixer_init(struct oxygen *chip)
659{
660 int err;
661
662 err = generic_wm8785_mixer_init(chip);
663 if (err < 0)
664 return err;
665 err = snd_ctl_add(chip->card,
666 snd_ctl_new1(&claro_dig_source_control, chip));
667 if (err < 0)
668 return err;
669 return 0;
670}
671
672static int claro_halo_mixer_init(struct oxygen *chip)
673{
674 int err;
675
676 err = generic_mixer_init(chip);
677 if (err < 0)
678 return err;
679 err = snd_ctl_add(chip->card,
680 snd_ctl_new1(&claro_dig_source_control, chip));
681 if (err < 0)
682 return err;
683 return 0;
684}
685
686static void dump_ak4396_registers(struct oxygen *chip,
687 struct snd_info_buffer *buffer)
688{
689 struct generic_data *data = chip->model_data;
690 unsigned int dac, i;
691
692 for (dac = 0; dac < data->dacs; ++dac) {
693 snd_iprintf(buffer, "\nAK4396 %u:", dac + 1);
694 for (i = 0; i < 5; ++i)
695 snd_iprintf(buffer, " %02x", data->ak4396_regs[dac][i]);
696 }
697 snd_iprintf(buffer, "\n");
698}
699
700static void dump_wm8785_registers(struct oxygen *chip,
701 struct snd_info_buffer *buffer)
702{
703 struct generic_data *data = chip->model_data;
704 unsigned int i;
705
706 snd_iprintf(buffer, "\nWM8785:");
707 for (i = 0; i < 3; ++i)
708 snd_iprintf(buffer, " %03x", data->wm8785_regs[i]);
709 snd_iprintf(buffer, "\n");
710}
711
712static void dump_oxygen_registers(struct oxygen *chip,
713 struct snd_info_buffer *buffer)
714{
715 dump_ak4396_registers(chip, buffer);
716 dump_wm8785_registers(chip, buffer);
717}
718
487static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); 719static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);
488 720
489static const struct oxygen_model model_generic = { 721static const struct oxygen_model model_generic = {
@@ -494,11 +726,11 @@ static const struct oxygen_model model_generic = {
494 .mixer_init = generic_wm8785_mixer_init, 726 .mixer_init = generic_wm8785_mixer_init,
495 .cleanup = generic_cleanup, 727 .cleanup = generic_cleanup,
496 .resume = generic_resume, 728 .resume = generic_resume,
497 .get_i2s_mclk = oxygen_default_i2s_mclk,
498 .set_dac_params = set_ak4396_params, 729 .set_dac_params = set_ak4396_params,
499 .set_adc_params = set_wm8785_params, 730 .set_adc_params = set_wm8785_params,
500 .update_dac_volume = update_ak4396_volume, 731 .update_dac_volume = update_ak4396_volume,
501 .update_dac_mute = update_ak4396_mute, 732 .update_dac_mute = update_ak4396_mute,
733 .dump_registers = dump_oxygen_registers,
502 .dac_tlv = ak4396_db_scale, 734 .dac_tlv = ak4396_db_scale,
503 .model_data_size = sizeof(struct generic_data), 735 .model_data_size = sizeof(struct generic_data),
504 .device_config = PLAYBACK_0_TO_I2S | 736 .device_config = PLAYBACK_0_TO_I2S |
@@ -508,11 +740,14 @@ static const struct oxygen_model model_generic = {
508 CAPTURE_1_FROM_SPDIF | 740 CAPTURE_1_FROM_SPDIF |
509 CAPTURE_2_FROM_AC97_1 | 741 CAPTURE_2_FROM_AC97_1 |
510 AC97_CD_INPUT, 742 AC97_CD_INPUT,
511 .dac_channels = 8, 743 .dac_channels_pcm = 8,
744 .dac_channels_mixer = 8,
512 .dac_volume_min = 0, 745 .dac_volume_min = 0,
513 .dac_volume_max = 255, 746 .dac_volume_max = 255,
514 .function_flags = OXYGEN_FUNCTION_SPI | 747 .function_flags = OXYGEN_FUNCTION_SPI |
515 OXYGEN_FUNCTION_ENABLE_SPI_4_5, 748 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
749 .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
750 .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
516 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 751 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
517 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 752 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
518}; 753};
@@ -520,42 +755,87 @@ static const struct oxygen_model model_generic = {
520static int __devinit get_oxygen_model(struct oxygen *chip, 755static int __devinit get_oxygen_model(struct oxygen *chip,
521 const struct pci_device_id *id) 756 const struct pci_device_id *id)
522{ 757{
758 static const char *const names[] = {
759 [MODEL_MERIDIAN] = "AuzenTech X-Meridian",
760 [MODEL_MERIDIAN_2G] = "AuzenTech X-Meridian 2G",
761 [MODEL_CLARO] = "HT-Omega Claro",
762 [MODEL_CLARO_HALO] = "HT-Omega Claro halo",
763 [MODEL_FANTASIA] = "TempoTec HiFier Fantasia",
764 [MODEL_SERENADE] = "TempoTec HiFier Serenade",
765 [MODEL_HG2PCI] = "CMI8787-HG2PCI",
766 };
767
523 chip->model = model_generic; 768 chip->model = model_generic;
524 switch (id->driver_data) { 769 switch (id->driver_data) {
525 case MODEL_MERIDIAN: 770 case MODEL_MERIDIAN:
771 case MODEL_MERIDIAN_2G:
526 chip->model.init = meridian_init; 772 chip->model.init = meridian_init;
527 chip->model.mixer_init = generic_mixer_init; 773 chip->model.mixer_init = meridian_mixer_init;
528 chip->model.resume = meridian_resume; 774 chip->model.resume = meridian_resume;
529 chip->model.set_adc_params = set_ak5385_params; 775 chip->model.set_adc_params = set_ak5385_params;
776 chip->model.dump_registers = dump_ak4396_registers;
530 chip->model.device_config = PLAYBACK_0_TO_I2S | 777 chip->model.device_config = PLAYBACK_0_TO_I2S |
531 PLAYBACK_1_TO_SPDIF | 778 PLAYBACK_1_TO_SPDIF |
532 CAPTURE_0_FROM_I2S_2 | 779 CAPTURE_0_FROM_I2S_2 |
533 CAPTURE_1_FROM_SPDIF; 780 CAPTURE_1_FROM_SPDIF;
781 if (id->driver_data == MODEL_MERIDIAN)
782 chip->model.device_config |= AC97_CD_INPUT;
534 break; 783 break;
535 case MODEL_CLARO: 784 case MODEL_CLARO:
536 chip->model.init = claro_init; 785 chip->model.init = claro_init;
786 chip->model.mixer_init = claro_mixer_init;
537 chip->model.cleanup = claro_cleanup; 787 chip->model.cleanup = claro_cleanup;
538 chip->model.suspend = claro_suspend; 788 chip->model.suspend = claro_suspend;
539 chip->model.resume = claro_resume; 789 chip->model.resume = claro_resume;
540 break; 790 break;
541 case MODEL_CLARO_HALO: 791 case MODEL_CLARO_HALO:
542 chip->model.init = claro_halo_init; 792 chip->model.init = claro_halo_init;
543 chip->model.mixer_init = generic_mixer_init; 793 chip->model.mixer_init = claro_halo_mixer_init;
544 chip->model.cleanup = claro_cleanup; 794 chip->model.cleanup = claro_cleanup;
545 chip->model.suspend = claro_suspend; 795 chip->model.suspend = claro_suspend;
546 chip->model.resume = claro_resume; 796 chip->model.resume = claro_resume;
547 chip->model.set_adc_params = set_ak5385_params; 797 chip->model.set_adc_params = set_ak5385_params;
798 chip->model.dump_registers = dump_ak4396_registers;
548 chip->model.device_config = PLAYBACK_0_TO_I2S | 799 chip->model.device_config = PLAYBACK_0_TO_I2S |
549 PLAYBACK_1_TO_SPDIF | 800 PLAYBACK_1_TO_SPDIF |
550 CAPTURE_0_FROM_I2S_2 | 801 CAPTURE_0_FROM_I2S_2 |
551 CAPTURE_1_FROM_SPDIF; 802 CAPTURE_1_FROM_SPDIF;
552 break; 803 break;
804 case MODEL_FANTASIA:
805 case MODEL_SERENADE:
806 case MODEL_2CH_OUTPUT:
807 case MODEL_HG2PCI:
808 chip->model.shortname = "C-Media CMI8787";
809 chip->model.chip = "CMI8787";
810 if (id->driver_data == MODEL_FANTASIA)
811 chip->model.init = fantasia_init;
812 else
813 chip->model.init = stereo_output_init;
814 chip->model.resume = stereo_resume;
815 chip->model.mixer_init = generic_mixer_init;
816 chip->model.set_adc_params = set_no_params;
817 chip->model.dump_registers = dump_ak4396_registers;
818 chip->model.device_config = PLAYBACK_0_TO_I2S |
819 PLAYBACK_1_TO_SPDIF;
820 if (id->driver_data == MODEL_FANTASIA) {
821 chip->model.device_config |= CAPTURE_0_FROM_I2S_1;
822 chip->model.adc_mclks = OXYGEN_MCLKS(256, 128, 128);
823 }
824 chip->model.dac_channels_pcm = 2;
825 chip->model.dac_channels_mixer = 2;
826 break;
827 case MODEL_XONAR_DG:
828 chip->model = model_xonar_dg;
829 break;
553 } 830 }
554 if (id->driver_data == MODEL_MERIDIAN || 831 if (id->driver_data == MODEL_MERIDIAN ||
832 id->driver_data == MODEL_MERIDIAN_2G ||
555 id->driver_data == MODEL_CLARO_HALO) { 833 id->driver_data == MODEL_CLARO_HALO) {
556 chip->model.misc_flags = OXYGEN_MISC_MIDI; 834 chip->model.misc_flags = OXYGEN_MISC_MIDI;
557 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; 835 chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT;
558 } 836 }
837 if (id->driver_data < ARRAY_SIZE(names) && names[id->driver_data])
838 chip->model.shortname = names[id->driver_data];
559 return 0; 839 return 0;
560} 840}
561 841
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 7d5222caa0a9..c2ae63d17cd2 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -16,6 +16,10 @@
16#define PCM_AC97 5 16#define PCM_AC97 5
17#define PCM_COUNT 6 17#define PCM_COUNT 6
18 18
19#define OXYGEN_MCLKS(f_single, f_double, f_quad) ((MCLK_##f_single << 0) | \
20 (MCLK_##f_double << 2) | \
21 (MCLK_##f_quad << 4))
22
19#define OXYGEN_IO_SIZE 0x100 23#define OXYGEN_IO_SIZE 0x100
20 24
21#define OXYGEN_EEPROM_ID 0x434d /* "CM" */ 25#define OXYGEN_EEPROM_ID 0x434d /* "CM" */
@@ -35,6 +39,7 @@
35#define MIDI_OUTPUT 0x0800 39#define MIDI_OUTPUT 0x0800
36#define MIDI_INPUT 0x1000 40#define MIDI_INPUT 0x1000
37#define AC97_CD_INPUT 0x2000 41#define AC97_CD_INPUT 0x2000
42#define AC97_FMIC_SWITCH 0x4000
38 43
39enum { 44enum {
40 CONTROL_SPDIF_PCM, 45 CONTROL_SPDIF_PCM,
@@ -65,6 +70,7 @@ struct snd_pcm_hardware;
65struct snd_pcm_hw_params; 70struct snd_pcm_hw_params;
66struct snd_kcontrol_new; 71struct snd_kcontrol_new;
67struct snd_rawmidi; 72struct snd_rawmidi;
73struct snd_info_buffer;
68struct oxygen; 74struct oxygen;
69 75
70struct oxygen_model { 76struct oxygen_model {
@@ -79,8 +85,6 @@ struct oxygen_model {
79 void (*resume)(struct oxygen *chip); 85 void (*resume)(struct oxygen *chip);
80 void (*pcm_hardware_filter)(unsigned int channel, 86 void (*pcm_hardware_filter)(unsigned int channel,
81 struct snd_pcm_hardware *hardware); 87 struct snd_pcm_hardware *hardware);
82 unsigned int (*get_i2s_mclk)(struct oxygen *chip, unsigned int channel,
83 struct snd_pcm_hw_params *hw_params);
84 void (*set_dac_params)(struct oxygen *chip, 88 void (*set_dac_params)(struct oxygen *chip,
85 struct snd_pcm_hw_params *params); 89 struct snd_pcm_hw_params *params);
86 void (*set_adc_params)(struct oxygen *chip, 90 void (*set_adc_params)(struct oxygen *chip,
@@ -92,15 +96,19 @@ struct oxygen_model {
92 void (*uart_input)(struct oxygen *chip); 96 void (*uart_input)(struct oxygen *chip);
93 void (*ac97_switch)(struct oxygen *chip, 97 void (*ac97_switch)(struct oxygen *chip,
94 unsigned int reg, unsigned int mute); 98 unsigned int reg, unsigned int mute);
99 void (*dump_registers)(struct oxygen *chip,
100 struct snd_info_buffer *buffer);
95 const unsigned int *dac_tlv; 101 const unsigned int *dac_tlv;
96 unsigned long private_data;
97 size_t model_data_size; 102 size_t model_data_size;
98 unsigned int device_config; 103 unsigned int device_config;
99 u8 dac_channels; 104 u8 dac_channels_pcm;
105 u8 dac_channels_mixer;
100 u8 dac_volume_min; 106 u8 dac_volume_min;
101 u8 dac_volume_max; 107 u8 dac_volume_max;
102 u8 misc_flags; 108 u8 misc_flags;
103 u8 function_flags; 109 u8 function_flags;
110 u8 dac_mclks;
111 u8 adc_mclks;
104 u16 dac_i2s_format; 112 u16 dac_i2s_format;
105 u16 adc_i2s_format; 113 u16 adc_i2s_format;
106}; 114};
@@ -121,7 +129,6 @@ struct oxygen {
121 u8 pcm_running; 129 u8 pcm_running;
122 u8 dac_routing; 130 u8 dac_routing;
123 u8 spdif_playback_enable; 131 u8 spdif_playback_enable;
124 u8 revision;
125 u8 has_ac97_0; 132 u8 has_ac97_0;
126 u8 has_ac97_1; 133 u8 has_ac97_1;
127 u32 spdif_bits; 134 u32 spdif_bits;
@@ -167,8 +174,6 @@ void oxygen_update_spdif_source(struct oxygen *chip);
167/* oxygen_pcm.c */ 174/* oxygen_pcm.c */
168 175
169int oxygen_pcm_init(struct oxygen *chip); 176int oxygen_pcm_init(struct oxygen *chip);
170unsigned int oxygen_default_i2s_mclk(struct oxygen *chip, unsigned int channel,
171 struct snd_pcm_hw_params *hw_params);
172 177
173/* oxygen_io.c */ 178/* oxygen_io.c */
174 179
diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c
index 09b2b2a36df5..f5164b1e1c80 100644
--- a/sound/pci/oxygen/oxygen_io.c
+++ b/sound/pci/oxygen/oxygen_io.c
@@ -197,11 +197,11 @@ void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data)
197{ 197{
198 unsigned int count; 198 unsigned int count;
199 199
200 /* should not need more than 7.68 us (24 * 320 ns) */ 200 /* should not need more than 30.72 us (24 * 1.28 us) */
201 count = 10; 201 count = 10;
202 while ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & OXYGEN_SPI_BUSY) 202 while ((oxygen_read8(chip, OXYGEN_SPI_CONTROL) & OXYGEN_SPI_BUSY)
203 && count > 0) { 203 && count > 0) {
204 udelay(1); 204 udelay(4);
205 --count; 205 --count;
206 } 206 }
207 207
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 969605fbcb7f..70b739816fcc 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -202,7 +202,13 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
202 struct oxygen *chip = entry->private_data; 202 struct oxygen *chip = entry->private_data;
203 int i, j; 203 int i, j;
204 204
205 snd_iprintf(buffer, "CMI8788\n\n"); 205 switch (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_PACKAGE_ID_MASK) {
206 case OXYGEN_PACKAGE_ID_8786: i = '6'; break;
207 case OXYGEN_PACKAGE_ID_8787: i = '7'; break;
208 case OXYGEN_PACKAGE_ID_8788: i = '8'; break;
209 default: i = '?'; break;
210 }
211 snd_iprintf(buffer, "CMI878%c:\n", i);
206 for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) { 212 for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) {
207 snd_iprintf(buffer, "%02x:", i); 213 snd_iprintf(buffer, "%02x:", i);
208 for (j = 0; j < 0x10; ++j) 214 for (j = 0; j < 0x10; ++j)
@@ -212,7 +218,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
212 if (mutex_lock_interruptible(&chip->mutex) < 0) 218 if (mutex_lock_interruptible(&chip->mutex) < 0)
213 return; 219 return;
214 if (chip->has_ac97_0) { 220 if (chip->has_ac97_0) {
215 snd_iprintf(buffer, "\nAC97\n"); 221 snd_iprintf(buffer, "\nAC97:\n");
216 for (i = 0; i < 0x80; i += 0x10) { 222 for (i = 0; i < 0x80; i += 0x10) {
217 snd_iprintf(buffer, "%02x:", i); 223 snd_iprintf(buffer, "%02x:", i);
218 for (j = 0; j < 0x10; j += 2) 224 for (j = 0; j < 0x10; j += 2)
@@ -222,7 +228,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
222 } 228 }
223 } 229 }
224 if (chip->has_ac97_1) { 230 if (chip->has_ac97_1) {
225 snd_iprintf(buffer, "\nAC97 2\n"); 231 snd_iprintf(buffer, "\nAC97 2:\n");
226 for (i = 0; i < 0x80; i += 0x10) { 232 for (i = 0; i < 0x80; i += 0x10) {
227 snd_iprintf(buffer, "%02x:", i); 233 snd_iprintf(buffer, "%02x:", i);
228 for (j = 0; j < 0x10; j += 2) 234 for (j = 0; j < 0x10; j += 2)
@@ -232,13 +238,15 @@ static void oxygen_proc_read(struct snd_info_entry *entry,
232 } 238 }
233 } 239 }
234 mutex_unlock(&chip->mutex); 240 mutex_unlock(&chip->mutex);
241 if (chip->model.dump_registers)
242 chip->model.dump_registers(chip, buffer);
235} 243}
236 244
237static void oxygen_proc_init(struct oxygen *chip) 245static void oxygen_proc_init(struct oxygen *chip)
238{ 246{
239 struct snd_info_entry *entry; 247 struct snd_info_entry *entry;
240 248
241 if (!snd_card_proc_new(chip->card, "cmi8788", &entry)) 249 if (!snd_card_proc_new(chip->card, "oxygen", &entry))
242 snd_info_set_text_ops(entry, chip, oxygen_proc_read); 250 snd_info_set_text_ops(entry, chip, oxygen_proc_read);
243} 251}
244#else 252#else
@@ -262,7 +270,7 @@ oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[])
262 */ 270 */
263 subdevice = oxygen_read_eeprom(chip, 2); 271 subdevice = oxygen_read_eeprom(chip, 2);
264 /* use default ID if EEPROM is missing */ 272 /* use default ID if EEPROM is missing */
265 if (subdevice == 0xffff) 273 if (subdevice == 0xffff && oxygen_read_eeprom(chip, 1) == 0xffff)
266 subdevice = 0x8788; 274 subdevice = 0x8788;
267 /* 275 /*
268 * We use only the subsystem device ID for searching because it is 276 * We use only the subsystem device ID for searching because it is
@@ -364,12 +372,7 @@ static void oxygen_init(struct oxygen *chip)
364 (IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT); 372 (IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT);
365 chip->spdif_pcm_bits = chip->spdif_bits; 373 chip->spdif_pcm_bits = chip->spdif_bits;
366 374
367 if (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_REVISION_2) 375 if (!(oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_REVISION_2))
368 chip->revision = 2;
369 else
370 chip->revision = 1;
371
372 if (chip->revision == 1)
373 oxygen_set_bits8(chip, OXYGEN_MISC, 376 oxygen_set_bits8(chip, OXYGEN_MISC,
374 OXYGEN_MISC_PCI_MEM_W_1_CLOCK); 377 OXYGEN_MISC_PCI_MEM_W_1_CLOCK);
375 378
@@ -406,28 +409,40 @@ static void oxygen_init(struct oxygen *chip)
406 (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT)); 409 (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT));
407 oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2); 410 oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2);
408 oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT, 411 oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT,
409 OXYGEN_RATE_48000 | chip->model.dac_i2s_format | 412 OXYGEN_RATE_48000 |
410 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 413 chip->model.dac_i2s_format |
411 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 414 OXYGEN_I2S_MCLK(chip->model.dac_mclks) |
415 OXYGEN_I2S_BITS_16 |
416 OXYGEN_I2S_MASTER |
417 OXYGEN_I2S_BCLK_64);
412 if (chip->model.device_config & CAPTURE_0_FROM_I2S_1) 418 if (chip->model.device_config & CAPTURE_0_FROM_I2S_1)
413 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 419 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
414 OXYGEN_RATE_48000 | chip->model.adc_i2s_format | 420 OXYGEN_RATE_48000 |
415 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 421 chip->model.adc_i2s_format |
416 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 422 OXYGEN_I2S_MCLK(chip->model.adc_mclks) |
423 OXYGEN_I2S_BITS_16 |
424 OXYGEN_I2S_MASTER |
425 OXYGEN_I2S_BCLK_64);
417 else 426 else
418 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 427 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
419 OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); 428 OXYGEN_I2S_MASTER |
429 OXYGEN_I2S_MUTE_MCLK);
420 if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 | 430 if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 |
421 CAPTURE_2_FROM_I2S_2)) 431 CAPTURE_2_FROM_I2S_2))
422 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, 432 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
423 OXYGEN_RATE_48000 | chip->model.adc_i2s_format | 433 OXYGEN_RATE_48000 |
424 OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | 434 chip->model.adc_i2s_format |
425 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 435 OXYGEN_I2S_MCLK(chip->model.adc_mclks) |
436 OXYGEN_I2S_BITS_16 |
437 OXYGEN_I2S_MASTER |
438 OXYGEN_I2S_BCLK_64);
426 else 439 else
427 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, 440 oxygen_write16(chip, OXYGEN_I2S_B_FORMAT,
428 OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); 441 OXYGEN_I2S_MASTER |
442 OXYGEN_I2S_MUTE_MCLK);
429 oxygen_write16(chip, OXYGEN_I2S_C_FORMAT, 443 oxygen_write16(chip, OXYGEN_I2S_C_FORMAT,
430 OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); 444 OXYGEN_I2S_MASTER |
445 OXYGEN_I2S_MUTE_MCLK);
431 oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, 446 oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL,
432 OXYGEN_SPDIF_OUT_ENABLE | 447 OXYGEN_SPDIF_OUT_ENABLE |
433 OXYGEN_SPDIF_LOOPBACK); 448 OXYGEN_SPDIF_LOOPBACK);
@@ -649,8 +664,8 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
649 664
650 strcpy(card->driver, chip->model.chip); 665 strcpy(card->driver, chip->model.chip);
651 strcpy(card->shortname, chip->model.shortname); 666 strcpy(card->shortname, chip->model.shortname);
652 sprintf(card->longname, "%s (rev %u) at %#lx, irq %i", 667 sprintf(card->longname, "%s at %#lx, irq %i",
653 chip->model.longname, chip->revision, chip->addr, chip->irq); 668 chip->model.longname, chip->addr, chip->irq);
654 strcpy(card->mixername, chip->model.chip); 669 strcpy(card->mixername, chip->model.chip);
655 snd_component_add(card, chip->model.chip); 670 snd_component_add(card, chip->model.chip);
656 671
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 2849b36f5f7e..9bff14d5895d 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -31,7 +31,7 @@ static int dac_volume_info(struct snd_kcontrol *ctl,
31 struct oxygen *chip = ctl->private_data; 31 struct oxygen *chip = ctl->private_data;
32 32
33 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 33 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
34 info->count = chip->model.dac_channels; 34 info->count = chip->model.dac_channels_mixer;
35 info->value.integer.min = chip->model.dac_volume_min; 35 info->value.integer.min = chip->model.dac_volume_min;
36 info->value.integer.max = chip->model.dac_volume_max; 36 info->value.integer.max = chip->model.dac_volume_max;
37 return 0; 37 return 0;
@@ -44,7 +44,7 @@ static int dac_volume_get(struct snd_kcontrol *ctl,
44 unsigned int i; 44 unsigned int i;
45 45
46 mutex_lock(&chip->mutex); 46 mutex_lock(&chip->mutex);
47 for (i = 0; i < chip->model.dac_channels; ++i) 47 for (i = 0; i < chip->model.dac_channels_mixer; ++i)
48 value->value.integer.value[i] = chip->dac_volume[i]; 48 value->value.integer.value[i] = chip->dac_volume[i];
49 mutex_unlock(&chip->mutex); 49 mutex_unlock(&chip->mutex);
50 return 0; 50 return 0;
@@ -59,7 +59,7 @@ static int dac_volume_put(struct snd_kcontrol *ctl,
59 59
60 changed = 0; 60 changed = 0;
61 mutex_lock(&chip->mutex); 61 mutex_lock(&chip->mutex);
62 for (i = 0; i < chip->model.dac_channels; ++i) 62 for (i = 0; i < chip->model.dac_channels_mixer; ++i)
63 if (value->value.integer.value[i] != chip->dac_volume[i]) { 63 if (value->value.integer.value[i] != chip->dac_volume[i]) {
64 chip->dac_volume[i] = value->value.integer.value[i]; 64 chip->dac_volume[i] = value->value.integer.value[i];
65 changed = 1; 65 changed = 1;
@@ -97,6 +97,16 @@ static int dac_mute_put(struct snd_kcontrol *ctl,
97 return changed; 97 return changed;
98} 98}
99 99
100static unsigned int upmix_item_count(struct oxygen *chip)
101{
102 if (chip->model.dac_channels_pcm < 8)
103 return 2;
104 else if (chip->model.update_center_lfe_mix)
105 return 5;
106 else
107 return 3;
108}
109
100static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 110static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
101{ 111{
102 static const char *const names[5] = { 112 static const char *const names[5] = {
@@ -107,15 +117,9 @@ static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
107 "Front+Surround+Center/LFE+Back", 117 "Front+Surround+Center/LFE+Back",
108 }; 118 };
109 struct oxygen *chip = ctl->private_data; 119 struct oxygen *chip = ctl->private_data;
110 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3; 120 unsigned int count = upmix_item_count(chip);
111 121
112 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 122 return snd_ctl_enum_info(info, 1, count, names);
113 info->count = 1;
114 info->value.enumerated.items = count;
115 if (info->value.enumerated.item >= count)
116 info->value.enumerated.item = count - 1;
117 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
118 return 0;
119} 123}
120 124
121static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 125static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
@@ -188,7 +192,7 @@ void oxygen_update_dac_routing(struct oxygen *chip)
188static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 192static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
189{ 193{
190 struct oxygen *chip = ctl->private_data; 194 struct oxygen *chip = ctl->private_data;
191 unsigned int count = chip->model.update_center_lfe_mix ? 5 : 3; 195 unsigned int count = upmix_item_count(chip);
192 int changed; 196 int changed;
193 197
194 if (value->value.enumerated.item[0] >= count) 198 if (value->value.enumerated.item[0] >= count)
@@ -430,30 +434,31 @@ static int spdif_input_default_get(struct snd_kcontrol *ctl,
430 return 0; 434 return 0;
431} 435}
432 436
433static int spdif_loopback_get(struct snd_kcontrol *ctl, 437static int spdif_bit_switch_get(struct snd_kcontrol *ctl,
434 struct snd_ctl_elem_value *value) 438 struct snd_ctl_elem_value *value)
435{ 439{
436 struct oxygen *chip = ctl->private_data; 440 struct oxygen *chip = ctl->private_data;
441 u32 bit = ctl->private_value;
437 442
438 value->value.integer.value[0] = 443 value->value.integer.value[0] =
439 !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) 444 !!(oxygen_read32(chip, OXYGEN_SPDIF_CONTROL) & bit);
440 & OXYGEN_SPDIF_LOOPBACK);
441 return 0; 445 return 0;
442} 446}
443 447
444static int spdif_loopback_put(struct snd_kcontrol *ctl, 448static int spdif_bit_switch_put(struct snd_kcontrol *ctl,
445 struct snd_ctl_elem_value *value) 449 struct snd_ctl_elem_value *value)
446{ 450{
447 struct oxygen *chip = ctl->private_data; 451 struct oxygen *chip = ctl->private_data;
452 u32 bit = ctl->private_value;
448 u32 oldreg, newreg; 453 u32 oldreg, newreg;
449 int changed; 454 int changed;
450 455
451 spin_lock_irq(&chip->reg_lock); 456 spin_lock_irq(&chip->reg_lock);
452 oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL); 457 oldreg = oxygen_read32(chip, OXYGEN_SPDIF_CONTROL);
453 if (value->value.integer.value[0]) 458 if (value->value.integer.value[0])
454 newreg = oldreg | OXYGEN_SPDIF_LOOPBACK; 459 newreg = oldreg | bit;
455 else 460 else
456 newreg = oldreg & ~OXYGEN_SPDIF_LOOPBACK; 461 newreg = oldreg & ~bit;
457 changed = newreg != oldreg; 462 changed = newreg != oldreg;
458 if (changed) 463 if (changed)
459 oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg); 464 oxygen_write32(chip, OXYGEN_SPDIF_CONTROL, newreg);
@@ -644,6 +649,46 @@ static int ac97_volume_put(struct snd_kcontrol *ctl,
644 return change; 649 return change;
645} 650}
646 651
652static int mic_fmic_source_info(struct snd_kcontrol *ctl,
653 struct snd_ctl_elem_info *info)
654{
655 static const char *const names[] = { "Mic Jack", "Front Panel" };
656
657 return snd_ctl_enum_info(info, 1, 2, names);
658}
659
660static int mic_fmic_source_get(struct snd_kcontrol *ctl,
661 struct snd_ctl_elem_value *value)
662{
663 struct oxygen *chip = ctl->private_data;
664
665 mutex_lock(&chip->mutex);
666 value->value.enumerated.item[0] =
667 !!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC);
668 mutex_unlock(&chip->mutex);
669 return 0;
670}
671
672static int mic_fmic_source_put(struct snd_kcontrol *ctl,
673 struct snd_ctl_elem_value *value)
674{
675 struct oxygen *chip = ctl->private_data;
676 u16 oldreg, newreg;
677 int change;
678
679 mutex_lock(&chip->mutex);
680 oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK);
681 if (value->value.enumerated.item[0])
682 newreg = oldreg | CM9780_FMIC2MIC;
683 else
684 newreg = oldreg & ~CM9780_FMIC2MIC;
685 change = newreg != oldreg;
686 if (change)
687 oxygen_write_ac97(chip, 0, CM9780_JACK, newreg);
688 mutex_unlock(&chip->mutex);
689 return change;
690}
691
647static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl, 692static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl,
648 struct snd_ctl_elem_info *info) 693 struct snd_ctl_elem_info *info)
649{ 694{
@@ -791,8 +836,17 @@ static const struct snd_kcontrol_new spdif_input_controls[] = {
791 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 836 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
792 .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH), 837 .name = SNDRV_CTL_NAME_IEC958("Loopback ", NONE, SWITCH),
793 .info = snd_ctl_boolean_mono_info, 838 .info = snd_ctl_boolean_mono_info,
794 .get = spdif_loopback_get, 839 .get = spdif_bit_switch_get,
795 .put = spdif_loopback_put, 840 .put = spdif_bit_switch_put,
841 .private_value = OXYGEN_SPDIF_LOOPBACK,
842 },
843 {
844 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
845 .name = SNDRV_CTL_NAME_IEC958("Validity Check ",CAPTURE,SWITCH),
846 .info = snd_ctl_boolean_mono_info,
847 .get = spdif_bit_switch_get,
848 .put = spdif_bit_switch_put,
849 .private_value = OXYGEN_SPDIF_SPDVALID,
796 }, 850 },
797}; 851};
798 852
@@ -908,6 +962,13 @@ static const struct snd_kcontrol_new ac97_controls[] = {
908 AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0), 962 AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0),
909 AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), 963 AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1),
910 AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), 964 AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0),
965 {
966 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
967 .name = "Mic Source Capture Enum",
968 .info = mic_fmic_source_info,
969 .get = mic_fmic_source_get,
970 .put = mic_fmic_source_put,
971 },
911 AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), 972 AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1),
912 AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1), 973 AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1),
913 AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), 974 AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1),
@@ -970,7 +1031,10 @@ static int add_controls(struct oxygen *chip,
970 continue; 1031 continue;
971 } 1032 }
972 if (!strcmp(template.name, "Stereo Upmixing") && 1033 if (!strcmp(template.name, "Stereo Upmixing") &&
973 chip->model.dac_channels == 2) 1034 chip->model.dac_channels_pcm == 2)
1035 continue;
1036 if (!strcmp(template.name, "Mic Source Capture Enum") &&
1037 !(chip->model.device_config & AC97_FMIC_SWITCH))
974 continue; 1038 continue;
975 if (!strncmp(template.name, "CD Capture ", 11) && 1039 if (!strncmp(template.name, "CD Capture ", 11) &&
976 !(chip->model.device_config & AC97_CD_INPUT)) 1040 !(chip->model.device_config & AC97_CD_INPUT))
diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c
index 814667442eb0..d5533e34ece9 100644
--- a/sound/pci/oxygen/oxygen_pcm.c
+++ b/sound/pci/oxygen/oxygen_pcm.c
@@ -39,7 +39,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = {
39 SNDRV_PCM_INFO_MMAP_VALID | 39 SNDRV_PCM_INFO_MMAP_VALID |
40 SNDRV_PCM_INFO_INTERLEAVED | 40 SNDRV_PCM_INFO_INTERLEAVED |
41 SNDRV_PCM_INFO_PAUSE | 41 SNDRV_PCM_INFO_PAUSE |
42 SNDRV_PCM_INFO_SYNC_START, 42 SNDRV_PCM_INFO_SYNC_START |
43 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
43 .formats = SNDRV_PCM_FMTBIT_S16_LE | 44 .formats = SNDRV_PCM_FMTBIT_S16_LE |
44 SNDRV_PCM_FMTBIT_S32_LE, 45 SNDRV_PCM_FMTBIT_S32_LE,
45 .rates = SNDRV_PCM_RATE_32000 | 46 .rates = SNDRV_PCM_RATE_32000 |
@@ -65,7 +66,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = {
65 SNDRV_PCM_INFO_MMAP_VALID | 66 SNDRV_PCM_INFO_MMAP_VALID |
66 SNDRV_PCM_INFO_INTERLEAVED | 67 SNDRV_PCM_INFO_INTERLEAVED |
67 SNDRV_PCM_INFO_PAUSE | 68 SNDRV_PCM_INFO_PAUSE |
68 SNDRV_PCM_INFO_SYNC_START, 69 SNDRV_PCM_INFO_SYNC_START |
70 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
69 .formats = SNDRV_PCM_FMTBIT_S16_LE | 71 .formats = SNDRV_PCM_FMTBIT_S16_LE |
70 SNDRV_PCM_FMTBIT_S32_LE, 72 SNDRV_PCM_FMTBIT_S32_LE,
71 .rates = SNDRV_PCM_RATE_32000 | 73 .rates = SNDRV_PCM_RATE_32000 |
@@ -91,7 +93,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = {
91 SNDRV_PCM_INFO_MMAP_VALID | 93 SNDRV_PCM_INFO_MMAP_VALID |
92 SNDRV_PCM_INFO_INTERLEAVED | 94 SNDRV_PCM_INFO_INTERLEAVED |
93 SNDRV_PCM_INFO_PAUSE | 95 SNDRV_PCM_INFO_PAUSE |
94 SNDRV_PCM_INFO_SYNC_START, 96 SNDRV_PCM_INFO_SYNC_START |
97 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
95 .formats = SNDRV_PCM_FMTBIT_S16_LE, 98 .formats = SNDRV_PCM_FMTBIT_S16_LE,
96 .rates = SNDRV_PCM_RATE_48000, 99 .rates = SNDRV_PCM_RATE_48000,
97 .rate_min = 48000, 100 .rate_min = 48000,
@@ -140,7 +143,7 @@ static int oxygen_open(struct snd_pcm_substream *substream,
140 runtime->hw.rate_min = 44100; 143 runtime->hw.rate_min = 44100;
141 break; 144 break;
142 case PCM_MULTICH: 145 case PCM_MULTICH:
143 runtime->hw.channels_max = chip->model.dac_channels; 146 runtime->hw.channels_max = chip->model.dac_channels_pcm;
144 break; 147 break;
145 } 148 }
146 if (chip->model.pcm_hardware_filter) 149 if (chip->model.pcm_hardware_filter)
@@ -271,17 +274,6 @@ static unsigned int oxygen_rate(struct snd_pcm_hw_params *hw_params)
271 } 274 }
272} 275}
273 276
274unsigned int oxygen_default_i2s_mclk(struct oxygen *chip,
275 unsigned int channel,
276 struct snd_pcm_hw_params *hw_params)
277{
278 if (params_rate(hw_params) <= 96000)
279 return OXYGEN_I2S_MCLK_256;
280 else
281 return OXYGEN_I2S_MCLK_128;
282}
283EXPORT_SYMBOL(oxygen_default_i2s_mclk);
284
285static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params) 277static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params)
286{ 278{
287 if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE) 279 if (params_format(hw_params) == SNDRV_PCM_FORMAT_S32_LE)
@@ -341,6 +333,26 @@ static int oxygen_hw_params(struct snd_pcm_substream *substream,
341 return 0; 333 return 0;
342} 334}
343 335
336static u16 get_mclk(struct oxygen *chip, unsigned int channel,
337 struct snd_pcm_hw_params *params)
338{
339 unsigned int mclks, shift;
340
341 if (channel == PCM_MULTICH)
342 mclks = chip->model.dac_mclks;
343 else
344 mclks = chip->model.adc_mclks;
345
346 if (params_rate(params) <= 48000)
347 shift = 0;
348 else if (params_rate(params) <= 96000)
349 shift = 2;
350 else
351 shift = 4;
352
353 return OXYGEN_I2S_MCLK(mclks >> shift);
354}
355
344static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, 356static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
345 struct snd_pcm_hw_params *hw_params) 357 struct snd_pcm_hw_params *hw_params)
346{ 358{
@@ -357,8 +369,8 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream,
357 OXYGEN_REC_FORMAT_A_MASK); 369 OXYGEN_REC_FORMAT_A_MASK);
358 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, 370 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT,
359 oxygen_rate(hw_params) | 371 oxygen_rate(hw_params) |
360 chip->model.get_i2s_mclk(chip, PCM_A, hw_params) |
361 chip->model.adc_i2s_format | 372 chip->model.adc_i2s_format |
373 get_mclk(chip, PCM_A, hw_params) |
362 oxygen_i2s_bits(hw_params), 374 oxygen_i2s_bits(hw_params),
363 OXYGEN_I2S_RATE_MASK | 375 OXYGEN_I2S_RATE_MASK |
364 OXYGEN_I2S_FORMAT_MASK | 376 OXYGEN_I2S_FORMAT_MASK |
@@ -393,9 +405,8 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream,
393 if (!is_ac97) 405 if (!is_ac97)
394 oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, 406 oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT,
395 oxygen_rate(hw_params) | 407 oxygen_rate(hw_params) |
396 chip->model.get_i2s_mclk(chip, PCM_B,
397 hw_params) |
398 chip->model.adc_i2s_format | 408 chip->model.adc_i2s_format |
409 get_mclk(chip, PCM_B, hw_params) |
399 oxygen_i2s_bits(hw_params), 410 oxygen_i2s_bits(hw_params),
400 OXYGEN_I2S_RATE_MASK | 411 OXYGEN_I2S_RATE_MASK |
401 OXYGEN_I2S_FORMAT_MASK | 412 OXYGEN_I2S_FORMAT_MASK |
@@ -476,8 +487,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream,
476 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, 487 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
477 oxygen_rate(hw_params) | 488 oxygen_rate(hw_params) |
478 chip->model.dac_i2s_format | 489 chip->model.dac_i2s_format |
479 chip->model.get_i2s_mclk(chip, PCM_MULTICH, 490 get_mclk(chip, PCM_MULTICH, hw_params) |
480 hw_params) |
481 oxygen_i2s_bits(hw_params), 491 oxygen_i2s_bits(hw_params),
482 OXYGEN_I2S_RATE_MASK | 492 OXYGEN_I2S_RATE_MASK |
483 OXYGEN_I2S_FORMAT_MASK | 493 OXYGEN_I2S_FORMAT_MASK |
@@ -530,7 +540,10 @@ static int oxygen_prepare(struct snd_pcm_substream *substream)
530 oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); 540 oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
531 oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); 541 oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask);
532 542
533 chip->interrupt_mask |= channel_mask; 543 if (substream->runtime->no_period_wakeup)
544 chip->interrupt_mask &= ~channel_mask;
545 else
546 chip->interrupt_mask |= channel_mask;
534 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); 547 oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask);
535 spin_unlock_irq(&chip->reg_lock); 548 spin_unlock_irq(&chip->reg_lock);
536 return 0; 549 return 0;
diff --git a/sound/pci/oxygen/oxygen_regs.h b/sound/pci/oxygen/oxygen_regs.h
index 4dcd41b78258..63dc7a0ab555 100644
--- a/sound/pci/oxygen/oxygen_regs.h
+++ b/sound/pci/oxygen/oxygen_regs.h
@@ -139,9 +139,11 @@
139#define OXYGEN_I2S_FORMAT_I2S 0x0000 139#define OXYGEN_I2S_FORMAT_I2S 0x0000
140#define OXYGEN_I2S_FORMAT_LJUST 0x0008 140#define OXYGEN_I2S_FORMAT_LJUST 0x0008
141#define OXYGEN_I2S_MCLK_MASK 0x0030 /* MCLK/LRCK */ 141#define OXYGEN_I2S_MCLK_MASK 0x0030 /* MCLK/LRCK */
142#define OXYGEN_I2S_MCLK_128 0x0000 142#define OXYGEN_I2S_MCLK_SHIFT 4
143#define OXYGEN_I2S_MCLK_256 0x0010 143#define MCLK_128 0
144#define OXYGEN_I2S_MCLK_512 0x0020 144#define MCLK_256 1
145#define MCLK_512 2
146#define OXYGEN_I2S_MCLK(f) (((f) & 3) << OXYGEN_I2S_MCLK_SHIFT)
145#define OXYGEN_I2S_BITS_MASK 0x00c0 147#define OXYGEN_I2S_BITS_MASK 0x00c0
146#define OXYGEN_I2S_BITS_16 0x0000 148#define OXYGEN_I2S_BITS_16 0x0000
147#define OXYGEN_I2S_BITS_20 0x0040 149#define OXYGEN_I2S_BITS_20 0x0040
@@ -238,11 +240,11 @@
238#define OXYGEN_SPI_DATA_LENGTH_MASK 0x02 240#define OXYGEN_SPI_DATA_LENGTH_MASK 0x02
239#define OXYGEN_SPI_DATA_LENGTH_2 0x00 241#define OXYGEN_SPI_DATA_LENGTH_2 0x00
240#define OXYGEN_SPI_DATA_LENGTH_3 0x02 242#define OXYGEN_SPI_DATA_LENGTH_3 0x02
241#define OXYGEN_SPI_CLOCK_MASK 0xc0 243#define OXYGEN_SPI_CLOCK_MASK 0x0c
242#define OXYGEN_SPI_CLOCK_160 0x00 /* ns */ 244#define OXYGEN_SPI_CLOCK_160 0x00 /* ns */
243#define OXYGEN_SPI_CLOCK_320 0x40 245#define OXYGEN_SPI_CLOCK_320 0x04
244#define OXYGEN_SPI_CLOCK_640 0x80 246#define OXYGEN_SPI_CLOCK_640 0x08
245#define OXYGEN_SPI_CLOCK_1280 0xc0 247#define OXYGEN_SPI_CLOCK_1280 0x0c
246#define OXYGEN_SPI_CODEC_MASK 0x70 /* 0..5 */ 248#define OXYGEN_SPI_CODEC_MASK 0x70 /* 0..5 */
247#define OXYGEN_SPI_CODEC_SHIFT 4 249#define OXYGEN_SPI_CODEC_SHIFT 4
248#define OXYGEN_SPI_CEN_MASK 0x80 250#define OXYGEN_SPI_CEN_MASK 0x80
diff --git a/sound/pci/oxygen/xonar.h b/sound/pci/oxygen/xonar.h
index b35343b0a9a5..0434c207e811 100644
--- a/sound/pci/oxygen/xonar.h
+++ b/sound/pci/oxygen/xonar.h
@@ -24,6 +24,8 @@ void xonar_init_ext_power(struct oxygen *chip);
24void xonar_init_cs53x1(struct oxygen *chip); 24void xonar_init_cs53x1(struct oxygen *chip);
25void xonar_set_cs53x1_params(struct oxygen *chip, 25void xonar_set_cs53x1_params(struct oxygen *chip,
26 struct snd_pcm_hw_params *params); 26 struct snd_pcm_hw_params *params);
27
28#define XONAR_GPIO_BIT_INVERT (1 << 16)
27int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl, 29int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
28 struct snd_ctl_elem_value *value); 30 struct snd_ctl_elem_value *value);
29int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl, 31int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c
index aa27c31049af..9f72d424969c 100644
--- a/sound/pci/oxygen/xonar_cs43xx.c
+++ b/sound/pci/oxygen/xonar_cs43xx.c
@@ -22,29 +22,28 @@
22 * 22 *
23 * CMI8788: 23 * CMI8788:
24 * 24 *
25 * I²C <-> CS4398 (front) 25 * I²C <-> CS4398 (addr 1001111) (front)
26 * <-> CS4362A (surround, center/LFE, back) 26 * <-> CS4362A (addr 0011000) (surround, center/LFE, back)
27 * 27 *
28 * GPI 0 <- external power present (DX only) 28 * GPI 0 <- external power present (DX only)
29 * 29 *
30 * GPIO 0 -> enable output to speakers 30 * GPIO 0 -> enable output to speakers
31 * GPIO 1 -> enable front panel I/O 31 * GPIO 1 -> route output to front panel
32 * GPIO 2 -> M0 of CS5361 32 * GPIO 2 -> M0 of CS5361
33 * GPIO 3 -> M1 of CS5361 33 * GPIO 3 -> M1 of CS5361
34 * GPIO 8 -> route input jack to line-in (0) or mic-in (1) 34 * GPIO 6 -> ?
35 * GPIO 7 -> ?
36 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
35 * 37 *
36 * CS4398: 38 * CM9780:
37 *
38 * AD0 <- 1
39 * AD1 <- 1
40 * 39 *
41 * CS4362A: 40 * LINE_OUT -> input of ADC
42 * 41 *
43 * AD0 <- 0 42 * AUX_IN <- aux
43 * MIC_IN <- mic
44 * FMIC_IN <- front mic
44 * 45 *
45 * CM9780: 46 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
46 *
47 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input
48 */ 47 */
49 48
50#include <linux/pci.h> 49#include <linux/pci.h>
@@ -63,6 +62,7 @@
63#define GPI_EXT_POWER 0x01 62#define GPI_EXT_POWER 0x01
64#define GPIO_D1_OUTPUT_ENABLE 0x0001 63#define GPIO_D1_OUTPUT_ENABLE 0x0001
65#define GPIO_D1_FRONT_PANEL 0x0002 64#define GPIO_D1_FRONT_PANEL 0x0002
65#define GPIO_D1_MAGIC 0x00c0
66#define GPIO_D1_INPUT_ROUTE 0x0100 66#define GPIO_D1_INPUT_ROUTE 0x0100
67 67
68#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */ 68#define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */
@@ -169,12 +169,12 @@ static void xonar_d1_init(struct oxygen *chip)
169 cs43xx_registers_init(chip); 169 cs43xx_registers_init(chip);
170 170
171 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 171 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
172 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); 172 GPIO_D1_FRONT_PANEL |
173 GPIO_D1_MAGIC |
174 GPIO_D1_INPUT_ROUTE);
173 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, 175 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
174 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); 176 GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE);
175 177
176 oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC);
177
178 xonar_init_cs53x1(chip); 178 xonar_init_cs53x1(chip);
179 xonar_enable_output(chip); 179 xonar_enable_output(chip);
180 180
@@ -284,7 +284,7 @@ static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed)
284 284
285static const struct snd_kcontrol_new front_panel_switch = { 285static const struct snd_kcontrol_new front_panel_switch = {
286 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 286 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
287 .name = "Front Panel Switch", 287 .name = "Front Panel Playback Switch",
288 .info = snd_ctl_boolean_mono_info, 288 .info = snd_ctl_boolean_mono_info,
289 .get = xonar_gpio_bit_switch_get, 289 .get = xonar_gpio_bit_switch_get,
290 .put = xonar_gpio_bit_switch_put, 290 .put = xonar_gpio_bit_switch_put,
@@ -298,13 +298,7 @@ static int rolloff_info(struct snd_kcontrol *ctl,
298 "Fast Roll-off", "Slow Roll-off" 298 "Fast Roll-off", "Slow Roll-off"
299 }; 299 };
300 300
301 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 301 return snd_ctl_enum_info(info, 1, 2, names);
302 info->count = 1;
303 info->value.enumerated.items = 2;
304 if (info->value.enumerated.item >= 2)
305 info->value.enumerated.item = 1;
306 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
307 return 0;
308} 302}
309 303
310static int rolloff_get(struct snd_kcontrol *ctl, 304static int rolloff_get(struct snd_kcontrol *ctl,
@@ -380,6 +374,30 @@ static int xonar_d1_mixer_init(struct oxygen *chip)
380 return 0; 374 return 0;
381} 375}
382 376
377static void dump_cs4362a_registers(struct xonar_cs43xx *data,
378 struct snd_info_buffer *buffer)
379{
380 unsigned int i;
381
382 snd_iprintf(buffer, "\nCS4362A:");
383 for (i = 1; i <= 14; ++i)
384 snd_iprintf(buffer, " %02x", data->cs4362a_regs[i]);
385 snd_iprintf(buffer, "\n");
386}
387
388static void dump_d1_registers(struct oxygen *chip,
389 struct snd_info_buffer *buffer)
390{
391 struct xonar_cs43xx *data = chip->model_data;
392 unsigned int i;
393
394 snd_iprintf(buffer, "\nCS4398: 7?");
395 for (i = 2; i <= 8; ++i)
396 snd_iprintf(buffer, " %02x", data->cs4398_regs[i]);
397 snd_iprintf(buffer, "\n");
398 dump_cs4362a_registers(data, buffer);
399}
400
383static const struct oxygen_model model_xonar_d1 = { 401static const struct oxygen_model model_xonar_d1 = {
384 .longname = "Asus Virtuoso 100", 402 .longname = "Asus Virtuoso 100",
385 .chip = "AV200", 403 .chip = "AV200",
@@ -388,22 +406,26 @@ static const struct oxygen_model model_xonar_d1 = {
388 .cleanup = xonar_d1_cleanup, 406 .cleanup = xonar_d1_cleanup,
389 .suspend = xonar_d1_suspend, 407 .suspend = xonar_d1_suspend,
390 .resume = xonar_d1_resume, 408 .resume = xonar_d1_resume,
391 .get_i2s_mclk = oxygen_default_i2s_mclk,
392 .set_dac_params = set_cs43xx_params, 409 .set_dac_params = set_cs43xx_params,
393 .set_adc_params = xonar_set_cs53x1_params, 410 .set_adc_params = xonar_set_cs53x1_params,
394 .update_dac_volume = update_cs43xx_volume, 411 .update_dac_volume = update_cs43xx_volume,
395 .update_dac_mute = update_cs43xx_mute, 412 .update_dac_mute = update_cs43xx_mute,
396 .update_center_lfe_mix = update_cs43xx_center_lfe_mix, 413 .update_center_lfe_mix = update_cs43xx_center_lfe_mix,
397 .ac97_switch = xonar_d1_line_mic_ac97_switch, 414 .ac97_switch = xonar_d1_line_mic_ac97_switch,
415 .dump_registers = dump_d1_registers,
398 .dac_tlv = cs4362a_db_scale, 416 .dac_tlv = cs4362a_db_scale,
399 .model_data_size = sizeof(struct xonar_cs43xx), 417 .model_data_size = sizeof(struct xonar_cs43xx),
400 .device_config = PLAYBACK_0_TO_I2S | 418 .device_config = PLAYBACK_0_TO_I2S |
401 PLAYBACK_1_TO_SPDIF | 419 PLAYBACK_1_TO_SPDIF |
402 CAPTURE_0_FROM_I2S_2, 420 CAPTURE_0_FROM_I2S_2 |
403 .dac_channels = 8, 421 AC97_FMIC_SWITCH,
422 .dac_channels_pcm = 8,
423 .dac_channels_mixer = 8,
404 .dac_volume_min = 127 - 60, 424 .dac_volume_min = 127 - 60,
405 .dac_volume_max = 127, 425 .dac_volume_max = 127,
406 .function_flags = OXYGEN_FUNCTION_2WIRE, 426 .function_flags = OXYGEN_FUNCTION_2WIRE,
427 .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
428 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
407 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 429 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
408 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 430 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
409}; 431};
diff --git a/sound/pci/oxygen/xonar_dg.c b/sound/pci/oxygen/xonar_dg.c
new file mode 100644
index 000000000000..e1fa602eba79
--- /dev/null
+++ b/sound/pci/oxygen/xonar_dg.c
@@ -0,0 +1,572 @@
1/*
2 * card driver for the Xonar DG
3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License, version 2.
9 *
10 * This driver is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this driver; if not, see <http://www.gnu.org/licenses/>.
17 */
18
19/*
20 * Xonar DG
21 * --------
22 *
23 * CMI8788:
24 *
25 * SPI 0 -> CS4245
26 *
27 * GPIO 3 <- ?
28 * GPIO 4 <- headphone detect
29 * GPIO 5 -> route input jack to line-in (0) or mic-in (1)
30 * GPIO 6 -> route input jack to line-in (0) or mic-in (1)
31 * GPIO 7 -> enable rear headphone amp
32 * GPIO 8 -> enable output to speakers
33 *
34 * CS4245:
35 *
36 * input 1 <- aux
37 * input 2 <- front mic
38 * input 4 <- line/mic
39 * aux out -> front panel headphones
40 */
41
42#include <linux/pci.h>
43#include <linux/delay.h>
44#include <sound/control.h>
45#include <sound/core.h>
46#include <sound/info.h>
47#include <sound/pcm.h>
48#include <sound/tlv.h>
49#include "oxygen.h"
50#include "xonar_dg.h"
51#include "cs4245.h"
52
53#define GPIO_MAGIC 0x0008
54#define GPIO_HP_DETECT 0x0010
55#define GPIO_INPUT_ROUTE 0x0060
56#define GPIO_HP_REAR 0x0080
57#define GPIO_OUTPUT_ENABLE 0x0100
58
59struct dg {
60 unsigned int output_sel;
61 s8 input_vol[4][2];
62 unsigned int input_sel;
63 u8 hp_vol_att;
64 u8 cs4245_regs[0x11];
65};
66
67static void cs4245_write(struct oxygen *chip, unsigned int reg, u8 value)
68{
69 struct dg *data = chip->model_data;
70
71 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
72 OXYGEN_SPI_DATA_LENGTH_3 |
73 OXYGEN_SPI_CLOCK_1280 |
74 (0 << OXYGEN_SPI_CODEC_SHIFT) |
75 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
76 CS4245_SPI_ADDRESS |
77 CS4245_SPI_WRITE |
78 (reg << 8) | value);
79 data->cs4245_regs[reg] = value;
80}
81
82static void cs4245_write_cached(struct oxygen *chip, unsigned int reg, u8 value)
83{
84 struct dg *data = chip->model_data;
85
86 if (value != data->cs4245_regs[reg])
87 cs4245_write(chip, reg, value);
88}
89
90static void cs4245_registers_init(struct oxygen *chip)
91{
92 struct dg *data = chip->model_data;
93
94 cs4245_write(chip, CS4245_POWER_CTRL, CS4245_PDN);
95 cs4245_write(chip, CS4245_DAC_CTRL_1,
96 data->cs4245_regs[CS4245_DAC_CTRL_1]);
97 cs4245_write(chip, CS4245_ADC_CTRL,
98 data->cs4245_regs[CS4245_ADC_CTRL]);
99 cs4245_write(chip, CS4245_SIGNAL_SEL,
100 data->cs4245_regs[CS4245_SIGNAL_SEL]);
101 cs4245_write(chip, CS4245_PGA_B_CTRL,
102 data->cs4245_regs[CS4245_PGA_B_CTRL]);
103 cs4245_write(chip, CS4245_PGA_A_CTRL,
104 data->cs4245_regs[CS4245_PGA_A_CTRL]);
105 cs4245_write(chip, CS4245_ANALOG_IN,
106 data->cs4245_regs[CS4245_ANALOG_IN]);
107 cs4245_write(chip, CS4245_DAC_A_CTRL,
108 data->cs4245_regs[CS4245_DAC_A_CTRL]);
109 cs4245_write(chip, CS4245_DAC_B_CTRL,
110 data->cs4245_regs[CS4245_DAC_B_CTRL]);
111 cs4245_write(chip, CS4245_DAC_CTRL_2,
112 CS4245_DAC_SOFT | CS4245_DAC_ZERO | CS4245_INVERT_DAC);
113 cs4245_write(chip, CS4245_INT_MASK, 0);
114 cs4245_write(chip, CS4245_POWER_CTRL, 0);
115}
116
117static void cs4245_init(struct oxygen *chip)
118{
119 struct dg *data = chip->model_data;
120
121 data->cs4245_regs[CS4245_DAC_CTRL_1] =
122 CS4245_DAC_FM_SINGLE | CS4245_DAC_DIF_LJUST;
123 data->cs4245_regs[CS4245_ADC_CTRL] =
124 CS4245_ADC_FM_SINGLE | CS4245_ADC_DIF_LJUST;
125 data->cs4245_regs[CS4245_SIGNAL_SEL] =
126 CS4245_A_OUT_SEL_HIZ | CS4245_ASYNCH;
127 data->cs4245_regs[CS4245_PGA_B_CTRL] = 0;
128 data->cs4245_regs[CS4245_PGA_A_CTRL] = 0;
129 data->cs4245_regs[CS4245_ANALOG_IN] =
130 CS4245_PGA_SOFT | CS4245_PGA_ZERO | CS4245_SEL_INPUT_4;
131 data->cs4245_regs[CS4245_DAC_A_CTRL] = 0;
132 data->cs4245_regs[CS4245_DAC_B_CTRL] = 0;
133 cs4245_registers_init(chip);
134 snd_component_add(chip->card, "CS4245");
135}
136
137static void dg_output_enable(struct oxygen *chip)
138{
139 msleep(2500);
140 oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
141}
142
143static void dg_init(struct oxygen *chip)
144{
145 struct dg *data = chip->model_data;
146
147 data->output_sel = 0;
148 data->input_sel = 3;
149 data->hp_vol_att = 2 * 16;
150
151 cs4245_init(chip);
152
153 oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
154 GPIO_MAGIC | GPIO_HP_DETECT);
155 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
156 GPIO_INPUT_ROUTE | GPIO_HP_REAR | GPIO_OUTPUT_ENABLE);
157 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
158 GPIO_INPUT_ROUTE | GPIO_HP_REAR);
159 dg_output_enable(chip);
160}
161
162static void dg_cleanup(struct oxygen *chip)
163{
164 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
165}
166
167static void dg_suspend(struct oxygen *chip)
168{
169 dg_cleanup(chip);
170}
171
172static void dg_resume(struct oxygen *chip)
173{
174 cs4245_registers_init(chip);
175 dg_output_enable(chip);
176}
177
178static void set_cs4245_dac_params(struct oxygen *chip,
179 struct snd_pcm_hw_params *params)
180{
181 struct dg *data = chip->model_data;
182 u8 value;
183
184 value = data->cs4245_regs[CS4245_DAC_CTRL_1] & ~CS4245_DAC_FM_MASK;
185 if (params_rate(params) <= 50000)
186 value |= CS4245_DAC_FM_SINGLE;
187 else if (params_rate(params) <= 100000)
188 value |= CS4245_DAC_FM_DOUBLE;
189 else
190 value |= CS4245_DAC_FM_QUAD;
191 cs4245_write_cached(chip, CS4245_DAC_CTRL_1, value);
192}
193
194static void set_cs4245_adc_params(struct oxygen *chip,
195 struct snd_pcm_hw_params *params)
196{
197 struct dg *data = chip->model_data;
198 u8 value;
199
200 value = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_ADC_FM_MASK;
201 if (params_rate(params) <= 50000)
202 value |= CS4245_ADC_FM_SINGLE;
203 else if (params_rate(params) <= 100000)
204 value |= CS4245_ADC_FM_DOUBLE;
205 else
206 value |= CS4245_ADC_FM_QUAD;
207 cs4245_write_cached(chip, CS4245_ADC_CTRL, value);
208}
209
210static int output_switch_info(struct snd_kcontrol *ctl,
211 struct snd_ctl_elem_info *info)
212{
213 static const char *const names[3] = {
214 "Speakers", "Headphones", "FP Headphones"
215 };
216
217 return snd_ctl_enum_info(info, 1, 3, names);
218}
219
220static int output_switch_get(struct snd_kcontrol *ctl,
221 struct snd_ctl_elem_value *value)
222{
223 struct oxygen *chip = ctl->private_data;
224 struct dg *data = chip->model_data;
225
226 mutex_lock(&chip->mutex);
227 value->value.enumerated.item[0] = data->output_sel;
228 mutex_unlock(&chip->mutex);
229 return 0;
230}
231
232static int output_switch_put(struct snd_kcontrol *ctl,
233 struct snd_ctl_elem_value *value)
234{
235 struct oxygen *chip = ctl->private_data;
236 struct dg *data = chip->model_data;
237 u8 reg;
238 int changed;
239
240 if (value->value.enumerated.item[0] > 2)
241 return -EINVAL;
242
243 mutex_lock(&chip->mutex);
244 changed = value->value.enumerated.item[0] != data->output_sel;
245 if (changed) {
246 data->output_sel = value->value.enumerated.item[0];
247
248 reg = data->cs4245_regs[CS4245_SIGNAL_SEL] &
249 ~CS4245_A_OUT_SEL_MASK;
250 reg |= data->output_sel == 2 ?
251 CS4245_A_OUT_SEL_DAC : CS4245_A_OUT_SEL_HIZ;
252 cs4245_write_cached(chip, CS4245_SIGNAL_SEL, reg);
253
254 cs4245_write_cached(chip, CS4245_DAC_A_CTRL,
255 data->output_sel ? data->hp_vol_att : 0);
256 cs4245_write_cached(chip, CS4245_DAC_B_CTRL,
257 data->output_sel ? data->hp_vol_att : 0);
258
259 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
260 data->output_sel == 1 ? GPIO_HP_REAR : 0,
261 GPIO_HP_REAR);
262 }
263 mutex_unlock(&chip->mutex);
264 return changed;
265}
266
267static int hp_volume_offset_info(struct snd_kcontrol *ctl,
268 struct snd_ctl_elem_info *info)
269{
270 static const char *const names[3] = {
271 "< 64 ohms", "64-150 ohms", "150-300 ohms"
272 };
273
274 return snd_ctl_enum_info(info, 1, 3, names);
275}
276
277static int hp_volume_offset_get(struct snd_kcontrol *ctl,
278 struct snd_ctl_elem_value *value)
279{
280 struct oxygen *chip = ctl->private_data;
281 struct dg *data = chip->model_data;
282
283 mutex_lock(&chip->mutex);
284 if (data->hp_vol_att > 2 * 7)
285 value->value.enumerated.item[0] = 0;
286 else if (data->hp_vol_att > 0)
287 value->value.enumerated.item[0] = 1;
288 else
289 value->value.enumerated.item[0] = 2;
290 mutex_unlock(&chip->mutex);
291 return 0;
292}
293
294static int hp_volume_offset_put(struct snd_kcontrol *ctl,
295 struct snd_ctl_elem_value *value)
296{
297 static const s8 atts[3] = { 2 * 16, 2 * 7, 0 };
298 struct oxygen *chip = ctl->private_data;
299 struct dg *data = chip->model_data;
300 s8 att;
301 int changed;
302
303 if (value->value.enumerated.item[0] > 2)
304 return -EINVAL;
305 att = atts[value->value.enumerated.item[0]];
306 mutex_lock(&chip->mutex);
307 changed = att != data->hp_vol_att;
308 if (changed) {
309 data->hp_vol_att = att;
310 if (data->output_sel) {
311 cs4245_write_cached(chip, CS4245_DAC_A_CTRL, att);
312 cs4245_write_cached(chip, CS4245_DAC_B_CTRL, att);
313 }
314 }
315 mutex_unlock(&chip->mutex);
316 return changed;
317}
318
319static int input_vol_info(struct snd_kcontrol *ctl,
320 struct snd_ctl_elem_info *info)
321{
322 info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
323 info->count = 2;
324 info->value.integer.min = 2 * -12;
325 info->value.integer.max = 2 * 12;
326 return 0;
327}
328
329static int input_vol_get(struct snd_kcontrol *ctl,
330 struct snd_ctl_elem_value *value)
331{
332 struct oxygen *chip = ctl->private_data;
333 struct dg *data = chip->model_data;
334 unsigned int idx = ctl->private_value;
335
336 mutex_lock(&chip->mutex);
337 value->value.integer.value[0] = data->input_vol[idx][0];
338 value->value.integer.value[1] = data->input_vol[idx][1];
339 mutex_unlock(&chip->mutex);
340 return 0;
341}
342
343static int input_vol_put(struct snd_kcontrol *ctl,
344 struct snd_ctl_elem_value *value)
345{
346 struct oxygen *chip = ctl->private_data;
347 struct dg *data = chip->model_data;
348 unsigned int idx = ctl->private_value;
349 int changed = 0;
350
351 if (value->value.integer.value[0] < 2 * -12 ||
352 value->value.integer.value[0] > 2 * 12 ||
353 value->value.integer.value[1] < 2 * -12 ||
354 value->value.integer.value[1] > 2 * 12)
355 return -EINVAL;
356 mutex_lock(&chip->mutex);
357 changed = data->input_vol[idx][0] != value->value.integer.value[0] ||
358 data->input_vol[idx][1] != value->value.integer.value[1];
359 if (changed) {
360 data->input_vol[idx][0] = value->value.integer.value[0];
361 data->input_vol[idx][1] = value->value.integer.value[1];
362 if (idx == data->input_sel) {
363 cs4245_write_cached(chip, CS4245_PGA_A_CTRL,
364 data->input_vol[idx][0]);
365 cs4245_write_cached(chip, CS4245_PGA_B_CTRL,
366 data->input_vol[idx][1]);
367 }
368 }
369 mutex_unlock(&chip->mutex);
370 return changed;
371}
372
373static DECLARE_TLV_DB_SCALE(cs4245_pga_db_scale, -1200, 50, 0);
374
375static int input_sel_info(struct snd_kcontrol *ctl,
376 struct snd_ctl_elem_info *info)
377{
378 static const char *const names[4] = {
379 "Mic", "Aux", "Front Mic", "Line"
380 };
381
382 return snd_ctl_enum_info(info, 1, 4, names);
383}
384
385static int input_sel_get(struct snd_kcontrol *ctl,
386 struct snd_ctl_elem_value *value)
387{
388 struct oxygen *chip = ctl->private_data;
389 struct dg *data = chip->model_data;
390
391 mutex_lock(&chip->mutex);
392 value->value.enumerated.item[0] = data->input_sel;
393 mutex_unlock(&chip->mutex);
394 return 0;
395}
396
397static int input_sel_put(struct snd_kcontrol *ctl,
398 struct snd_ctl_elem_value *value)
399{
400 static const u8 sel_values[4] = {
401 CS4245_SEL_MIC,
402 CS4245_SEL_INPUT_1,
403 CS4245_SEL_INPUT_2,
404 CS4245_SEL_INPUT_4
405 };
406 struct oxygen *chip = ctl->private_data;
407 struct dg *data = chip->model_data;
408 int changed;
409
410 if (value->value.enumerated.item[0] > 3)
411 return -EINVAL;
412
413 mutex_lock(&chip->mutex);
414 changed = value->value.enumerated.item[0] != data->input_sel;
415 if (changed) {
416 data->input_sel = value->value.enumerated.item[0];
417
418 cs4245_write(chip, CS4245_ANALOG_IN,
419 (data->cs4245_regs[CS4245_ANALOG_IN] &
420 ~CS4245_SEL_MASK) |
421 sel_values[data->input_sel]);
422
423 cs4245_write_cached(chip, CS4245_PGA_A_CTRL,
424 data->input_vol[data->input_sel][0]);
425 cs4245_write_cached(chip, CS4245_PGA_B_CTRL,
426 data->input_vol[data->input_sel][1]);
427
428 oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
429 data->input_sel ? 0 : GPIO_INPUT_ROUTE,
430 GPIO_INPUT_ROUTE);
431 }
432 mutex_unlock(&chip->mutex);
433 return changed;
434}
435
436static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
437{
438 static const char *const names[2] = { "Active", "Frozen" };
439
440 return snd_ctl_enum_info(info, 1, 2, names);
441}
442
443static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
444{
445 struct oxygen *chip = ctl->private_data;
446 struct dg *data = chip->model_data;
447
448 value->value.enumerated.item[0] =
449 !!(data->cs4245_regs[CS4245_ADC_CTRL] & CS4245_HPF_FREEZE);
450 return 0;
451}
452
453static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
454{
455 struct oxygen *chip = ctl->private_data;
456 struct dg *data = chip->model_data;
457 u8 reg;
458 int changed;
459
460 mutex_lock(&chip->mutex);
461 reg = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_HPF_FREEZE;
462 if (value->value.enumerated.item[0])
463 reg |= CS4245_HPF_FREEZE;
464 changed = reg != data->cs4245_regs[CS4245_ADC_CTRL];
465 if (changed)
466 cs4245_write(chip, CS4245_ADC_CTRL, reg);
467 mutex_unlock(&chip->mutex);
468 return changed;
469}
470
471#define INPUT_VOLUME(xname, index) { \
472 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
473 .name = xname, \
474 .info = input_vol_info, \
475 .get = input_vol_get, \
476 .put = input_vol_put, \
477 .tlv = { .p = cs4245_pga_db_scale }, \
478 .private_value = index, \
479}
480static const struct snd_kcontrol_new dg_controls[] = {
481 {
482 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
483 .name = "Analog Output Playback Enum",
484 .info = output_switch_info,
485 .get = output_switch_get,
486 .put = output_switch_put,
487 },
488 {
489 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
490 .name = "Headphones Impedance Playback Enum",
491 .info = hp_volume_offset_info,
492 .get = hp_volume_offset_get,
493 .put = hp_volume_offset_put,
494 },
495 INPUT_VOLUME("Mic Capture Volume", 0),
496 INPUT_VOLUME("Aux Capture Volume", 1),
497 INPUT_VOLUME("Front Mic Capture Volume", 2),
498 INPUT_VOLUME("Line Capture Volume", 3),
499 {
500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
501 .name = "Capture Source",
502 .info = input_sel_info,
503 .get = input_sel_get,
504 .put = input_sel_put,
505 },
506 {
507 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
508 .name = "ADC High-pass Filter Capture Enum",
509 .info = hpf_info,
510 .get = hpf_get,
511 .put = hpf_put,
512 },
513};
514
515static int dg_control_filter(struct snd_kcontrol_new *template)
516{
517 if (!strncmp(template->name, "Master Playback ", 16))
518 return 1;
519 return 0;
520}
521
522static int dg_mixer_init(struct oxygen *chip)
523{
524 unsigned int i;
525 int err;
526
527 for (i = 0; i < ARRAY_SIZE(dg_controls); ++i) {
528 err = snd_ctl_add(chip->card,
529 snd_ctl_new1(&dg_controls[i], chip));
530 if (err < 0)
531 return err;
532 }
533 return 0;
534}
535
536static void dump_cs4245_registers(struct oxygen *chip,
537 struct snd_info_buffer *buffer)
538{
539 struct dg *data = chip->model_data;
540 unsigned int i;
541
542 snd_iprintf(buffer, "\nCS4245:");
543 for (i = 1; i <= 0x10; ++i)
544 snd_iprintf(buffer, " %02x", data->cs4245_regs[i]);
545 snd_iprintf(buffer, "\n");
546}
547
548struct oxygen_model model_xonar_dg = {
549 .shortname = "Xonar DG",
550 .longname = "C-Media Oxygen HD Audio",
551 .chip = "CMI8786",
552 .init = dg_init,
553 .control_filter = dg_control_filter,
554 .mixer_init = dg_mixer_init,
555 .cleanup = dg_cleanup,
556 .suspend = dg_suspend,
557 .resume = dg_resume,
558 .set_dac_params = set_cs4245_dac_params,
559 .set_adc_params = set_cs4245_adc_params,
560 .dump_registers = dump_cs4245_registers,
561 .model_data_size = sizeof(struct dg),
562 .device_config = PLAYBACK_0_TO_I2S |
563 PLAYBACK_1_TO_SPDIF |
564 CAPTURE_0_FROM_I2S_2,
565 .dac_channels_pcm = 6,
566 .dac_channels_mixer = 0,
567 .function_flags = OXYGEN_FUNCTION_SPI,
568 .dac_mclks = OXYGEN_MCLKS(256, 128, 128),
569 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
570 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
571 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
572};
diff --git a/sound/pci/oxygen/xonar_dg.h b/sound/pci/oxygen/xonar_dg.h
new file mode 100644
index 000000000000..5688d78609a9
--- /dev/null
+++ b/sound/pci/oxygen/xonar_dg.h
@@ -0,0 +1,8 @@
1#ifndef XONAR_DG_H_INCLUDED
2#define XONAR_DG_H_INCLUDED
3
4#include "oxygen.h"
5
6extern struct oxygen_model model_xonar_dg;
7
8#endif
diff --git a/sound/pci/oxygen/xonar_hdmi.c b/sound/pci/oxygen/xonar_hdmi.c
index b12db1f1cea9..136dac6a3964 100644
--- a/sound/pci/oxygen/xonar_hdmi.c
+++ b/sound/pci/oxygen/xonar_hdmi.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * helper functions for HDMI models (Xonar HDAV1.3) 2 * helper functions for HDMI models (Xonar HDAV1.3/HDAV1.3 Slim)
3 * 3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * 5 *
diff --git a/sound/pci/oxygen/xonar_lib.c b/sound/pci/oxygen/xonar_lib.c
index b3ff71316653..0ebe7f5916f9 100644
--- a/sound/pci/oxygen/xonar_lib.c
+++ b/sound/pci/oxygen/xonar_lib.c
@@ -104,9 +104,10 @@ int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl,
104{ 104{
105 struct oxygen *chip = ctl->private_data; 105 struct oxygen *chip = ctl->private_data;
106 u16 bit = ctl->private_value; 106 u16 bit = ctl->private_value;
107 bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
107 108
108 value->value.integer.value[0] = 109 value->value.integer.value[0] =
109 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit); 110 !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit) ^ invert;
110 return 0; 111 return 0;
111} 112}
112 113
@@ -115,12 +116,13 @@ int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl,
115{ 116{
116 struct oxygen *chip = ctl->private_data; 117 struct oxygen *chip = ctl->private_data;
117 u16 bit = ctl->private_value; 118 u16 bit = ctl->private_value;
119 bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT;
118 u16 old_bits, new_bits; 120 u16 old_bits, new_bits;
119 int changed; 121 int changed;
120 122
121 spin_lock_irq(&chip->reg_lock); 123 spin_lock_irq(&chip->reg_lock);
122 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); 124 old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA);
123 if (value->value.integer.value[0]) 125 if (!!value->value.integer.value[0] ^ invert)
124 new_bits = old_bits | bit; 126 new_bits = old_bits | bit;
125 else 127 else
126 new_bits = old_bits & ~bit; 128 new_bits = old_bits & ~bit;
diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c
index d491fd6c0be2..54cad38ec30a 100644
--- a/sound/pci/oxygen/xonar_pcm179x.c
+++ b/sound/pci/oxygen/xonar_pcm179x.c
@@ -22,20 +22,26 @@
22 * 22 *
23 * CMI8788: 23 * CMI8788:
24 * 24 *
25 * SPI 0 -> 1st PCM1796 (front) 25 * SPI 0 -> 1st PCM1796 (front)
26 * SPI 1 -> 2nd PCM1796 (surround) 26 * SPI 1 -> 2nd PCM1796 (surround)
27 * SPI 2 -> 3rd PCM1796 (center/LFE) 27 * SPI 2 -> 3rd PCM1796 (center/LFE)
28 * SPI 4 -> 4th PCM1796 (back) 28 * SPI 4 -> 4th PCM1796 (back)
29 * 29 *
30 * GPIO 2 -> M0 of CS5381 30 * GPIO 2 -> M0 of CS5381
31 * GPIO 3 -> M1 of CS5381 31 * GPIO 3 -> M1 of CS5381
32 * GPIO 5 <- external power present (D2X only) 32 * GPIO 5 <- external power present (D2X only)
33 * GPIO 7 -> ALT 33 * GPIO 7 -> ALT
34 * GPIO 8 -> enable output to speakers 34 * GPIO 8 -> enable output to speakers
35 * 35 *
36 * CM9780: 36 * CM9780:
37 * 37 *
38 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input 38 * LINE_OUT -> input of ADC
39 *
40 * AUX_IN <- aux
41 * VIDEO_IN <- CD
42 * FMIC_IN <- mic
43 *
44 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
39 */ 45 */
40 46
41/* 47/*
@@ -44,52 +50,53 @@
44 * 50 *
45 * CMI8788: 51 * CMI8788:
46 * 52 *
47 * I²C <-> PCM1796 (front) 53 * I²C <-> PCM1796 (addr 1001100) (front)
48 * 54 *
49 * GPI 0 <- external power present 55 * GPI 0 <- external power present
50 * 56 *
51 * GPIO 0 -> enable output to speakers 57 * GPIO 0 -> enable HDMI (0) or speaker (1) output
52 * GPIO 2 -> M0 of CS5381 58 * GPIO 2 -> M0 of CS5381
53 * GPIO 3 -> M1 of CS5381 59 * GPIO 3 -> M1 of CS5381
54 * GPIO 8 -> route input jack to line-in (0) or mic-in (1) 60 * GPIO 4 <- daughterboard detection
61 * GPIO 5 <- daughterboard detection
62 * GPIO 6 -> ?
63 * GPIO 7 -> ?
64 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
55 * 65 *
56 * TXD -> HDMI controller 66 * UART <-> HDMI controller
57 * RXD <- HDMI controller
58 *
59 * PCM1796 front: AD1,0 <- 0,0
60 * 67 *
61 * CM9780: 68 * CM9780:
62 * 69 *
63 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input 70 * LINE_OUT -> input of ADC
71 *
72 * AUX_IN <- aux
73 * CD_IN <- CD
74 * MIC_IN <- mic
75 *
76 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
64 * 77 *
65 * no daughterboard 78 * no daughterboard
66 * ---------------- 79 * ----------------
67 * 80 *
68 * GPIO 4 <- 1 81 * GPIO 4 <- 1
69 * 82 *
70 * H6 daughterboard 83 * H6 daughterboard
71 * ---------------- 84 * ----------------
72 * 85 *
73 * GPIO 4 <- 0 86 * GPIO 4 <- 0
74 * GPIO 5 <- 0 87 * GPIO 5 <- 0
75 *
76 * I²C <-> PCM1796 (surround)
77 * <-> PCM1796 (center/LFE)
78 * <-> PCM1796 (back)
79 * 88 *
80 * PCM1796 surround: AD1,0 <- 0,1 89 * I²C <-> PCM1796 (addr 1001101) (surround)
81 * PCM1796 center/LFE: AD1,0 <- 1,0 90 * <-> PCM1796 (addr 1001110) (center/LFE)
82 * PCM1796 back: AD1,0 <- 1,1 91 * <-> PCM1796 (addr 1001111) (back)
83 * 92 *
84 * unknown daughterboard 93 * unknown daughterboard
85 * --------------------- 94 * ---------------------
86 * 95 *
87 * GPIO 4 <- 0 96 * GPIO 4 <- 0
88 * GPIO 5 <- 1 97 * GPIO 5 <- 1
89 *
90 * I²C <-> CS4362A (surround, center/LFE, back)
91 * 98 *
92 * CS4362A: AD0 <- 0 99 * I²C <-> CS4362A (addr 0011000) (surround, center/LFE, back)
93 */ 100 */
94 101
95/* 102/*
@@ -98,32 +105,35 @@
98 * 105 *
99 * CMI8788: 106 * CMI8788:
100 * 107 *
101 * I²C <-> PCM1792A 108 * I²C <-> PCM1792A (addr 1001100)
102 * <-> CS2000 (ST only) 109 * <-> CS2000 (addr 1001110) (ST only)
103 * 110 *
104 * ADC1 MCLK -> REF_CLK of CS2000 (ST only) 111 * ADC1 MCLK -> REF_CLK of CS2000 (ST only)
105 * 112 *
106 * GPI 0 <- external power present (STX only) 113 * GPI 0 <- external power present (STX only)
107 * 114 *
108 * GPIO 0 -> enable output to speakers 115 * GPIO 0 -> enable output to speakers
109 * GPIO 1 -> route HP to front panel (0) or rear jack (1) 116 * GPIO 1 -> route HP to front panel (0) or rear jack (1)
110 * GPIO 2 -> M0 of CS5381 117 * GPIO 2 -> M0 of CS5381
111 * GPIO 3 -> M1 of CS5381 118 * GPIO 3 -> M1 of CS5381
112 * GPIO 7 -> route output to speaker jacks (0) or HP (1) 119 * GPIO 4 <- daughterboard detection
113 * GPIO 8 -> route input jack to line-in (0) or mic-in (1) 120 * GPIO 5 <- daughterboard detection
121 * GPIO 6 -> ?
122 * GPIO 7 -> route output to speaker jacks (0) or HP (1)
123 * GPIO 8 -> route input jack to line-in (0) or mic-in (1)
114 * 124 *
115 * PCM1792A: 125 * PCM1792A:
116 * 126 *
117 * AD1,0 <- 0,0 127 * SCK <- CLK_OUT of CS2000 (ST only)
118 * SCK <- CLK_OUT of CS2000 (ST only)
119 * 128 *
120 * CS2000: 129 * CM9780:
121 * 130 *
122 * AD0 <- 0 131 * LINE_OUT -> input of ADC
123 * 132 *
124 * CM9780: 133 * AUX_IN <- aux
134 * MIC_IN <- mic
125 * 135 *
126 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input 136 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
127 * 137 *
128 * H6 daughterboard 138 * H6 daughterboard
129 * ---------------- 139 * ----------------
@@ -133,15 +143,39 @@
133 */ 143 */
134 144
135/* 145/*
136 * Xonar HDAV1.3 Slim 146 * Xonar Xense
137 * ------------------ 147 * -----------
138 * 148 *
139 * CMI8788: 149 * CMI8788:
140 * 150 *
141 * GPIO 1 -> enable output 151 * I²C <-> PCM1796 (addr 1001100) (front)
152 * <-> CS4362A (addr 0011000) (surround, center/LFE, back)
153 * <-> CS2000 (addr 1001110)
154 *
155 * ADC1 MCLK -> REF_CLK of CS2000
156 *
157 * GPI 0 <- external power present
158 *
159 * GPIO 0 -> enable output
160 * GPIO 1 -> route HP to front panel (0) or rear jack (1)
161 * GPIO 2 -> M0 of CS5381
162 * GPIO 3 -> M1 of CS5381
163 * GPIO 4 -> enable output
164 * GPIO 5 -> enable output
165 * GPIO 6 -> ?
166 * GPIO 7 -> route output to HP (0) or speaker (1)
167 * GPIO 8 -> route input jack to mic-in (0) or line-in (1)
142 * 168 *
143 * TXD -> HDMI controller 169 * CM9780:
144 * RXD <- HDMI controller 170 *
171 * LINE_OUT -> input of ADC
172 *
173 * AUX_IN <- aux
174 * VIDEO_IN <- ?
175 * FMIC_IN <- mic
176 *
177 * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input
178 * GPO 1 -> route mic-in from input jack (0) or front panel header (1)
145 */ 179 */
146 180
147#include <linux/pci.h> 181#include <linux/pci.h>
@@ -150,6 +184,7 @@
150#include <sound/ac97_codec.h> 184#include <sound/ac97_codec.h>
151#include <sound/control.h> 185#include <sound/control.h>
152#include <sound/core.h> 186#include <sound/core.h>
187#include <sound/info.h>
153#include <sound/pcm.h> 188#include <sound/pcm.h>
154#include <sound/pcm_params.h> 189#include <sound/pcm_params.h>
155#include <sound/tlv.h> 190#include <sound/tlv.h>
@@ -167,12 +202,14 @@
167#define GPIO_INPUT_ROUTE 0x0100 202#define GPIO_INPUT_ROUTE 0x0100
168 203
169#define GPIO_HDAV_OUTPUT_ENABLE 0x0001 204#define GPIO_HDAV_OUTPUT_ENABLE 0x0001
205#define GPIO_HDAV_MAGIC 0x00c0
170 206
171#define GPIO_DB_MASK 0x0030 207#define GPIO_DB_MASK 0x0030
172#define GPIO_DB_H6 0x0000 208#define GPIO_DB_H6 0x0000
173 209
174#define GPIO_ST_OUTPUT_ENABLE 0x0001 210#define GPIO_ST_OUTPUT_ENABLE 0x0001
175#define GPIO_ST_HP_REAR 0x0002 211#define GPIO_ST_HP_REAR 0x0002
212#define GPIO_ST_MAGIC 0x0040
176#define GPIO_ST_HP 0x0080 213#define GPIO_ST_HP 0x0080
177 214
178#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */ 215#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */
@@ -186,11 +223,12 @@ struct xonar_pcm179x {
186 unsigned int dacs; 223 unsigned int dacs;
187 u8 pcm1796_regs[4][5]; 224 u8 pcm1796_regs[4][5];
188 unsigned int current_rate; 225 unsigned int current_rate;
189 bool os_128; 226 bool h6;
190 bool hp_active; 227 bool hp_active;
191 s8 hp_gain_offset; 228 s8 hp_gain_offset;
192 bool has_cs2000; 229 bool has_cs2000;
193 u8 cs2000_fun_cfg_1; 230 u8 cs2000_regs[0x1f];
231 bool broken_i2c;
194}; 232};
195 233
196struct xonar_hdav { 234struct xonar_hdav {
@@ -249,16 +287,14 @@ static void cs2000_write(struct oxygen *chip, u8 reg, u8 value)
249 struct xonar_pcm179x *data = chip->model_data; 287 struct xonar_pcm179x *data = chip->model_data;
250 288
251 oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value); 289 oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value);
252 if (reg == CS2000_FUN_CFG_1) 290 data->cs2000_regs[reg] = value;
253 data->cs2000_fun_cfg_1 = value;
254} 291}
255 292
256static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value) 293static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value)
257{ 294{
258 struct xonar_pcm179x *data = chip->model_data; 295 struct xonar_pcm179x *data = chip->model_data;
259 296
260 if (reg != CS2000_FUN_CFG_1 || 297 if (value != data->cs2000_regs[reg])
261 value != data->cs2000_fun_cfg_1)
262 cs2000_write(chip, reg, value); 298 cs2000_write(chip, reg, value);
263} 299}
264 300
@@ -268,6 +304,7 @@ static void pcm1796_registers_init(struct oxygen *chip)
268 unsigned int i; 304 unsigned int i;
269 s8 gain_offset; 305 s8 gain_offset;
270 306
307 msleep(1);
271 gain_offset = data->hp_active ? data->hp_gain_offset : 0; 308 gain_offset = data->hp_active ? data->hp_gain_offset : 0;
272 for (i = 0; i < data->dacs; ++i) { 309 for (i = 0; i < data->dacs; ++i) {
273 /* set ATLD before ATL/ATR */ 310 /* set ATLD before ATL/ATR */
@@ -282,6 +319,7 @@ static void pcm1796_registers_init(struct oxygen *chip)
282 pcm1796_write(chip, i, 20, 319 pcm1796_write(chip, i, 20,
283 data->pcm1796_regs[0][20 - PCM1796_REG_BASE]); 320 data->pcm1796_regs[0][20 - PCM1796_REG_BASE]);
284 pcm1796_write(chip, i, 21, 0); 321 pcm1796_write(chip, i, 21, 0);
322 gain_offset = 0;
285 } 323 }
286} 324}
287 325
@@ -290,10 +328,11 @@ static void pcm1796_init(struct oxygen *chip)
290 struct xonar_pcm179x *data = chip->model_data; 328 struct xonar_pcm179x *data = chip->model_data;
291 329
292 data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE | 330 data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE |
293 PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD; 331 PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
294 data->pcm1796_regs[0][19 - PCM1796_REG_BASE] = 332 data->pcm1796_regs[0][19 - PCM1796_REG_BASE] =
295 PCM1796_FLT_SHARP | PCM1796_ATS_1; 333 PCM1796_FLT_SHARP | PCM1796_ATS_1;
296 data->pcm1796_regs[0][20 - PCM1796_REG_BASE] = PCM1796_OS_64; 334 data->pcm1796_regs[0][20 - PCM1796_REG_BASE] =
335 data->h6 ? PCM1796_OS_64 : PCM1796_OS_128;
297 pcm1796_registers_init(chip); 336 pcm1796_registers_init(chip);
298 data->current_rate = 48000; 337 data->current_rate = 48000;
299} 338}
@@ -339,18 +378,20 @@ static void xonar_hdav_init(struct oxygen *chip)
339 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 378 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
340 OXYGEN_2WIRE_LENGTH_8 | 379 OXYGEN_2WIRE_LENGTH_8 |
341 OXYGEN_2WIRE_INTERRUPT_MASK | 380 OXYGEN_2WIRE_INTERRUPT_MASK |
342 OXYGEN_2WIRE_SPEED_FAST); 381 OXYGEN_2WIRE_SPEED_STANDARD);
343 382
344 data->pcm179x.generic.anti_pop_delay = 100; 383 data->pcm179x.generic.anti_pop_delay = 100;
345 data->pcm179x.generic.output_enable_bit = GPIO_HDAV_OUTPUT_ENABLE; 384 data->pcm179x.generic.output_enable_bit = GPIO_HDAV_OUTPUT_ENABLE;
346 data->pcm179x.generic.ext_power_reg = OXYGEN_GPI_DATA; 385 data->pcm179x.generic.ext_power_reg = OXYGEN_GPI_DATA;
347 data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; 386 data->pcm179x.generic.ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK;
348 data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER; 387 data->pcm179x.generic.ext_power_bit = GPI_EXT_POWER;
349 data->pcm179x.dacs = chip->model.private_data ? 4 : 1; 388 data->pcm179x.dacs = chip->model.dac_channels_mixer / 2;
389 data->pcm179x.h6 = chip->model.dac_channels_mixer > 2;
350 390
351 pcm1796_init(chip); 391 pcm1796_init(chip);
352 392
353 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_INPUT_ROUTE); 393 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
394 GPIO_HDAV_MAGIC | GPIO_INPUT_ROUTE);
354 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE); 395 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE);
355 396
356 xonar_init_cs53x1(chip); 397 xonar_init_cs53x1(chip);
@@ -367,7 +408,7 @@ static void xonar_st_init_i2c(struct oxygen *chip)
367 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, 408 oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS,
368 OXYGEN_2WIRE_LENGTH_8 | 409 OXYGEN_2WIRE_LENGTH_8 |
369 OXYGEN_2WIRE_INTERRUPT_MASK | 410 OXYGEN_2WIRE_INTERRUPT_MASK |
370 OXYGEN_2WIRE_SPEED_FAST); 411 OXYGEN_2WIRE_SPEED_STANDARD);
371} 412}
372 413
373static void xonar_st_init_common(struct oxygen *chip) 414static void xonar_st_init_common(struct oxygen *chip)
@@ -375,13 +416,14 @@ static void xonar_st_init_common(struct oxygen *chip)
375 struct xonar_pcm179x *data = chip->model_data; 416 struct xonar_pcm179x *data = chip->model_data;
376 417
377 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE; 418 data->generic.output_enable_bit = GPIO_ST_OUTPUT_ENABLE;
378 data->dacs = chip->model.private_data ? 4 : 1; 419 data->dacs = chip->model.dac_channels_mixer / 2;
379 data->hp_gain_offset = 2*-18; 420 data->hp_gain_offset = 2*-18;
380 421
381 pcm1796_init(chip); 422 pcm1796_init(chip);
382 423
383 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, 424 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
384 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP); 425 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR |
426 GPIO_ST_MAGIC | GPIO_ST_HP);
385 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, 427 oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
386 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP); 428 GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP);
387 429
@@ -410,9 +452,11 @@ static void cs2000_registers_init(struct oxygen *chip)
410 cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10); 452 cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10);
411 cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00); 453 cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00);
412 cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00); 454 cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00);
413 cs2000_write(chip, CS2000_FUN_CFG_1, data->cs2000_fun_cfg_1); 455 cs2000_write(chip, CS2000_FUN_CFG_1,
456 data->cs2000_regs[CS2000_FUN_CFG_1]);
414 cs2000_write(chip, CS2000_FUN_CFG_2, 0); 457 cs2000_write(chip, CS2000_FUN_CFG_2, 0);
415 cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2); 458 cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2);
459 msleep(3); /* PLL lock delay */
416} 460}
417 461
418static void xonar_st_init(struct oxygen *chip) 462static void xonar_st_init(struct oxygen *chip)
@@ -420,13 +464,18 @@ static void xonar_st_init(struct oxygen *chip)
420 struct xonar_pcm179x *data = chip->model_data; 464 struct xonar_pcm179x *data = chip->model_data;
421 465
422 data->generic.anti_pop_delay = 100; 466 data->generic.anti_pop_delay = 100;
467 data->h6 = chip->model.dac_channels_mixer > 2;
423 data->has_cs2000 = 1; 468 data->has_cs2000 = 1;
424 data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1; 469 data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1;
470 data->broken_i2c = true;
425 471
426 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, 472 oxygen_write16(chip, OXYGEN_I2S_A_FORMAT,
427 OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S | 473 OXYGEN_RATE_48000 |
428 OXYGEN_I2S_MCLK_128 | OXYGEN_I2S_BITS_16 | 474 OXYGEN_I2S_FORMAT_I2S |
429 OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); 475 OXYGEN_I2S_MCLK(data->h6 ? MCLK_256 : MCLK_512) |
476 OXYGEN_I2S_BITS_16 |
477 OXYGEN_I2S_MASTER |
478 OXYGEN_I2S_BCLK_64);
430 479
431 xonar_st_init_i2c(chip); 480 xonar_st_init_i2c(chip);
432 cs2000_registers_init(chip); 481 cs2000_registers_init(chip);
@@ -507,44 +556,16 @@ static void xonar_st_resume(struct oxygen *chip)
507 xonar_stx_resume(chip); 556 xonar_stx_resume(chip);
508} 557}
509 558
510static unsigned int mclk_from_rate(struct oxygen *chip, unsigned int rate)
511{
512 struct xonar_pcm179x *data = chip->model_data;
513
514 if (rate <= 32000)
515 return OXYGEN_I2S_MCLK_512;
516 else if (rate <= 48000 && data->os_128)
517 return OXYGEN_I2S_MCLK_512;
518 else if (rate <= 96000)
519 return OXYGEN_I2S_MCLK_256;
520 else
521 return OXYGEN_I2S_MCLK_128;
522}
523
524static unsigned int get_pcm1796_i2s_mclk(struct oxygen *chip,
525 unsigned int channel,
526 struct snd_pcm_hw_params *params)
527{
528 if (channel == PCM_MULTICH)
529 return mclk_from_rate(chip, params_rate(params));
530 else
531 return oxygen_default_i2s_mclk(chip, channel, params);
532}
533
534static void update_pcm1796_oversampling(struct oxygen *chip) 559static void update_pcm1796_oversampling(struct oxygen *chip)
535{ 560{
536 struct xonar_pcm179x *data = chip->model_data; 561 struct xonar_pcm179x *data = chip->model_data;
537 unsigned int i; 562 unsigned int i;
538 u8 reg; 563 u8 reg;
539 564
540 if (data->current_rate <= 32000) 565 if (data->current_rate <= 48000 && !data->h6)
541 reg = PCM1796_OS_128; 566 reg = PCM1796_OS_128;
542 else if (data->current_rate <= 48000 && data->os_128)
543 reg = PCM1796_OS_128;
544 else if (data->current_rate <= 96000 || data->os_128)
545 reg = PCM1796_OS_64;
546 else 567 else
547 reg = PCM1796_OS_32; 568 reg = PCM1796_OS_64;
548 for (i = 0; i < data->dacs; ++i) 569 for (i = 0; i < data->dacs; ++i)
549 pcm1796_write_cached(chip, i, 20, reg); 570 pcm1796_write_cached(chip, i, 20, reg);
550} 571}
@@ -554,6 +575,7 @@ static void set_pcm1796_params(struct oxygen *chip,
554{ 575{
555 struct xonar_pcm179x *data = chip->model_data; 576 struct xonar_pcm179x *data = chip->model_data;
556 577
578 msleep(1);
557 data->current_rate = params_rate(params); 579 data->current_rate = params_rate(params);
558 update_pcm1796_oversampling(chip); 580 update_pcm1796_oversampling(chip);
559} 581}
@@ -570,6 +592,7 @@ static void update_pcm1796_volume(struct oxygen *chip)
570 + gain_offset); 592 + gain_offset);
571 pcm1796_write_cached(chip, i, 17, chip->dac_volume[i * 2 + 1] 593 pcm1796_write_cached(chip, i, 17, chip->dac_volume[i * 2 + 1]
572 + gain_offset); 594 + gain_offset);
595 gain_offset = 0;
573 } 596 }
574} 597}
575 598
@@ -579,7 +602,7 @@ static void update_pcm1796_mute(struct oxygen *chip)
579 unsigned int i; 602 unsigned int i;
580 u8 value; 603 u8 value;
581 604
582 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD; 605 value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
583 if (chip->dac_mute) 606 if (chip->dac_mute)
584 value |= PCM1796_MUTE; 607 value |= PCM1796_MUTE;
585 for (i = 0; i < data->dacs; ++i) 608 for (i = 0; i < data->dacs; ++i)
@@ -592,45 +615,35 @@ static void update_cs2000_rate(struct oxygen *chip, unsigned int rate)
592 u8 rate_mclk, reg; 615 u8 rate_mclk, reg;
593 616
594 switch (rate) { 617 switch (rate) {
595 /* XXX Why is the I2S A MCLK half the actual I2S MCLK? */
596 case 32000: 618 case 32000:
597 rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256;
598 break;
599 case 44100:
600 if (data->os_128)
601 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256;
602 else
603 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_128;
604 break;
605 default: /* 48000 */
606 if (data->os_128)
607 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256;
608 else
609 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_128;
610 break;
611 case 64000: 619 case 64000:
612 rate_mclk = OXYGEN_RATE_32000 | OXYGEN_I2S_MCLK_256; 620 rate_mclk = OXYGEN_RATE_32000;
613 break; 621 break;
622 case 44100:
614 case 88200: 623 case 88200:
615 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256;
616 break;
617 case 96000:
618 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256;
619 break;
620 case 176400: 624 case 176400:
621 rate_mclk = OXYGEN_RATE_44100 | OXYGEN_I2S_MCLK_256; 625 rate_mclk = OXYGEN_RATE_44100;
622 break; 626 break;
627 default:
628 case 48000:
629 case 96000:
623 case 192000: 630 case 192000:
624 rate_mclk = OXYGEN_RATE_48000 | OXYGEN_I2S_MCLK_256; 631 rate_mclk = OXYGEN_RATE_48000;
625 break; 632 break;
626 } 633 }
627 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk, 634
628 OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK); 635 if (rate <= 96000 && (rate > 48000 || data->h6)) {
629 if ((rate_mclk & OXYGEN_I2S_MCLK_MASK) <= OXYGEN_I2S_MCLK_128) 636 rate_mclk |= OXYGEN_I2S_MCLK(MCLK_256);
630 reg = CS2000_REF_CLK_DIV_1; 637 reg = CS2000_REF_CLK_DIV_1;
631 else 638 } else {
639 rate_mclk |= OXYGEN_I2S_MCLK(MCLK_512);
632 reg = CS2000_REF_CLK_DIV_2; 640 reg = CS2000_REF_CLK_DIV_2;
641 }
642
643 oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, rate_mclk,
644 OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_MCLK_MASK);
633 cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg); 645 cs2000_write_cached(chip, CS2000_FUN_CFG_1, reg);
646 msleep(3); /* PLL lock delay */
634} 647}
635 648
636static void set_st_params(struct oxygen *chip, 649static void set_st_params(struct oxygen *chip,
@@ -665,13 +678,7 @@ static int rolloff_info(struct snd_kcontrol *ctl,
665 "Sharp Roll-off", "Slow Roll-off" 678 "Sharp Roll-off", "Slow Roll-off"
666 }; 679 };
667 680
668 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 681 return snd_ctl_enum_info(info, 1, 2, names);
669 info->count = 1;
670 info->value.enumerated.items = 2;
671 if (info->value.enumerated.item >= 2)
672 info->value.enumerated.item = 1;
673 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
674 return 0;
675} 682}
676 683
677static int rolloff_get(struct snd_kcontrol *ctl, 684static int rolloff_get(struct snd_kcontrol *ctl,
@@ -719,57 +726,13 @@ static const struct snd_kcontrol_new rolloff_control = {
719 .put = rolloff_put, 726 .put = rolloff_put,
720}; 727};
721 728
722static int os_128_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) 729static const struct snd_kcontrol_new hdav_hdmi_control = {
723{
724 static const char *const names[2] = { "64x", "128x" };
725
726 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
727 info->count = 1;
728 info->value.enumerated.items = 2;
729 if (info->value.enumerated.item >= 2)
730 info->value.enumerated.item = 1;
731 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
732 return 0;
733}
734
735static int os_128_get(struct snd_kcontrol *ctl,
736 struct snd_ctl_elem_value *value)
737{
738 struct oxygen *chip = ctl->private_data;
739 struct xonar_pcm179x *data = chip->model_data;
740
741 value->value.enumerated.item[0] = data->os_128;
742 return 0;
743}
744
745static int os_128_put(struct snd_kcontrol *ctl,
746 struct snd_ctl_elem_value *value)
747{
748 struct oxygen *chip = ctl->private_data;
749 struct xonar_pcm179x *data = chip->model_data;
750 int changed;
751
752 mutex_lock(&chip->mutex);
753 changed = value->value.enumerated.item[0] != data->os_128;
754 if (changed) {
755 data->os_128 = value->value.enumerated.item[0];
756 if (data->has_cs2000)
757 update_cs2000_rate(chip, data->current_rate);
758 oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT,
759 mclk_from_rate(chip, data->current_rate),
760 OXYGEN_I2S_MCLK_MASK);
761 update_pcm1796_oversampling(chip);
762 }
763 mutex_unlock(&chip->mutex);
764 return changed;
765}
766
767static const struct snd_kcontrol_new os_128_control = {
768 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 730 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
769 .name = "DAC Oversampling Playback Enum", 731 .name = "HDMI Playback Switch",
770 .info = os_128_info, 732 .info = snd_ctl_boolean_mono_info,
771 .get = os_128_get, 733 .get = xonar_gpio_bit_switch_get,
772 .put = os_128_put, 734 .put = xonar_gpio_bit_switch_put,
735 .private_value = GPIO_HDAV_OUTPUT_ENABLE | XONAR_GPIO_BIT_INVERT,
773}; 736};
774 737
775static int st_output_switch_info(struct snd_kcontrol *ctl, 738static int st_output_switch_info(struct snd_kcontrol *ctl,
@@ -779,13 +742,7 @@ static int st_output_switch_info(struct snd_kcontrol *ctl,
779 "Speakers", "Headphones", "FP Headphones" 742 "Speakers", "Headphones", "FP Headphones"
780 }; 743 };
781 744
782 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 745 return snd_ctl_enum_info(info, 1, 3, names);
783 info->count = 1;
784 info->value.enumerated.items = 3;
785 if (info->value.enumerated.item >= 3)
786 info->value.enumerated.item = 2;
787 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
788 return 0;
789} 746}
790 747
791static int st_output_switch_get(struct snd_kcontrol *ctl, 748static int st_output_switch_get(struct snd_kcontrol *ctl,
@@ -840,13 +797,7 @@ static int st_hp_volume_offset_info(struct snd_kcontrol *ctl,
840 "< 64 ohms", "64-300 ohms", "300-600 ohms" 797 "< 64 ohms", "64-300 ohms", "300-600 ohms"
841 }; 798 };
842 799
843 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 800 return snd_ctl_enum_info(info, 1, 3, names);
844 info->count = 1;
845 info->value.enumerated.items = 3;
846 if (info->value.enumerated.item > 2)
847 info->value.enumerated.item = 2;
848 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
849 return 0;
850} 801}
851 802
852static int st_hp_volume_offset_get(struct snd_kcontrol *ctl, 803static int st_hp_volume_offset_get(struct snd_kcontrol *ctl,
@@ -928,16 +879,25 @@ static int xonar_d2_control_filter(struct snd_kcontrol_new *template)
928 return 0; 879 return 0;
929} 880}
930 881
882static int xonar_st_h6_control_filter(struct snd_kcontrol_new *template)
883{
884 if (!strncmp(template->name, "Master Playback ", 16))
885 /* no volume/mute, as I²C to the third DAC does not work */
886 return 1;
887 return 0;
888}
889
931static int add_pcm1796_controls(struct oxygen *chip) 890static int add_pcm1796_controls(struct oxygen *chip)
932{ 891{
892 struct xonar_pcm179x *data = chip->model_data;
933 int err; 893 int err;
934 894
935 err = snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); 895 if (!data->broken_i2c) {
936 if (err < 0) 896 err = snd_ctl_add(chip->card,
937 return err; 897 snd_ctl_new1(&rolloff_control, chip));
938 err = snd_ctl_add(chip->card, snd_ctl_new1(&os_128_control, chip)); 898 if (err < 0)
939 if (err < 0) 899 return err;
940 return err; 900 }
941 return 0; 901 return 0;
942} 902}
943 903
@@ -956,7 +916,15 @@ static int xonar_d2_mixer_init(struct oxygen *chip)
956 916
957static int xonar_hdav_mixer_init(struct oxygen *chip) 917static int xonar_hdav_mixer_init(struct oxygen *chip)
958{ 918{
959 return add_pcm1796_controls(chip); 919 int err;
920
921 err = snd_ctl_add(chip->card, snd_ctl_new1(&hdav_hdmi_control, chip));
922 if (err < 0)
923 return err;
924 err = add_pcm1796_controls(chip);
925 if (err < 0)
926 return err;
927 return 0;
960} 928}
961 929
962static int xonar_st_mixer_init(struct oxygen *chip) 930static int xonar_st_mixer_init(struct oxygen *chip)
@@ -976,6 +944,45 @@ static int xonar_st_mixer_init(struct oxygen *chip)
976 return 0; 944 return 0;
977} 945}
978 946
947static void dump_pcm1796_registers(struct oxygen *chip,
948 struct snd_info_buffer *buffer)
949{
950 struct xonar_pcm179x *data = chip->model_data;
951 unsigned int dac, i;
952
953 for (dac = 0; dac < data->dacs; ++dac) {
954 snd_iprintf(buffer, "\nPCM1796 %u:", dac + 1);
955 for (i = 0; i < 5; ++i)
956 snd_iprintf(buffer, " %02x",
957 data->pcm1796_regs[dac][i]);
958 }
959 snd_iprintf(buffer, "\n");
960}
961
962static void dump_cs2000_registers(struct oxygen *chip,
963 struct snd_info_buffer *buffer)
964{
965 struct xonar_pcm179x *data = chip->model_data;
966 unsigned int i;
967
968 if (data->has_cs2000) {
969 snd_iprintf(buffer, "\nCS2000:\n00: ");
970 for (i = 1; i < 0x10; ++i)
971 snd_iprintf(buffer, " %02x", data->cs2000_regs[i]);
972 snd_iprintf(buffer, "\n10:");
973 for (i = 0x10; i < 0x1f; ++i)
974 snd_iprintf(buffer, " %02x", data->cs2000_regs[i]);
975 snd_iprintf(buffer, "\n");
976 }
977}
978
979static void dump_st_registers(struct oxygen *chip,
980 struct snd_info_buffer *buffer)
981{
982 dump_pcm1796_registers(chip, buffer);
983 dump_cs2000_registers(chip, buffer);
984}
985
979static const struct oxygen_model model_xonar_d2 = { 986static const struct oxygen_model model_xonar_d2 = {
980 .longname = "Asus Virtuoso 200", 987 .longname = "Asus Virtuoso 200",
981 .chip = "AV200", 988 .chip = "AV200",
@@ -985,11 +992,11 @@ static const struct oxygen_model model_xonar_d2 = {
985 .cleanup = xonar_d2_cleanup, 992 .cleanup = xonar_d2_cleanup,
986 .suspend = xonar_d2_suspend, 993 .suspend = xonar_d2_suspend,
987 .resume = xonar_d2_resume, 994 .resume = xonar_d2_resume,
988 .get_i2s_mclk = get_pcm1796_i2s_mclk,
989 .set_dac_params = set_pcm1796_params, 995 .set_dac_params = set_pcm1796_params,
990 .set_adc_params = xonar_set_cs53x1_params, 996 .set_adc_params = xonar_set_cs53x1_params,
991 .update_dac_volume = update_pcm1796_volume, 997 .update_dac_volume = update_pcm1796_volume,
992 .update_dac_mute = update_pcm1796_mute, 998 .update_dac_mute = update_pcm1796_mute,
999 .dump_registers = dump_pcm1796_registers,
993 .dac_tlv = pcm1796_db_scale, 1000 .dac_tlv = pcm1796_db_scale,
994 .model_data_size = sizeof(struct xonar_pcm179x), 1001 .model_data_size = sizeof(struct xonar_pcm179x),
995 .device_config = PLAYBACK_0_TO_I2S | 1002 .device_config = PLAYBACK_0_TO_I2S |
@@ -999,13 +1006,16 @@ static const struct oxygen_model model_xonar_d2 = {
999 MIDI_OUTPUT | 1006 MIDI_OUTPUT |
1000 MIDI_INPUT | 1007 MIDI_INPUT |
1001 AC97_CD_INPUT, 1008 AC97_CD_INPUT,
1002 .dac_channels = 8, 1009 .dac_channels_pcm = 8,
1010 .dac_channels_mixer = 8,
1003 .dac_volume_min = 255 - 2*60, 1011 .dac_volume_min = 255 - 2*60,
1004 .dac_volume_max = 255, 1012 .dac_volume_max = 255,
1005 .misc_flags = OXYGEN_MISC_MIDI, 1013 .misc_flags = OXYGEN_MISC_MIDI,
1006 .function_flags = OXYGEN_FUNCTION_SPI | 1014 .function_flags = OXYGEN_FUNCTION_SPI |
1007 OXYGEN_FUNCTION_ENABLE_SPI_4_5, 1015 OXYGEN_FUNCTION_ENABLE_SPI_4_5,
1008 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1016 .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
1017 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
1018 .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
1009 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1019 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1010}; 1020};
1011 1021
@@ -1018,25 +1028,28 @@ static const struct oxygen_model model_xonar_hdav = {
1018 .suspend = xonar_hdav_suspend, 1028 .suspend = xonar_hdav_suspend,
1019 .resume = xonar_hdav_resume, 1029 .resume = xonar_hdav_resume,
1020 .pcm_hardware_filter = xonar_hdmi_pcm_hardware_filter, 1030 .pcm_hardware_filter = xonar_hdmi_pcm_hardware_filter,
1021 .get_i2s_mclk = get_pcm1796_i2s_mclk,
1022 .set_dac_params = set_hdav_params, 1031 .set_dac_params = set_hdav_params,
1023 .set_adc_params = xonar_set_cs53x1_params, 1032 .set_adc_params = xonar_set_cs53x1_params,
1024 .update_dac_volume = update_pcm1796_volume, 1033 .update_dac_volume = update_pcm1796_volume,
1025 .update_dac_mute = update_pcm1796_mute, 1034 .update_dac_mute = update_pcm1796_mute,
1026 .uart_input = xonar_hdmi_uart_input, 1035 .uart_input = xonar_hdmi_uart_input,
1027 .ac97_switch = xonar_line_mic_ac97_switch, 1036 .ac97_switch = xonar_line_mic_ac97_switch,
1037 .dump_registers = dump_pcm1796_registers,
1028 .dac_tlv = pcm1796_db_scale, 1038 .dac_tlv = pcm1796_db_scale,
1029 .model_data_size = sizeof(struct xonar_hdav), 1039 .model_data_size = sizeof(struct xonar_hdav),
1030 .device_config = PLAYBACK_0_TO_I2S | 1040 .device_config = PLAYBACK_0_TO_I2S |
1031 PLAYBACK_1_TO_SPDIF | 1041 PLAYBACK_1_TO_SPDIF |
1032 CAPTURE_0_FROM_I2S_2 | 1042 CAPTURE_0_FROM_I2S_2 |
1033 CAPTURE_1_FROM_SPDIF, 1043 CAPTURE_1_FROM_SPDIF,
1034 .dac_channels = 8, 1044 .dac_channels_pcm = 8,
1045 .dac_channels_mixer = 2,
1035 .dac_volume_min = 255 - 2*60, 1046 .dac_volume_min = 255 - 2*60,
1036 .dac_volume_max = 255, 1047 .dac_volume_max = 255,
1037 .misc_flags = OXYGEN_MISC_MIDI, 1048 .misc_flags = OXYGEN_MISC_MIDI,
1038 .function_flags = OXYGEN_FUNCTION_2WIRE, 1049 .function_flags = OXYGEN_FUNCTION_2WIRE,
1039 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1050 .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
1051 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
1052 .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
1040 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1053 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1041}; 1054};
1042 1055
@@ -1048,22 +1061,26 @@ static const struct oxygen_model model_xonar_st = {
1048 .cleanup = xonar_st_cleanup, 1061 .cleanup = xonar_st_cleanup,
1049 .suspend = xonar_st_suspend, 1062 .suspend = xonar_st_suspend,
1050 .resume = xonar_st_resume, 1063 .resume = xonar_st_resume,
1051 .get_i2s_mclk = get_pcm1796_i2s_mclk,
1052 .set_dac_params = set_st_params, 1064 .set_dac_params = set_st_params,
1053 .set_adc_params = xonar_set_cs53x1_params, 1065 .set_adc_params = xonar_set_cs53x1_params,
1054 .update_dac_volume = update_pcm1796_volume, 1066 .update_dac_volume = update_pcm1796_volume,
1055 .update_dac_mute = update_pcm1796_mute, 1067 .update_dac_mute = update_pcm1796_mute,
1056 .ac97_switch = xonar_line_mic_ac97_switch, 1068 .ac97_switch = xonar_line_mic_ac97_switch,
1069 .dump_registers = dump_st_registers,
1057 .dac_tlv = pcm1796_db_scale, 1070 .dac_tlv = pcm1796_db_scale,
1058 .model_data_size = sizeof(struct xonar_pcm179x), 1071 .model_data_size = sizeof(struct xonar_pcm179x),
1059 .device_config = PLAYBACK_0_TO_I2S | 1072 .device_config = PLAYBACK_0_TO_I2S |
1060 PLAYBACK_1_TO_SPDIF | 1073 PLAYBACK_1_TO_SPDIF |
1061 CAPTURE_0_FROM_I2S_2, 1074 CAPTURE_0_FROM_I2S_2 |
1062 .dac_channels = 2, 1075 AC97_FMIC_SWITCH,
1076 .dac_channels_pcm = 2,
1077 .dac_channels_mixer = 2,
1063 .dac_volume_min = 255 - 2*60, 1078 .dac_volume_min = 255 - 2*60,
1064 .dac_volume_max = 255, 1079 .dac_volume_max = 255,
1065 .function_flags = OXYGEN_FUNCTION_2WIRE, 1080 .function_flags = OXYGEN_FUNCTION_2WIRE,
1066 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1081 .dac_mclks = OXYGEN_MCLKS(512, 128, 128),
1082 .adc_mclks = OXYGEN_MCLKS(256, 128, 128),
1083 .dac_i2s_format = OXYGEN_I2S_FORMAT_I2S,
1067 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1084 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1068}; 1085};
1069 1086
@@ -1089,7 +1106,8 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
1089 break; 1106 break;
1090 case GPIO_DB_H6: 1107 case GPIO_DB_H6:
1091 chip->model.shortname = "Xonar HDAV1.3+H6"; 1108 chip->model.shortname = "Xonar HDAV1.3+H6";
1092 chip->model.private_data = 1; 1109 chip->model.dac_channels_mixer = 8;
1110 chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
1093 break; 1111 break;
1094 } 1112 }
1095 break; 1113 break;
@@ -1102,8 +1120,10 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
1102 break; 1120 break;
1103 case GPIO_DB_H6: 1121 case GPIO_DB_H6:
1104 chip->model.shortname = "Xonar ST+H6"; 1122 chip->model.shortname = "Xonar ST+H6";
1105 chip->model.dac_channels = 8; 1123 chip->model.control_filter = xonar_st_h6_control_filter;
1106 chip->model.private_data = 1; 1124 chip->model.dac_channels_pcm = 8;
1125 chip->model.dac_channels_mixer = 8;
1126 chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
1107 break; 1127 break;
1108 } 1128 }
1109 break; 1129 break;
@@ -1114,9 +1134,6 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
1114 chip->model.resume = xonar_stx_resume; 1134 chip->model.resume = xonar_stx_resume;
1115 chip->model.set_dac_params = set_pcm1796_params; 1135 chip->model.set_dac_params = set_pcm1796_params;
1116 break; 1136 break;
1117 case 0x835e:
1118 snd_printk(KERN_ERR "the HDAV1.3 Slim is not supported\n");
1119 return -ENODEV;
1120 default: 1137 default:
1121 return -EINVAL; 1138 return -EINVAL;
1122 } 1139 }
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 200f7601276f..42d1ab136217 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * card driver for models with WM8776/WM8766 DACs (Xonar DS) 2 * card driver for models with WM8776/WM8766 DACs (Xonar DS/HDAV1.3 Slim)
3 * 3 *
4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de> 4 * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5 * 5 *
@@ -22,26 +22,48 @@
22 * 22 *
23 * CMI8788: 23 * CMI8788:
24 * 24 *
25 * SPI 0 -> WM8766 (surround, center/LFE, back) 25 * SPI 0 -> WM8766 (surround, center/LFE, back)
26 * SPI 1 -> WM8776 (front, input) 26 * SPI 1 -> WM8776 (front, input)
27 * 27 *
28 * GPIO 4 <- headphone detect, 0 = plugged 28 * GPIO 4 <- headphone detect, 0 = plugged
29 * GPIO 6 -> route input jack to mic-in (0) or line-in (1) 29 * GPIO 6 -> route input jack to mic-in (0) or line-in (1)
30 * GPIO 7 -> enable output to front L/R speaker channels 30 * GPIO 7 -> enable output to front L/R speaker channels
31 * GPIO 8 -> enable output to other speaker channels and front panel headphone 31 * GPIO 8 -> enable output to other speaker channels and front panel headphone
32 * 32 *
33 * WM8766: 33 * WM8776:
34 * 34 *
35 * input 1 <- line 35 * input 1 <- line
36 * input 2 <- mic 36 * input 2 <- mic
37 * input 3 <- front mic 37 * input 3 <- front mic
38 * input 4 <- aux 38 * input 4 <- aux
39 */
40
41/*
42 * Xonar HDAV1.3 Slim
43 * ------------------
44 *
45 * CMI8788:
46 *
47 * I²C <-> WM8776 (addr 0011010)
48 *
49 * GPIO 0 -> disable HDMI output
50 * GPIO 1 -> enable HP output
51 * GPIO 6 -> firmware EEPROM I²C clock
52 * GPIO 7 <-> firmware EEPROM I²C data
53 *
54 * UART <-> HDMI controller
55 *
56 * WM8776:
57 *
58 * input 1 <- mic
59 * input 2 <- aux
39 */ 60 */
40 61
41#include <linux/pci.h> 62#include <linux/pci.h>
42#include <linux/delay.h> 63#include <linux/delay.h>
43#include <sound/control.h> 64#include <sound/control.h>
44#include <sound/core.h> 65#include <sound/core.h>
66#include <sound/info.h>
45#include <sound/jack.h> 67#include <sound/jack.h>
46#include <sound/pcm.h> 68#include <sound/pcm.h>
47#include <sound/pcm_params.h> 69#include <sound/pcm_params.h>
@@ -55,6 +77,13 @@
55#define GPIO_DS_OUTPUT_FRONTLR 0x0080 77#define GPIO_DS_OUTPUT_FRONTLR 0x0080
56#define GPIO_DS_OUTPUT_ENABLE 0x0100 78#define GPIO_DS_OUTPUT_ENABLE 0x0100
57 79
80#define GPIO_SLIM_HDMI_DISABLE 0x0001
81#define GPIO_SLIM_OUTPUT_ENABLE 0x0002
82#define GPIO_SLIM_FIRMWARE_CLK 0x0040
83#define GPIO_SLIM_FIRMWARE_DATA 0x0080
84
85#define I2C_DEVICE_WM8776 0x34 /* 001101, 0, /W=0 */
86
58#define LC_CONTROL_LIMITER 0x40000000 87#define LC_CONTROL_LIMITER 0x40000000
59#define LC_CONTROL_ALC 0x20000000 88#define LC_CONTROL_ALC 0x20000000
60 89
@@ -66,19 +95,37 @@ struct xonar_wm87x6 {
66 struct snd_kcontrol *mic_adcmux_control; 95 struct snd_kcontrol *mic_adcmux_control;
67 struct snd_kcontrol *lc_controls[13]; 96 struct snd_kcontrol *lc_controls[13];
68 struct snd_jack *hp_jack; 97 struct snd_jack *hp_jack;
98 struct xonar_hdmi hdmi;
69}; 99};
70 100
71static void wm8776_write(struct oxygen *chip, 101static void wm8776_write_spi(struct oxygen *chip,
72 unsigned int reg, unsigned int value) 102 unsigned int reg, unsigned int value)
73{ 103{
74 struct xonar_wm87x6 *data = chip->model_data;
75
76 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 104 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
77 OXYGEN_SPI_DATA_LENGTH_2 | 105 OXYGEN_SPI_DATA_LENGTH_2 |
78 OXYGEN_SPI_CLOCK_160 | 106 OXYGEN_SPI_CLOCK_160 |
79 (1 << OXYGEN_SPI_CODEC_SHIFT) | 107 (1 << OXYGEN_SPI_CODEC_SHIFT) |
80 OXYGEN_SPI_CEN_LATCH_CLOCK_LO, 108 OXYGEN_SPI_CEN_LATCH_CLOCK_LO,
81 (reg << 9) | value); 109 (reg << 9) | value);
110}
111
112static void wm8776_write_i2c(struct oxygen *chip,
113 unsigned int reg, unsigned int value)
114{
115 oxygen_write_i2c(chip, I2C_DEVICE_WM8776,
116 (reg << 1) | (value >> 8), value);
117}
118
119static void wm8776_write(struct oxygen *chip,
120 unsigned int reg, unsigned int value)
121{
122 struct xonar_wm87x6 *data = chip->model_data;
123
124 if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) ==
125 OXYGEN_FUNCTION_SPI)
126 wm8776_write_spi(chip, reg, value);
127 else
128 wm8776_write_i2c(chip, reg, value);
82 if (reg < ARRAY_SIZE(data->wm8776_regs)) { 129 if (reg < ARRAY_SIZE(data->wm8776_regs)) {
83 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER) 130 if (reg >= WM8776_HPLVOL && reg <= WM8776_DACMASTER)
84 value &= ~WM8776_UPDATE; 131 value &= ~WM8776_UPDATE;
@@ -245,17 +292,50 @@ static void xonar_ds_init(struct oxygen *chip)
245 snd_component_add(chip->card, "WM8766"); 292 snd_component_add(chip->card, "WM8766");
246} 293}
247 294
295static void xonar_hdav_slim_init(struct oxygen *chip)
296{
297 struct xonar_wm87x6 *data = chip->model_data;
298
299 data->generic.anti_pop_delay = 300;
300 data->generic.output_enable_bit = GPIO_SLIM_OUTPUT_ENABLE;
301
302 wm8776_init(chip);
303
304 oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
305 GPIO_SLIM_HDMI_DISABLE |
306 GPIO_SLIM_FIRMWARE_CLK |
307 GPIO_SLIM_FIRMWARE_DATA);
308
309 xonar_hdmi_init(chip, &data->hdmi);
310 xonar_enable_output(chip);
311
312 snd_component_add(chip->card, "WM8776");
313}
314
248static void xonar_ds_cleanup(struct oxygen *chip) 315static void xonar_ds_cleanup(struct oxygen *chip)
249{ 316{
250 xonar_disable_output(chip); 317 xonar_disable_output(chip);
251 wm8776_write(chip, WM8776_RESET, 0); 318 wm8776_write(chip, WM8776_RESET, 0);
252} 319}
253 320
321static void xonar_hdav_slim_cleanup(struct oxygen *chip)
322{
323 xonar_hdmi_cleanup(chip);
324 xonar_disable_output(chip);
325 wm8776_write(chip, WM8776_RESET, 0);
326 msleep(2);
327}
328
254static void xonar_ds_suspend(struct oxygen *chip) 329static void xonar_ds_suspend(struct oxygen *chip)
255{ 330{
256 xonar_ds_cleanup(chip); 331 xonar_ds_cleanup(chip);
257} 332}
258 333
334static void xonar_hdav_slim_suspend(struct oxygen *chip)
335{
336 xonar_hdav_slim_cleanup(chip);
337}
338
259static void xonar_ds_resume(struct oxygen *chip) 339static void xonar_ds_resume(struct oxygen *chip)
260{ 340{
261 wm8776_registers_init(chip); 341 wm8776_registers_init(chip);
@@ -264,6 +344,15 @@ static void xonar_ds_resume(struct oxygen *chip)
264 xonar_ds_handle_hp_jack(chip); 344 xonar_ds_handle_hp_jack(chip);
265} 345}
266 346
347static void xonar_hdav_slim_resume(struct oxygen *chip)
348{
349 struct xonar_wm87x6 *data = chip->model_data;
350
351 wm8776_registers_init(chip);
352 xonar_hdmi_resume(chip, &data->hdmi);
353 xonar_enable_output(chip);
354}
355
267static void wm8776_adc_hardware_filter(unsigned int channel, 356static void wm8776_adc_hardware_filter(unsigned int channel,
268 struct snd_pcm_hardware *hardware) 357 struct snd_pcm_hardware *hardware)
269{ 358{
@@ -278,6 +367,13 @@ static void wm8776_adc_hardware_filter(unsigned int channel,
278 } 367 }
279} 368}
280 369
370static void xonar_hdav_slim_hardware_filter(unsigned int channel,
371 struct snd_pcm_hardware *hardware)
372{
373 wm8776_adc_hardware_filter(channel, hardware);
374 xonar_hdmi_pcm_hardware_filter(channel, hardware);
375}
376
281static void set_wm87x6_dac_params(struct oxygen *chip, 377static void set_wm87x6_dac_params(struct oxygen *chip,
282 struct snd_pcm_hw_params *params) 378 struct snd_pcm_hw_params *params)
283{ 379{
@@ -294,6 +390,14 @@ static void set_wm8776_adc_params(struct oxygen *chip,
294 wm8776_write_cached(chip, WM8776_MSTRCTRL, reg); 390 wm8776_write_cached(chip, WM8776_MSTRCTRL, reg);
295} 391}
296 392
393static void set_hdav_slim_dac_params(struct oxygen *chip,
394 struct snd_pcm_hw_params *params)
395{
396 struct xonar_wm87x6 *data = chip->model_data;
397
398 xonar_set_hdmi_params(chip, &data->hdmi, params);
399}
400
297static void update_wm8776_volume(struct oxygen *chip) 401static void update_wm8776_volume(struct oxygen *chip)
298{ 402{
299 struct xonar_wm87x6 *data = chip->model_data; 403 struct xonar_wm87x6 *data = chip->model_data;
@@ -473,11 +577,6 @@ static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
473 const char *const *names; 577 const char *const *names;
474 578
475 max = (ctl->private_value >> 12) & 0xf; 579 max = (ctl->private_value >> 12) & 0xf;
476 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
477 info->count = 1;
478 info->value.enumerated.items = max + 1;
479 if (info->value.enumerated.item > max)
480 info->value.enumerated.item = max;
481 switch ((ctl->private_value >> 24) & 0x1f) { 580 switch ((ctl->private_value >> 24) & 0x1f) {
482 case WM8776_ALCCTRL2: 581 case WM8776_ALCCTRL2:
483 names = hld; 582 names = hld;
@@ -501,8 +600,7 @@ static int wm8776_field_enum_info(struct snd_kcontrol *ctl,
501 default: 600 default:
502 return -ENXIO; 601 return -ENXIO;
503 } 602 }
504 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); 603 return snd_ctl_enum_info(info, 1, max + 1, names);
505 return 0;
506} 604}
507 605
508static int wm8776_field_volume_info(struct snd_kcontrol *ctl, 606static int wm8776_field_volume_info(struct snd_kcontrol *ctl,
@@ -759,13 +857,8 @@ static int wm8776_level_control_info(struct snd_kcontrol *ctl,
759 static const char *const names[3] = { 857 static const char *const names[3] = {
760 "None", "Peak Limiter", "Automatic Level Control" 858 "None", "Peak Limiter", "Automatic Level Control"
761 }; 859 };
762 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 860
763 info->count = 1; 861 return snd_ctl_enum_info(info, 1, 3, names);
764 info->value.enumerated.items = 3;
765 if (info->value.enumerated.item >= 3)
766 info->value.enumerated.item = 2;
767 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
768 return 0;
769} 862}
770 863
771static int wm8776_level_control_get(struct snd_kcontrol *ctl, 864static int wm8776_level_control_get(struct snd_kcontrol *ctl,
@@ -851,13 +944,7 @@ static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
851 "None", "High-pass Filter" 944 "None", "High-pass Filter"
852 }; 945 };
853 946
854 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 947 return snd_ctl_enum_info(info, 1, 2, names);
855 info->count = 1;
856 info->value.enumerated.items = 2;
857 if (info->value.enumerated.item >= 2)
858 info->value.enumerated.item = 1;
859 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
860 return 0;
861} 948}
862 949
863static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) 950static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
@@ -985,6 +1072,53 @@ static const struct snd_kcontrol_new ds_controls[] = {
985 .private_value = 0, 1072 .private_value = 0,
986 }, 1073 },
987}; 1074};
1075static const struct snd_kcontrol_new hdav_slim_controls[] = {
1076 {
1077 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1078 .name = "HDMI Playback Switch",
1079 .info = snd_ctl_boolean_mono_info,
1080 .get = xonar_gpio_bit_switch_get,
1081 .put = xonar_gpio_bit_switch_put,
1082 .private_value = GPIO_SLIM_HDMI_DISABLE | XONAR_GPIO_BIT_INVERT,
1083 },
1084 {
1085 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1086 .name = "Headphone Playback Volume",
1087 .info = wm8776_hp_vol_info,
1088 .get = wm8776_hp_vol_get,
1089 .put = wm8776_hp_vol_put,
1090 .tlv = { .p = wm8776_hp_db_scale },
1091 },
1092 WM8776_BIT_SWITCH("Headphone Playback Switch",
1093 WM8776_PWRDOWN, WM8776_HPPD, 1, 0),
1094 {
1095 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1096 .name = "Input Capture Volume",
1097 .info = wm8776_input_vol_info,
1098 .get = wm8776_input_vol_get,
1099 .put = wm8776_input_vol_put,
1100 .tlv = { .p = wm8776_adc_db_scale },
1101 },
1102 WM8776_BIT_SWITCH("Mic Capture Switch",
1103 WM8776_ADCMUX, 1 << 0, 0, 0),
1104 WM8776_BIT_SWITCH("Aux Capture Switch",
1105 WM8776_ADCMUX, 1 << 1, 0, 0),
1106 {
1107 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1108 .name = "ADC Filter Capture Enum",
1109 .info = hpf_info,
1110 .get = hpf_get,
1111 .put = hpf_put,
1112 },
1113 {
1114 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1115 .name = "Level Control Capture Enum",
1116 .info = wm8776_level_control_info,
1117 .get = wm8776_level_control_get,
1118 .put = wm8776_level_control_put,
1119 .private_value = 0,
1120 },
1121};
988static const struct snd_kcontrol_new lc_controls[] = { 1122static const struct snd_kcontrol_new lc_controls[] = {
989 WM8776_FIELD_CTL_VOLUME("Limiter Threshold", 1123 WM8776_FIELD_CTL_VOLUME("Limiter Threshold",
990 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf, 1124 WM8776_ALCCTRL1, 0, 11, 0, 15, 0xf,
@@ -1028,6 +1162,26 @@ static const struct snd_kcontrol_new lc_controls[] = {
1028 LC_CONTROL_ALC, wm8776_ngth_db_scale), 1162 LC_CONTROL_ALC, wm8776_ngth_db_scale),
1029}; 1163};
1030 1164
1165static int add_lc_controls(struct oxygen *chip)
1166{
1167 struct xonar_wm87x6 *data = chip->model_data;
1168 unsigned int i;
1169 struct snd_kcontrol *ctl;
1170 int err;
1171
1172 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
1173 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
1174 ctl = snd_ctl_new1(&lc_controls[i], chip);
1175 if (!ctl)
1176 return -ENOMEM;
1177 err = snd_ctl_add(chip->card, ctl);
1178 if (err < 0)
1179 return err;
1180 data->lc_controls[i] = ctl;
1181 }
1182 return 0;
1183}
1184
1031static int xonar_ds_mixer_init(struct oxygen *chip) 1185static int xonar_ds_mixer_init(struct oxygen *chip)
1032{ 1186{
1033 struct xonar_wm87x6 *data = chip->model_data; 1187 struct xonar_wm87x6 *data = chip->model_data;
@@ -1049,17 +1203,54 @@ static int xonar_ds_mixer_init(struct oxygen *chip)
1049 } 1203 }
1050 if (!data->line_adcmux_control || !data->mic_adcmux_control) 1204 if (!data->line_adcmux_control || !data->mic_adcmux_control)
1051 return -ENXIO; 1205 return -ENXIO;
1052 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); 1206
1053 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { 1207 return add_lc_controls(chip);
1054 ctl = snd_ctl_new1(&lc_controls[i], chip); 1208}
1209
1210static int xonar_hdav_slim_mixer_init(struct oxygen *chip)
1211{
1212 unsigned int i;
1213 struct snd_kcontrol *ctl;
1214 int err;
1215
1216 for (i = 0; i < ARRAY_SIZE(hdav_slim_controls); ++i) {
1217 ctl = snd_ctl_new1(&hdav_slim_controls[i], chip);
1055 if (!ctl) 1218 if (!ctl)
1056 return -ENOMEM; 1219 return -ENOMEM;
1057 err = snd_ctl_add(chip->card, ctl); 1220 err = snd_ctl_add(chip->card, ctl);
1058 if (err < 0) 1221 if (err < 0)
1059 return err; 1222 return err;
1060 data->lc_controls[i] = ctl;
1061 } 1223 }
1062 return 0; 1224
1225 return add_lc_controls(chip);
1226}
1227
1228static void dump_wm8776_registers(struct oxygen *chip,
1229 struct snd_info_buffer *buffer)
1230{
1231 struct xonar_wm87x6 *data = chip->model_data;
1232 unsigned int i;
1233
1234 snd_iprintf(buffer, "\nWM8776:\n00:");
1235 for (i = 0; i < 0x10; ++i)
1236 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
1237 snd_iprintf(buffer, "\n10:");
1238 for (i = 0x10; i < 0x17; ++i)
1239 snd_iprintf(buffer, " %03x", data->wm8776_regs[i]);
1240 snd_iprintf(buffer, "\n");
1241}
1242
1243static void dump_wm87x6_registers(struct oxygen *chip,
1244 struct snd_info_buffer *buffer)
1245{
1246 struct xonar_wm87x6 *data = chip->model_data;
1247 unsigned int i;
1248
1249 dump_wm8776_registers(chip, buffer);
1250 snd_iprintf(buffer, "\nWM8766:\n00:");
1251 for (i = 0; i < 0x10; ++i)
1252 snd_iprintf(buffer, " %03x", data->wm8766_regs[i]);
1253 snd_iprintf(buffer, "\n");
1063} 1254}
1064 1255
1065static const struct oxygen_model model_xonar_ds = { 1256static const struct oxygen_model model_xonar_ds = {
@@ -1072,22 +1263,57 @@ static const struct oxygen_model model_xonar_ds = {
1072 .suspend = xonar_ds_suspend, 1263 .suspend = xonar_ds_suspend,
1073 .resume = xonar_ds_resume, 1264 .resume = xonar_ds_resume,
1074 .pcm_hardware_filter = wm8776_adc_hardware_filter, 1265 .pcm_hardware_filter = wm8776_adc_hardware_filter,
1075 .get_i2s_mclk = oxygen_default_i2s_mclk,
1076 .set_dac_params = set_wm87x6_dac_params, 1266 .set_dac_params = set_wm87x6_dac_params,
1077 .set_adc_params = set_wm8776_adc_params, 1267 .set_adc_params = set_wm8776_adc_params,
1078 .update_dac_volume = update_wm87x6_volume, 1268 .update_dac_volume = update_wm87x6_volume,
1079 .update_dac_mute = update_wm87x6_mute, 1269 .update_dac_mute = update_wm87x6_mute,
1080 .update_center_lfe_mix = update_wm8766_center_lfe_mix, 1270 .update_center_lfe_mix = update_wm8766_center_lfe_mix,
1081 .gpio_changed = xonar_ds_gpio_changed, 1271 .gpio_changed = xonar_ds_gpio_changed,
1272 .dump_registers = dump_wm87x6_registers,
1082 .dac_tlv = wm87x6_dac_db_scale, 1273 .dac_tlv = wm87x6_dac_db_scale,
1083 .model_data_size = sizeof(struct xonar_wm87x6), 1274 .model_data_size = sizeof(struct xonar_wm87x6),
1084 .device_config = PLAYBACK_0_TO_I2S | 1275 .device_config = PLAYBACK_0_TO_I2S |
1085 PLAYBACK_1_TO_SPDIF | 1276 PLAYBACK_1_TO_SPDIF |
1086 CAPTURE_0_FROM_I2S_1, 1277 CAPTURE_0_FROM_I2S_1,
1087 .dac_channels = 8, 1278 .dac_channels_pcm = 8,
1279 .dac_channels_mixer = 8,
1088 .dac_volume_min = 255 - 2*60, 1280 .dac_volume_min = 255 - 2*60,
1089 .dac_volume_max = 255, 1281 .dac_volume_max = 255,
1090 .function_flags = OXYGEN_FUNCTION_SPI, 1282 .function_flags = OXYGEN_FUNCTION_SPI,
1283 .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
1284 .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
1285 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1286 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1287};
1288
1289static const struct oxygen_model model_xonar_hdav_slim = {
1290 .shortname = "Xonar HDAV1.3 Slim",
1291 .longname = "Asus Virtuoso 200",
1292 .chip = "AV200",
1293 .init = xonar_hdav_slim_init,
1294 .mixer_init = xonar_hdav_slim_mixer_init,
1295 .cleanup = xonar_hdav_slim_cleanup,
1296 .suspend = xonar_hdav_slim_suspend,
1297 .resume = xonar_hdav_slim_resume,
1298 .pcm_hardware_filter = xonar_hdav_slim_hardware_filter,
1299 .set_dac_params = set_hdav_slim_dac_params,
1300 .set_adc_params = set_wm8776_adc_params,
1301 .update_dac_volume = update_wm8776_volume,
1302 .update_dac_mute = update_wm8776_mute,
1303 .uart_input = xonar_hdmi_uart_input,
1304 .dump_registers = dump_wm8776_registers,
1305 .dac_tlv = wm87x6_dac_db_scale,
1306 .model_data_size = sizeof(struct xonar_wm87x6),
1307 .device_config = PLAYBACK_0_TO_I2S |
1308 PLAYBACK_1_TO_SPDIF |
1309 CAPTURE_0_FROM_I2S_1,
1310 .dac_channels_pcm = 8,
1311 .dac_channels_mixer = 2,
1312 .dac_volume_min = 255 - 2*60,
1313 .dac_volume_max = 255,
1314 .function_flags = OXYGEN_FUNCTION_2WIRE,
1315 .dac_mclks = OXYGEN_MCLKS(256, 256, 128),
1316 .adc_mclks = OXYGEN_MCLKS(256, 256, 128),
1091 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1317 .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1092 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, 1318 .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
1093}; 1319};
@@ -1099,6 +1325,9 @@ int __devinit get_xonar_wm87x6_model(struct oxygen *chip,
1099 case 0x838e: 1325 case 0x838e:
1100 chip->model = model_xonar_ds; 1326 chip->model = model_xonar_ds;
1101 break; 1327 break;
1328 case 0x835e:
1329 chip->model = model_xonar_hdav_slim;
1330 break;
1102 default: 1331 default:
1103 return -EINVAL; 1332 return -EINVAL;
1104 } 1333 }
diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
index 0b720cf7783e..2d8332416c83 100644
--- a/sound/pci/rme9652/hdsp.c
+++ b/sound/pci/rme9652/hdsp.c
@@ -60,6 +60,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP},"
60 "{RME HDSP-9652}," 60 "{RME HDSP-9652},"
61 "{RME HDSP-9632}}"); 61 "{RME HDSP-9632}}");
62#ifdef HDSP_FW_LOADER 62#ifdef HDSP_FW_LOADER
63MODULE_FIRMWARE("rpm_firmware.bin");
63MODULE_FIRMWARE("multiface_firmware.bin"); 64MODULE_FIRMWARE("multiface_firmware.bin");
64MODULE_FIRMWARE("multiface_firmware_rev11.bin"); 65MODULE_FIRMWARE("multiface_firmware_rev11.bin");
65MODULE_FIRMWARE("digiface_firmware.bin"); 66MODULE_FIRMWARE("digiface_firmware.bin");
@@ -81,6 +82,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
81#define H9632_SS_CHANNELS 12 82#define H9632_SS_CHANNELS 12
82#define H9632_DS_CHANNELS 8 83#define H9632_DS_CHANNELS 8
83#define H9632_QS_CHANNELS 4 84#define H9632_QS_CHANNELS 4
85#define RPM_CHANNELS 6
84 86
85/* Write registers. These are defined as byte-offsets from the iobase value. 87/* Write registers. These are defined as byte-offsets from the iobase value.
86 */ 88 */
@@ -191,6 +193,25 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin");
191#define HDSP_PhoneGain1 (1<<30) 193#define HDSP_PhoneGain1 (1<<30)
192#define HDSP_QuadSpeed (1<<31) 194#define HDSP_QuadSpeed (1<<31)
193 195
196/* RPM uses some of the registers for special purposes */
197#define HDSP_RPM_Inp12 0x04A00
198#define HDSP_RPM_Inp12_Phon_6dB 0x00800 /* Dolby */
199#define HDSP_RPM_Inp12_Phon_0dB 0x00000 /* .. */
200#define HDSP_RPM_Inp12_Phon_n6dB 0x04000 /* inp_0 */
201#define HDSP_RPM_Inp12_Line_0dB 0x04200 /* Dolby+PRO */
202#define HDSP_RPM_Inp12_Line_n6dB 0x00200 /* PRO */
203
204#define HDSP_RPM_Inp34 0x32000
205#define HDSP_RPM_Inp34_Phon_6dB 0x20000 /* SyncRef1 */
206#define HDSP_RPM_Inp34_Phon_0dB 0x00000 /* .. */
207#define HDSP_RPM_Inp34_Phon_n6dB 0x02000 /* SyncRef2 */
208#define HDSP_RPM_Inp34_Line_0dB 0x30000 /* SyncRef1+SyncRef0 */
209#define HDSP_RPM_Inp34_Line_n6dB 0x10000 /* SyncRef0 */
210
211#define HDSP_RPM_Bypass 0x01000
212
213#define HDSP_RPM_Disconnect 0x00001
214
194#define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1) 215#define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1)
195#define HDSP_ADGainMinus10dBV HDSP_ADGainMask 216#define HDSP_ADGainMinus10dBV HDSP_ADGainMask
196#define HDSP_ADGainPlus4dBu (HDSP_ADGain0) 217#define HDSP_ADGainPlus4dBu (HDSP_ADGain0)
@@ -450,7 +471,7 @@ struct hdsp {
450 u32 creg_spdif; 471 u32 creg_spdif;
451 u32 creg_spdif_stream; 472 u32 creg_spdif_stream;
452 int clock_source_locked; 473 int clock_source_locked;
453 char *card_name; /* digiface/multiface */ 474 char *card_name; /* digiface/multiface/rpm */
454 enum HDSP_IO_Type io_type; /* ditto, but for code use */ 475 enum HDSP_IO_Type io_type; /* ditto, but for code use */
455 unsigned short firmware_rev; 476 unsigned short firmware_rev;
456 unsigned short state; /* stores state bits */ 477 unsigned short state; /* stores state bits */
@@ -612,6 +633,7 @@ static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out)
612 switch (hdsp->io_type) { 633 switch (hdsp->io_type) {
613 case Multiface: 634 case Multiface:
614 case Digiface: 635 case Digiface:
636 case RPM:
615 default: 637 default:
616 if (hdsp->firmware_rev == 0xa) 638 if (hdsp->firmware_rev == 0xa)
617 return (64 * out) + (32 + (in)); 639 return (64 * out) + (32 + (in));
@@ -629,6 +651,7 @@ static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out)
629 switch (hdsp->io_type) { 651 switch (hdsp->io_type) {
630 case Multiface: 652 case Multiface:
631 case Digiface: 653 case Digiface:
654 case RPM:
632 default: 655 default:
633 if (hdsp->firmware_rev == 0xa) 656 if (hdsp->firmware_rev == 0xa)
634 return (64 * out) + in; 657 return (64 * out) + in;
@@ -655,7 +678,7 @@ static int hdsp_check_for_iobox (struct hdsp *hdsp)
655{ 678{
656 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; 679 if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0;
657 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) { 680 if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) {
658 snd_printk ("Hammerfall-DSP: no Digiface or Multiface connected!\n"); 681 snd_printk("Hammerfall-DSP: no IO box connected!\n");
659 hdsp->state &= ~HDSP_FirmwareLoaded; 682 hdsp->state &= ~HDSP_FirmwareLoaded;
660 return -EIO; 683 return -EIO;
661 } 684 }
@@ -680,7 +703,7 @@ static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops,
680 } 703 }
681 } 704 }
682 705
683 snd_printk("Hammerfall-DSP: no Digiface or Multiface connected!\n"); 706 snd_printk("Hammerfall-DSP: no IO box connected!\n");
684 hdsp->state &= ~HDSP_FirmwareLoaded; 707 hdsp->state &= ~HDSP_FirmwareLoaded;
685 return -EIO; 708 return -EIO;
686} 709}
@@ -752,17 +775,21 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp)
752 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); 775 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD);
753 hdsp_write (hdsp, HDSP_fifoData, 0); 776 hdsp_write (hdsp, HDSP_fifoData, 0);
754 777
755 if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT)) { 778 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) {
756 hdsp->io_type = Multiface; 779 hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT);
757 hdsp_write (hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); 780 hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD);
758 hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); 781 if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT))
759 hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT); 782 hdsp->io_type = RPM;
783 else
784 hdsp->io_type = Multiface;
760 } else { 785 } else {
761 hdsp->io_type = Digiface; 786 hdsp->io_type = Digiface;
762 } 787 }
763 } else { 788 } else {
764 /* firmware was already loaded, get iobox type */ 789 /* firmware was already loaded, get iobox type */
765 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) 790 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
791 hdsp->io_type = RPM;
792 else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
766 hdsp->io_type = Multiface; 793 hdsp->io_type = Multiface;
767 else 794 else
768 hdsp->io_type = Digiface; 795 hdsp->io_type = Digiface;
@@ -1184,6 +1211,7 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally)
1184 hdsp->channel_map = channel_map_ds; 1211 hdsp->channel_map = channel_map_ds;
1185 } else { 1212 } else {
1186 switch (hdsp->io_type) { 1213 switch (hdsp->io_type) {
1214 case RPM:
1187 case Multiface: 1215 case Multiface:
1188 hdsp->channel_map = channel_map_mf_ss; 1216 hdsp->channel_map = channel_map_mf_ss;
1189 break; 1217 break;
@@ -3231,6 +3259,318 @@ HDSP_PRECISE_POINTER("Precise Pointer", 0),
3231HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), 3259HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0),
3232}; 3260};
3233 3261
3262
3263static int hdsp_rpm_input12(struct hdsp *hdsp)
3264{
3265 switch (hdsp->control_register & HDSP_RPM_Inp12) {
3266 case HDSP_RPM_Inp12_Phon_6dB:
3267 return 0;
3268 case HDSP_RPM_Inp12_Phon_n6dB:
3269 return 2;
3270 case HDSP_RPM_Inp12_Line_0dB:
3271 return 3;
3272 case HDSP_RPM_Inp12_Line_n6dB:
3273 return 4;
3274 }
3275 return 1;
3276}
3277
3278
3279static int snd_hdsp_get_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3280{
3281 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3282
3283 ucontrol->value.enumerated.item[0] = hdsp_rpm_input12(hdsp);
3284 return 0;
3285}
3286
3287
3288static int hdsp_set_rpm_input12(struct hdsp *hdsp, int mode)
3289{
3290 hdsp->control_register &= ~HDSP_RPM_Inp12;
3291 switch (mode) {
3292 case 0:
3293 hdsp->control_register |= HDSP_RPM_Inp12_Phon_6dB;
3294 break;
3295 case 1:
3296 break;
3297 case 2:
3298 hdsp->control_register |= HDSP_RPM_Inp12_Phon_n6dB;
3299 break;
3300 case 3:
3301 hdsp->control_register |= HDSP_RPM_Inp12_Line_0dB;
3302 break;
3303 case 4:
3304 hdsp->control_register |= HDSP_RPM_Inp12_Line_n6dB;
3305 break;
3306 default:
3307 return -1;
3308 }
3309
3310 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3311 return 0;
3312}
3313
3314
3315static int snd_hdsp_put_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3316{
3317 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3318 int change;
3319 int val;
3320
3321 if (!snd_hdsp_use_is_exclusive(hdsp))
3322 return -EBUSY;
3323 val = ucontrol->value.enumerated.item[0];
3324 if (val < 0)
3325 val = 0;
3326 if (val > 4)
3327 val = 4;
3328 spin_lock_irq(&hdsp->lock);
3329 if (val != hdsp_rpm_input12(hdsp))
3330 change = (hdsp_set_rpm_input12(hdsp, val) == 0) ? 1 : 0;
3331 else
3332 change = 0;
3333 spin_unlock_irq(&hdsp->lock);
3334 return change;
3335}
3336
3337
3338static int snd_hdsp_info_rpm_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
3339{
3340 static char *texts[] = {"Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB"};
3341
3342 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3343 uinfo->count = 1;
3344 uinfo->value.enumerated.items = 5;
3345 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3346 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3347 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3348 return 0;
3349}
3350
3351
3352static int hdsp_rpm_input34(struct hdsp *hdsp)
3353{
3354 switch (hdsp->control_register & HDSP_RPM_Inp34) {
3355 case HDSP_RPM_Inp34_Phon_6dB:
3356 return 0;
3357 case HDSP_RPM_Inp34_Phon_n6dB:
3358 return 2;
3359 case HDSP_RPM_Inp34_Line_0dB:
3360 return 3;
3361 case HDSP_RPM_Inp34_Line_n6dB:
3362 return 4;
3363 }
3364 return 1;
3365}
3366
3367
3368static int snd_hdsp_get_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3369{
3370 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3371
3372 ucontrol->value.enumerated.item[0] = hdsp_rpm_input34(hdsp);
3373 return 0;
3374}
3375
3376
3377static int hdsp_set_rpm_input34(struct hdsp *hdsp, int mode)
3378{
3379 hdsp->control_register &= ~HDSP_RPM_Inp34;
3380 switch (mode) {
3381 case 0:
3382 hdsp->control_register |= HDSP_RPM_Inp34_Phon_6dB;
3383 break;
3384 case 1:
3385 break;
3386 case 2:
3387 hdsp->control_register |= HDSP_RPM_Inp34_Phon_n6dB;
3388 break;
3389 case 3:
3390 hdsp->control_register |= HDSP_RPM_Inp34_Line_0dB;
3391 break;
3392 case 4:
3393 hdsp->control_register |= HDSP_RPM_Inp34_Line_n6dB;
3394 break;
3395 default:
3396 return -1;
3397 }
3398
3399 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3400 return 0;
3401}
3402
3403
3404static int snd_hdsp_put_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3405{
3406 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3407 int change;
3408 int val;
3409
3410 if (!snd_hdsp_use_is_exclusive(hdsp))
3411 return -EBUSY;
3412 val = ucontrol->value.enumerated.item[0];
3413 if (val < 0)
3414 val = 0;
3415 if (val > 4)
3416 val = 4;
3417 spin_lock_irq(&hdsp->lock);
3418 if (val != hdsp_rpm_input34(hdsp))
3419 change = (hdsp_set_rpm_input34(hdsp, val) == 0) ? 1 : 0;
3420 else
3421 change = 0;
3422 spin_unlock_irq(&hdsp->lock);
3423 return change;
3424}
3425
3426
3427/* RPM Bypass switch */
3428static int hdsp_rpm_bypass(struct hdsp *hdsp)
3429{
3430 return (hdsp->control_register & HDSP_RPM_Bypass) ? 1 : 0;
3431}
3432
3433
3434static int snd_hdsp_get_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3435{
3436 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3437
3438 ucontrol->value.integer.value[0] = hdsp_rpm_bypass(hdsp);
3439 return 0;
3440}
3441
3442
3443static int hdsp_set_rpm_bypass(struct hdsp *hdsp, int on)
3444{
3445 if (on)
3446 hdsp->control_register |= HDSP_RPM_Bypass;
3447 else
3448 hdsp->control_register &= ~HDSP_RPM_Bypass;
3449 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3450 return 0;
3451}
3452
3453
3454static int snd_hdsp_put_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3455{
3456 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3457 int change;
3458 unsigned int val;
3459
3460 if (!snd_hdsp_use_is_exclusive(hdsp))
3461 return -EBUSY;
3462 val = ucontrol->value.integer.value[0] & 1;
3463 spin_lock_irq(&hdsp->lock);
3464 change = (int)val != hdsp_rpm_bypass(hdsp);
3465 hdsp_set_rpm_bypass(hdsp, val);
3466 spin_unlock_irq(&hdsp->lock);
3467 return change;
3468}
3469
3470
3471static int snd_hdsp_info_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
3472{
3473 static char *texts[] = {"On", "Off"};
3474
3475 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3476 uinfo->count = 1;
3477 uinfo->value.enumerated.items = 2;
3478 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3479 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3480 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3481 return 0;
3482}
3483
3484
3485/* RPM Disconnect switch */
3486static int hdsp_rpm_disconnect(struct hdsp *hdsp)
3487{
3488 return (hdsp->control_register & HDSP_RPM_Disconnect) ? 1 : 0;
3489}
3490
3491
3492static int snd_hdsp_get_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3493{
3494 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3495
3496 ucontrol->value.integer.value[0] = hdsp_rpm_disconnect(hdsp);
3497 return 0;
3498}
3499
3500
3501static int hdsp_set_rpm_disconnect(struct hdsp *hdsp, int on)
3502{
3503 if (on)
3504 hdsp->control_register |= HDSP_RPM_Disconnect;
3505 else
3506 hdsp->control_register &= ~HDSP_RPM_Disconnect;
3507 hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register);
3508 return 0;
3509}
3510
3511
3512static int snd_hdsp_put_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
3513{
3514 struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
3515 int change;
3516 unsigned int val;
3517
3518 if (!snd_hdsp_use_is_exclusive(hdsp))
3519 return -EBUSY;
3520 val = ucontrol->value.integer.value[0] & 1;
3521 spin_lock_irq(&hdsp->lock);
3522 change = (int)val != hdsp_rpm_disconnect(hdsp);
3523 hdsp_set_rpm_disconnect(hdsp, val);
3524 spin_unlock_irq(&hdsp->lock);
3525 return change;
3526}
3527
3528static int snd_hdsp_info_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
3529{
3530 static char *texts[] = {"On", "Off"};
3531
3532 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3533 uinfo->count = 1;
3534 uinfo->value.enumerated.items = 2;
3535 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
3536 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
3537 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
3538 return 0;
3539}
3540
3541static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = {
3542 {
3543 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3544 .name = "RPM Bypass",
3545 .get = snd_hdsp_get_rpm_bypass,
3546 .put = snd_hdsp_put_rpm_bypass,
3547 .info = snd_hdsp_info_rpm_bypass
3548 },
3549 {
3550 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3551 .name = "RPM Disconnect",
3552 .get = snd_hdsp_get_rpm_disconnect,
3553 .put = snd_hdsp_put_rpm_disconnect,
3554 .info = snd_hdsp_info_rpm_disconnect
3555 },
3556 {
3557 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3558 .name = "Input 1/2",
3559 .get = snd_hdsp_get_rpm_input12,
3560 .put = snd_hdsp_put_rpm_input12,
3561 .info = snd_hdsp_info_rpm_input
3562 },
3563 {
3564 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3565 .name = "Input 3/4",
3566 .get = snd_hdsp_get_rpm_input34,
3567 .put = snd_hdsp_put_rpm_input34,
3568 .info = snd_hdsp_info_rpm_input
3569 },
3570 HDSP_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
3571 HDSP_MIXER("Mixer", 0)
3572};
3573
3234static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); 3574static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0);
3235static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; 3575static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK;
3236 3576
@@ -3240,6 +3580,16 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp)
3240 int err; 3580 int err;
3241 struct snd_kcontrol *kctl; 3581 struct snd_kcontrol *kctl;
3242 3582
3583 if (hdsp->io_type == RPM) {
3584 /* RPM Bypass, Disconnect and Input switches */
3585 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_rpm_controls); idx++) {
3586 err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_rpm_controls[idx], hdsp));
3587 if (err < 0)
3588 return err;
3589 }
3590 return 0;
3591 }
3592
3243 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) { 3593 for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) {
3244 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0) 3594 if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0)
3245 return err; 3595 return err;
@@ -3459,48 +3809,102 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer)
3459 3809
3460 snd_iprintf(buffer, "\n"); 3810 snd_iprintf(buffer, "\n");
3461 3811
3462 switch (hdsp_spdif_in(hdsp)) { 3812 if (hdsp->io_type != RPM) {
3463 case HDSP_SPDIFIN_OPTICAL: 3813 switch (hdsp_spdif_in(hdsp)) {
3464 snd_iprintf(buffer, "IEC958 input: Optical\n"); 3814 case HDSP_SPDIFIN_OPTICAL:
3465 break; 3815 snd_iprintf(buffer, "IEC958 input: Optical\n");
3466 case HDSP_SPDIFIN_COAXIAL: 3816 break;
3467 snd_iprintf(buffer, "IEC958 input: Coaxial\n"); 3817 case HDSP_SPDIFIN_COAXIAL:
3468 break; 3818 snd_iprintf(buffer, "IEC958 input: Coaxial\n");
3469 case HDSP_SPDIFIN_INTERNAL: 3819 break;
3470 snd_iprintf(buffer, "IEC958 input: Internal\n"); 3820 case HDSP_SPDIFIN_INTERNAL:
3471 break; 3821 snd_iprintf(buffer, "IEC958 input: Internal\n");
3472 case HDSP_SPDIFIN_AES: 3822 break;
3473 snd_iprintf(buffer, "IEC958 input: AES\n"); 3823 case HDSP_SPDIFIN_AES:
3474 break; 3824 snd_iprintf(buffer, "IEC958 input: AES\n");
3475 default: 3825 break;
3476 snd_iprintf(buffer, "IEC958 input: ???\n"); 3826 default:
3477 break; 3827 snd_iprintf(buffer, "IEC958 input: ???\n");
3828 break;
3829 }
3478 } 3830 }
3479 3831
3480 if (hdsp->control_register & HDSP_SPDIFOpticalOut) 3832 if (RPM == hdsp->io_type) {
3481 snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n"); 3833 if (hdsp->control_register & HDSP_RPM_Bypass)
3482 else 3834 snd_iprintf(buffer, "RPM Bypass: disabled\n");
3483 snd_iprintf(buffer, "IEC958 output: Coaxial only\n"); 3835 else
3836 snd_iprintf(buffer, "RPM Bypass: enabled\n");
3837 if (hdsp->control_register & HDSP_RPM_Disconnect)
3838 snd_iprintf(buffer, "RPM disconnected\n");
3839 else
3840 snd_iprintf(buffer, "RPM connected\n");
3484 3841
3485 if (hdsp->control_register & HDSP_SPDIFProfessional) 3842 switch (hdsp->control_register & HDSP_RPM_Inp12) {
3486 snd_iprintf(buffer, "IEC958 quality: Professional\n"); 3843 case HDSP_RPM_Inp12_Phon_6dB:
3487 else 3844 snd_iprintf(buffer, "Input 1/2: Phono, 6dB\n");
3488 snd_iprintf(buffer, "IEC958 quality: Consumer\n"); 3845 break;
3846 case HDSP_RPM_Inp12_Phon_0dB:
3847 snd_iprintf(buffer, "Input 1/2: Phono, 0dB\n");
3848 break;
3849 case HDSP_RPM_Inp12_Phon_n6dB:
3850 snd_iprintf(buffer, "Input 1/2: Phono, -6dB\n");
3851 break;
3852 case HDSP_RPM_Inp12_Line_0dB:
3853 snd_iprintf(buffer, "Input 1/2: Line, 0dB\n");
3854 break;
3855 case HDSP_RPM_Inp12_Line_n6dB:
3856 snd_iprintf(buffer, "Input 1/2: Line, -6dB\n");
3857 break;
3858 default:
3859 snd_iprintf(buffer, "Input 1/2: ???\n");
3860 }
3489 3861
3490 if (hdsp->control_register & HDSP_SPDIFEmphasis) 3862 switch (hdsp->control_register & HDSP_RPM_Inp34) {
3491 snd_iprintf(buffer, "IEC958 emphasis: on\n"); 3863 case HDSP_RPM_Inp34_Phon_6dB:
3492 else 3864 snd_iprintf(buffer, "Input 3/4: Phono, 6dB\n");
3493 snd_iprintf(buffer, "IEC958 emphasis: off\n"); 3865 break;
3866 case HDSP_RPM_Inp34_Phon_0dB:
3867 snd_iprintf(buffer, "Input 3/4: Phono, 0dB\n");
3868 break;
3869 case HDSP_RPM_Inp34_Phon_n6dB:
3870 snd_iprintf(buffer, "Input 3/4: Phono, -6dB\n");
3871 break;
3872 case HDSP_RPM_Inp34_Line_0dB:
3873 snd_iprintf(buffer, "Input 3/4: Line, 0dB\n");
3874 break;
3875 case HDSP_RPM_Inp34_Line_n6dB:
3876 snd_iprintf(buffer, "Input 3/4: Line, -6dB\n");
3877 break;
3878 default:
3879 snd_iprintf(buffer, "Input 3/4: ???\n");
3880 }
3494 3881
3495 if (hdsp->control_register & HDSP_SPDIFNonAudio) 3882 } else {
3496 snd_iprintf(buffer, "IEC958 NonAudio: on\n"); 3883 if (hdsp->control_register & HDSP_SPDIFOpticalOut)
3497 else 3884 snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n");
3498 snd_iprintf(buffer, "IEC958 NonAudio: off\n"); 3885 else
3499 if ((x = hdsp_spdif_sample_rate (hdsp)) != 0) 3886 snd_iprintf(buffer, "IEC958 output: Coaxial only\n");
3500 snd_iprintf (buffer, "IEC958 sample rate: %d\n", x); 3887
3501 else 3888 if (hdsp->control_register & HDSP_SPDIFProfessional)
3502 snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n"); 3889 snd_iprintf(buffer, "IEC958 quality: Professional\n");
3890 else
3891 snd_iprintf(buffer, "IEC958 quality: Consumer\n");
3892
3893 if (hdsp->control_register & HDSP_SPDIFEmphasis)
3894 snd_iprintf(buffer, "IEC958 emphasis: on\n");
3895 else
3896 snd_iprintf(buffer, "IEC958 emphasis: off\n");
3503 3897
3898 if (hdsp->control_register & HDSP_SPDIFNonAudio)
3899 snd_iprintf(buffer, "IEC958 NonAudio: on\n");
3900 else
3901 snd_iprintf(buffer, "IEC958 NonAudio: off\n");
3902 x = hdsp_spdif_sample_rate(hdsp);
3903 if (x != 0)
3904 snd_iprintf(buffer, "IEC958 sample rate: %d\n", x);
3905 else
3906 snd_iprintf(buffer, "IEC958 sample rate: Error flag set\n");
3907 }
3504 snd_iprintf(buffer, "\n"); 3908 snd_iprintf(buffer, "\n");
3505 3909
3506 /* Sync Check */ 3910 /* Sync Check */
@@ -3765,7 +4169,7 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id)
3765 snd_hdsp_midi_input_read (&hdsp->midi[0]); 4169 snd_hdsp_midi_input_read (&hdsp->midi[0]);
3766 } 4170 }
3767 } 4171 }
3768 if (hdsp->io_type != Multiface && hdsp->io_type != H9632 && midi1 && midi1status) { 4172 if (hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632 && midi1 && midi1status) {
3769 if (hdsp->use_midi_tasklet) { 4173 if (hdsp->use_midi_tasklet) {
3770 /* we disable interrupts for this input until processing is done */ 4174 /* we disable interrupts for this input until processing is done */
3771 hdsp->control_register &= ~HDSP_Midi1InterruptEnable; 4175 hdsp->control_register &= ~HDSP_Midi1InterruptEnable;
@@ -4093,7 +4497,7 @@ static struct snd_pcm_hardware snd_hdsp_playback_subinfo =
4093 SNDRV_PCM_RATE_96000), 4497 SNDRV_PCM_RATE_96000),
4094 .rate_min = 32000, 4498 .rate_min = 32000,
4095 .rate_max = 96000, 4499 .rate_max = 96000,
4096 .channels_min = 14, 4500 .channels_min = 6,
4097 .channels_max = HDSP_MAX_CHANNELS, 4501 .channels_max = HDSP_MAX_CHANNELS,
4098 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, 4502 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
4099 .period_bytes_min = (64 * 4) * 10, 4503 .period_bytes_min = (64 * 4) * 10,
@@ -4122,7 +4526,7 @@ static struct snd_pcm_hardware snd_hdsp_capture_subinfo =
4122 SNDRV_PCM_RATE_96000), 4526 SNDRV_PCM_RATE_96000),
4123 .rate_min = 32000, 4527 .rate_min = 32000,
4124 .rate_max = 96000, 4528 .rate_max = 96000,
4125 .channels_min = 14, 4529 .channels_min = 5,
4126 .channels_max = HDSP_MAX_CHANNELS, 4530 .channels_max = HDSP_MAX_CHANNELS,
4127 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, 4531 .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS,
4128 .period_bytes_min = (64 * 4) * 10, 4532 .period_bytes_min = (64 * 4) * 10,
@@ -4357,10 +4761,12 @@ static int snd_hdsp_playback_open(struct snd_pcm_substream *substream)
4357 snd_hdsp_hw_rule_rate_out_channels, hdsp, 4761 snd_hdsp_hw_rule_rate_out_channels, hdsp,
4358 SNDRV_PCM_HW_PARAM_CHANNELS, -1); 4762 SNDRV_PCM_HW_PARAM_CHANNELS, -1);
4359 4763
4360 hdsp->creg_spdif_stream = hdsp->creg_spdif; 4764 if (RPM != hdsp->io_type) {
4361 hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; 4765 hdsp->creg_spdif_stream = hdsp->creg_spdif;
4362 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | 4766 hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE;
4363 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); 4767 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
4768 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
4769 }
4364 return 0; 4770 return 0;
4365} 4771}
4366 4772
@@ -4375,9 +4781,11 @@ static int snd_hdsp_playback_release(struct snd_pcm_substream *substream)
4375 4781
4376 spin_unlock_irq(&hdsp->lock); 4782 spin_unlock_irq(&hdsp->lock);
4377 4783
4378 hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; 4784 if (RPM != hdsp->io_type) {
4379 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | 4785 hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
4380 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); 4786 snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE |
4787 SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id);
4788 }
4381 return 0; 4789 return 0;
4382} 4790}
4383 4791
@@ -4616,7 +5024,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
4616 if (hdsp->io_type != H9632) 5024 if (hdsp->io_type != H9632)
4617 info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp); 5025 info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp);
4618 info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp); 5026 info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp);
4619 for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i) 5027 for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i)
4620 info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i); 5028 info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i);
4621 info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp); 5029 info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp);
4622 info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp); 5030 info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp);
@@ -4636,6 +5044,9 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
4636 info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp); 5044 info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp);
4637 info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp); 5045 info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp);
4638 5046
5047 } else if (hdsp->io_type == RPM) {
5048 info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp);
5049 info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp);
4639 } 5050 }
4640 if (hdsp->io_type == H9632 || hdsp->io_type == H9652) 5051 if (hdsp->io_type == H9632 || hdsp->io_type == H9652)
4641 info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp); 5052 info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp);
@@ -4844,6 +5255,14 @@ static void snd_hdsp_initialize_channels(struct hdsp *hdsp)
4844 hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS; 5255 hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS;
4845 break; 5256 break;
4846 5257
5258 case RPM:
5259 hdsp->card_name = "RME Hammerfall DSP + RPM";
5260 hdsp->ss_in_channels = RPM_CHANNELS-1;
5261 hdsp->ss_out_channels = RPM_CHANNELS;
5262 hdsp->ds_in_channels = RPM_CHANNELS-1;
5263 hdsp->ds_out_channels = RPM_CHANNELS;
5264 break;
5265
4847 default: 5266 default:
4848 /* should never get here */ 5267 /* should never get here */
4849 break; 5268 break;
@@ -4930,6 +5349,9 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp)
4930 5349
4931 /* caution: max length of firmware filename is 30! */ 5350 /* caution: max length of firmware filename is 30! */
4932 switch (hdsp->io_type) { 5351 switch (hdsp->io_type) {
5352 case RPM:
5353 fwfile = "rpm_firmware.bin";
5354 break;
4933 case Multiface: 5355 case Multiface:
4934 if (hdsp->firmware_rev == 0xa) 5356 if (hdsp->firmware_rev == 0xa)
4935 fwfile = "multiface_firmware.bin"; 5357 fwfile = "multiface_firmware.bin";
@@ -5100,7 +5522,9 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
5100 return 0; 5522 return 0;
5101 } else { 5523 } else {
5102 snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n"); 5524 snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n");
5103 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) 5525 if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2)
5526 hdsp->io_type = RPM;
5527 else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1)
5104 hdsp->io_type = Multiface; 5528 hdsp->io_type = Multiface;
5105 else 5529 else
5106 hdsp->io_type = Digiface; 5530 hdsp->io_type = Digiface;
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index 0c98ef9156d8..f5eadfc0672a 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -487,7 +487,7 @@ struct hdspm {
487 struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS]; 487 struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS];
488 /* but input to much, so not used */ 488 /* but input to much, so not used */
489 struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS]; 489 struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS];
490 /* full mixer accessable over mixer ioctl or hwdep-device */ 490 /* full mixer accessible over mixer ioctl or hwdep-device */
491 struct hdspm_mixer *mixer; 491 struct hdspm_mixer *mixer;
492 492
493}; 493};
@@ -550,7 +550,7 @@ static inline int HDSPM_bit2freq(int n)
550 return bit2freq_tab[n]; 550 return bit2freq_tab[n];
551} 551}
552 552
553/* Write/read to/from HDSPM with Adresses in Bytes 553/* Write/read to/from HDSPM with Addresses in Bytes
554 not words but only 32Bit writes are allowed */ 554 not words but only 32Bit writes are allowed */
555 555
556static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg, 556static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg,
@@ -2908,7 +2908,7 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm
2908 2908
2909 /* Channel playback mixer as default control 2909 /* Channel playback mixer as default control
2910 Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, 2910 Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders,
2911 thats too * big for any alsamixer they are accesible via special 2911 thats too * big for any alsamixer they are accessible via special
2912 IOCTL on hwdep and the mixer 2dimensional mixer control 2912 IOCTL on hwdep and the mixer 2dimensional mixer control
2913 */ 2913 */
2914 2914
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index 5518371db13f..c94c051ad0c8 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -1389,15 +1389,9 @@ static struct snd_kcontrol_new snd_ymfpci_spdif_stream __devinitdata =
1389 1389
1390static int snd_ymfpci_drec_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info) 1390static int snd_ymfpci_drec_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info)
1391{ 1391{
1392 static char *texts[3] = {"AC'97", "IEC958", "ZV Port"}; 1392 static const char *const texts[3] = {"AC'97", "IEC958", "ZV Port"};
1393 1393
1394 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1394 return snd_ctl_enum_info(info, 1, 3, texts);
1395 info->count = 1;
1396 info->value.enumerated.items = 3;
1397 if (info->value.enumerated.item > 2)
1398 info->value.enumerated.item = 2;
1399 strcpy(info->value.enumerated.name, texts[info->value.enumerated.item]);
1400 return 0;
1401} 1395}
1402 1396
1403static int snd_ymfpci_drec_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) 1397static int snd_ymfpci_drec_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value)
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c
index 581a670e8261..edce8a27e3ee 100644
--- a/sound/ppc/snd_ps3.c
+++ b/sound/ppc/snd_ps3.c
@@ -51,7 +51,7 @@ static struct snd_ps3_card_info the_card;
51static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY; 51static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY;
52 52
53module_param_named(start_delay, snd_ps3_start_delay, uint, 0644); 53module_param_named(start_delay, snd_ps3_start_delay, uint, 0644);
54MODULE_PARM_DESC(start_delay, "time to insert silent data in milisec"); 54MODULE_PARM_DESC(start_delay, "time to insert silent data in ms");
55 55
56static int index = SNDRV_DEFAULT_IDX1; 56static int index = SNDRV_DEFAULT_IDX1;
57static char *id = SNDRV_DEFAULT_STR1; 57static char *id = SNDRV_DEFAULT_STR1;
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 37133c40e762..89498f9ad2e5 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -1958,7 +1958,7 @@ static int max98088_probe(struct snd_soc_codec *codec)
1958 return ret; 1958 return ret;
1959 } 1959 }
1960 1960
1961 /* initalize private data */ 1961 /* initialize private data */
1962 1962
1963 max98088->sysclk = (unsigned)-1; 1963 max98088->sysclk = (unsigned)-1;
1964 max98088->eq_textcnt = 0; 1964 max98088->eq_textcnt = 0;
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c
index b439eee462cb..8ad93ee2e92b 100644
--- a/sound/soc/pxa/pxa-ssp.c
+++ b/sound/soc/pxa/pxa-ssp.c
@@ -20,6 +20,7 @@
20#include <linux/platform_device.h> 20#include <linux/platform_device.h>
21#include <linux/clk.h> 21#include <linux/clk.h>
22#include <linux/io.h> 22#include <linux/io.h>
23#include <linux/pxa2xx_ssp.h>
23 24
24#include <asm/irq.h> 25#include <asm/irq.h>
25 26
@@ -33,7 +34,6 @@
33#include <mach/hardware.h> 34#include <mach/hardware.h>
34#include <mach/dma.h> 35#include <mach/dma.h>
35#include <mach/audio.h> 36#include <mach/audio.h>
36#include <plat/ssp.h>
37 37
38#include "../../arm/pxa2xx-pcm.h" 38#include "../../arm/pxa2xx-pcm.h"
39#include "pxa-ssp.h" 39#include "pxa-ssp.h"
diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c
index cb2f4d04ab7e..b5c3fad01bb8 100644
--- a/sound/soc/samsung/smdk_spdif.c
+++ b/sound/soc/samsung/smdk_spdif.c
@@ -61,7 +61,7 @@ static int set_audio_clock_heirachy(struct platform_device *pdev)
61 goto out3; 61 goto out3;
62 } 62 }
63 63
64 /* Set audio clock heirachy for S/PDIF */ 64 /* Set audio clock hierarchy for S/PDIF */
65 clk_set_parent(mout_epll, fout_epll); 65 clk_set_parent(mout_epll, fout_epll);
66 clk_set_parent(sclk_audio0, mout_epll); 66 clk_set_parent(sclk_audio0, mout_epll);
67 clk_set_parent(sclk_spdif, sclk_audio0); 67 clk_set_parent(sclk_spdif, sclk_audio0);
@@ -79,7 +79,7 @@ out1:
79 79
80/* We should haved to set clock directly on this part because of clock 80/* We should haved to set clock directly on this part because of clock
81 * scheme of Samsudng SoCs did not support to set rates from abstrct 81 * scheme of Samsudng SoCs did not support to set rates from abstrct
82 * clock of it's heirachy. 82 * clock of it's hierarchy.
83 */ 83 */
84static int set_audio_clock_rate(unsigned long epll_rate, 84static int set_audio_clock_rate(unsigned long epll_rate,
85 unsigned long audio_rate) 85 unsigned long audio_rate)
@@ -195,7 +195,7 @@ static int __init smdk_init(void)
195 if (ret) 195 if (ret)
196 goto err3; 196 goto err3;
197 197
198 /* Set audio clock heirachy manually */ 198 /* Set audio clock hierarchy manually */
199 ret = set_audio_clock_heirachy(smdk_snd_spdif_device); 199 ret = set_audio_clock_heirachy(smdk_snd_spdif_device);
200 if (ret) 200 if (ret)
201 goto err4; 201 goto err4;
diff --git a/sound/usb/format.c b/sound/usb/format.c
index 69148212aa70..5b792d2c8061 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -76,7 +76,10 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
76 format = 1 << UAC_FORMAT_TYPE_I_PCM; 76 format = 1 << UAC_FORMAT_TYPE_I_PCM;
77 } 77 }
78 if (format & (1 << UAC_FORMAT_TYPE_I_PCM)) { 78 if (format & (1 << UAC_FORMAT_TYPE_I_PCM)) {
79 if (sample_width > sample_bytes * 8) { 79 if (chip->usb_id == USB_ID(0x0582, 0x0016) /* Edirol SD-90 */ &&
80 sample_width == 24 && sample_bytes == 2)
81 sample_bytes = 3;
82 else if (sample_width > sample_bytes * 8) {
80 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n", 83 snd_printk(KERN_INFO "%d:%u:%d : sample bitwidth %d in over sample bytes %d\n",
81 chip->dev->devnum, fp->iface, fp->altsetting, 84 chip->dev->devnum, fp->iface, fp->altsetting,
82 sample_width, sample_bytes); 85 sample_width, sample_bytes);
diff --git a/sound/usb/midi.c b/sound/usb/midi.c
index 25bce7e5b1af..db2dc5ffe6dd 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -850,8 +850,8 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
850 return; 850 return;
851 } 851 }
852 852
853 memset(urb->transfer_buffer + count, 0xFD, 9 - count); 853 memset(urb->transfer_buffer + count, 0xFD, ep->max_transfer - count);
854 urb->transfer_buffer_length = count; 854 urb->transfer_buffer_length = ep->max_transfer;
855} 855}
856 856
857static struct usb_protocol_ops snd_usbmidi_122l_ops = { 857static struct usb_protocol_ops snd_usbmidi_122l_ops = {
@@ -1295,6 +1295,13 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
1295 case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */ 1295 case USB_ID(0x1a86, 0x752d): /* QinHeng CH345 "USB2.0-MIDI" */
1296 ep->max_transfer = 4; 1296 ep->max_transfer = 4;
1297 break; 1297 break;
1298 /*
1299 * Some devices only work with 9 bytes packet size:
1300 */
1301 case USB_ID(0x0644, 0x800E): /* Tascam US-122L */
1302 case USB_ID(0x0644, 0x800F): /* Tascam US-144 */
1303 ep->max_transfer = 9;
1304 break;
1298 } 1305 }
1299 for (i = 0; i < OUTPUT_URBS; ++i) { 1306 for (i = 0; i < OUTPUT_URBS; ++i) {
1300 buffer = usb_alloc_coherent(umidi->dev, 1307 buffer = usb_alloc_coherent(umidi->dev,
@@ -1729,13 +1736,7 @@ static int roland_load_info(struct snd_kcontrol *kcontrol,
1729{ 1736{
1730 static const char *const names[] = { "High Load", "Light Load" }; 1737 static const char *const names[] = { "High Load", "Light Load" };
1731 1738
1732 info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1739 return snd_ctl_enum_info(info, 1, 2, names);
1733 info->count = 1;
1734 info->value.enumerated.items = 2;
1735 if (info->value.enumerated.item > 1)
1736 info->value.enumerated.item = 1;
1737 strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
1738 return 0;
1739} 1740}
1740 1741
1741static int roland_load_get(struct snd_kcontrol *kcontrol, 1742static int roland_load_get(struct snd_kcontrol *kcontrol,
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index f2d74d654b3c..7df89b3d7ded 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -1633,18 +1633,11 @@ static int parse_audio_extension_unit(struct mixer_build *state, int unitid, voi
1633static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 1633static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1634{ 1634{
1635 struct usb_mixer_elem_info *cval = kcontrol->private_data; 1635 struct usb_mixer_elem_info *cval = kcontrol->private_data;
1636 char **itemlist = (char **)kcontrol->private_value; 1636 const char **itemlist = (const char **)kcontrol->private_value;
1637 1637
1638 if (snd_BUG_ON(!itemlist)) 1638 if (snd_BUG_ON(!itemlist))
1639 return -EINVAL; 1639 return -EINVAL;
1640 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 1640 return snd_ctl_enum_info(uinfo, 1, cval->max, itemlist);
1641 uinfo->count = 1;
1642 uinfo->value.enumerated.items = cval->max;
1643 if (uinfo->value.enumerated.item >= cval->max)
1644 uinfo->value.enumerated.item = cval->max - 1;
1645 strlcpy(uinfo->value.enumerated.name, itemlist[uinfo->value.enumerated.item],
1646 sizeof(uinfo->value.enumerated.name));
1647 return 0;
1648} 1641}
1649 1642
1650/* get callback for selector unit */ 1643/* get callback for selector unit */
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index ad7079d1676c..35999874d301 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -705,11 +705,11 @@ YAMAHA_DEVICE(0x7010, "UB99"),
705 .data = (const struct snd_usb_audio_quirk[]) { 705 .data = (const struct snd_usb_audio_quirk[]) {
706 { 706 {
707 .ifnum = 0, 707 .ifnum = 0,
708 .type = QUIRK_IGNORE_INTERFACE 708 .type = QUIRK_AUDIO_STANDARD_INTERFACE
709 }, 709 },
710 { 710 {
711 .ifnum = 1, 711 .ifnum = 1,
712 .type = QUIRK_IGNORE_INTERFACE 712 .type = QUIRK_AUDIO_STANDARD_INTERFACE
713 }, 713 },
714 { 714 {
715 .ifnum = 2, 715 .ifnum = 2,
diff --git a/sound/usb/usx2y/us122l.c b/sound/usb/usx2y/us122l.c
index 6ef68e42138e..084e6fc8d5bf 100644
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -273,29 +273,26 @@ static unsigned int usb_stream_hwdep_poll(struct snd_hwdep *hw,
273 struct file *file, poll_table *wait) 273 struct file *file, poll_table *wait)
274{ 274{
275 struct us122l *us122l = hw->private_data; 275 struct us122l *us122l = hw->private_data;
276 struct usb_stream *s = us122l->sk.s;
277 unsigned *polled; 276 unsigned *polled;
278 unsigned int mask; 277 unsigned int mask;
279 278
280 poll_wait(file, &us122l->sk.sleep, wait); 279 poll_wait(file, &us122l->sk.sleep, wait);
281 280
282 switch (s->state) { 281 mask = POLLIN | POLLOUT | POLLWRNORM | POLLERR;
283 case usb_stream_ready: 282 if (mutex_trylock(&us122l->mutex)) {
284 if (us122l->first == file) 283 struct usb_stream *s = us122l->sk.s;
285 polled = &s->periods_polled; 284 if (s && s->state == usb_stream_ready) {
286 else 285 if (us122l->first == file)
287 polled = &us122l->second_periods_polled; 286 polled = &s->periods_polled;
288 if (*polled != s->periods_done) { 287 else
289 *polled = s->periods_done; 288 polled = &us122l->second_periods_polled;
290 mask = POLLIN | POLLOUT | POLLWRNORM; 289 if (*polled != s->periods_done) {
291 break; 290 *polled = s->periods_done;
291 mask = POLLIN | POLLOUT | POLLWRNORM;
292 } else
293 mask = 0;
292 } 294 }
293 /* Fall through */ 295 mutex_unlock(&us122l->mutex);
294 mask = 0;
295 break;
296 default:
297 mask = POLLIN | POLLOUT | POLLWRNORM | POLLERR;
298 break;
299 } 296 }
300 return mask; 297 return mask;
301} 298}
@@ -381,6 +378,7 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
381{ 378{
382 struct usb_stream_config *cfg; 379 struct usb_stream_config *cfg;
383 struct us122l *us122l = hw->private_data; 380 struct us122l *us122l = hw->private_data;
381 struct usb_stream *s;
384 unsigned min_period_frames; 382 unsigned min_period_frames;
385 int err = 0; 383 int err = 0;
386 bool high_speed; 384 bool high_speed;
@@ -426,18 +424,18 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
426 snd_power_wait(hw->card, SNDRV_CTL_POWER_D0); 424 snd_power_wait(hw->card, SNDRV_CTL_POWER_D0);
427 425
428 mutex_lock(&us122l->mutex); 426 mutex_lock(&us122l->mutex);
427 s = us122l->sk.s;
429 if (!us122l->master) 428 if (!us122l->master)
430 us122l->master = file; 429 us122l->master = file;
431 else if (us122l->master != file) { 430 else if (us122l->master != file) {
432 if (memcmp(cfg, &us122l->sk.s->cfg, sizeof(*cfg))) { 431 if (!s || memcmp(cfg, &s->cfg, sizeof(*cfg))) {
433 err = -EIO; 432 err = -EIO;
434 goto unlock; 433 goto unlock;
435 } 434 }
436 us122l->slave = file; 435 us122l->slave = file;
437 } 436 }
438 if (!us122l->sk.s || 437 if (!s || memcmp(cfg, &s->cfg, sizeof(*cfg)) ||
439 memcmp(cfg, &us122l->sk.s->cfg, sizeof(*cfg)) || 438 s->state == usb_stream_xrun) {
440 us122l->sk.s->state == usb_stream_xrun) {
441 us122l_stop(us122l); 439 us122l_stop(us122l);
442 if (!us122l_start(us122l, cfg->sample_rate, cfg->period_frames)) 440 if (!us122l_start(us122l, cfg->sample_rate, cfg->period_frames))
443 err = -EIO; 441 err = -EIO;
@@ -448,6 +446,7 @@ unlock:
448 mutex_unlock(&us122l->mutex); 446 mutex_unlock(&us122l->mutex);
449free: 447free:
450 kfree(cfg); 448 kfree(cfg);
449 wake_up_all(&us122l->sk.sleep);
451 return err; 450 return err;
452} 451}
453 452