diff options
Diffstat (limited to 'sound')
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 | */ |
25 | static int ac97_bus_match(struct device *dev, struct device_driver *drv) | 25 | static 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 | */ |
1493 | int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, | 1493 | int 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 | ||
1515 | EXPORT_SYMBOL(snd_ctl_boolean_stereo_info); | 1515 | EXPORT_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 | */ | ||
1528 | int 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 | } | ||
1541 | EXPORT_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 | */ |
647 | int snd_card_register(struct snd_card *card) | 647 | int 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 | ||
1102 | EXPORT_SYMBOL(snd_pcm_hw_rule_add); | 1128 | EXPORT_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 | |||
73 | module_param(seq_default_timer_resolution, int, 0644); | 74 | module_param(seq_default_timer_resolution, int, 0644); |
74 | MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz."); | 75 | MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz."); |
75 | 76 | ||
77 | MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_SEQUENCER); | ||
78 | MODULE_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 |
191 | static int snd_find_free_minor(void) | 191 | static 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."); | |||
52 | module_param(timer_tstamp_monotonic, int, 0444); | 52 | module_param(timer_tstamp_monotonic, int, 0444); |
53 | MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default)."); | 53 | MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default)."); |
54 | 54 | ||
55 | MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_TIMER); | ||
56 | MODULE_ALIAS("devname:snd/timer"); | ||
57 | |||
55 | struct snd_timer_user { | 58 | struct 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 | ||
211 | config SND_OXYGEN | 211 | config 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 | ||
581 | config 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 | |||
593 | config SND_ICE1712 | 586 | config 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 */ |
1964 | static struct snd_ac97_build_ops null_build_ops; | 1964 | static 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 |
1967 | static void do_update_power(struct work_struct *work) | 1967 | static 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 | ||
374 | static struct snd_ac97_build_ops patch_yamaha_ymf743_ops = { | 374 | static 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 | ||
458 | static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { | 458 | static 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 | ||
505 | static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { | 505 | static 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 | ||
536 | static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { | 536 | static 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 | ||
680 | static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { | 680 | static 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 | ||
874 | static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { | 874 | static 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 | ||
979 | static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = { | 979 | static 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 | ||
1026 | static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = { | 1026 | static 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 | ||
1255 | static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = { | 1255 | static 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 | ||
1330 | static struct snd_ac97_build_ops patch_cirrus_ops = { | 1330 | static 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 | ||
1387 | static struct snd_ac97_build_ops patch_conexant_ops = { | 1387 | static 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 | ||
1563 | static struct snd_ac97_build_ops patch_ad1881_build_ops = { | 1563 | static 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 | ||
1650 | static struct snd_ac97_build_ops patch_ad1885_build_ops = { | 1650 | static 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 | ||
1677 | static struct snd_ac97_build_ops patch_ad1886_build_ops = { | 1677 | static 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 | ||
1884 | static struct snd_ac97_build_ops patch_ad1981a_build_ops = { | 1884 | static 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 | ||
1939 | static struct snd_ac97_build_ops patch_ad1981b_build_ops = { | 1939 | static 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 | ||
2078 | static struct snd_ac97_build_ops patch_ad1888_build_ops = { | 2078 | static 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 | ||
2127 | static struct snd_ac97_build_ops patch_ad1980_build_ops = { | 2127 | static 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 | ||
2242 | static struct snd_ac97_build_ops patch_ad1985_build_ops = { | 2242 | static 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 | ||
2534 | static struct snd_ac97_build_ops patch_ad1986_build_ops = { | 2534 | static 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 | ||
2639 | static struct snd_ac97_build_ops patch_alc650_ops = { | 2639 | static 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 | ||
2791 | static struct snd_ac97_build_ops patch_alc655_ops = { | 2791 | static 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 | ||
2903 | static struct snd_ac97_build_ops patch_alc850_ops = { | 2903 | static 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 | ||
2965 | static struct snd_ac97_build_ops patch_cm9738_ops = { | 2965 | static 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 | ||
3056 | static struct snd_ac97_build_ops patch_cm9739_ops = { | 3056 | static 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 | ||
3230 | static struct snd_ac97_build_ops patch_cm9761_ops = { | 3230 | static 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 | ||
3326 | static struct snd_ac97_build_ops patch_cm9780_ops = { | 3326 | static 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 | ||
3446 | static struct snd_ac97_build_ops patch_vt1616_ops = { | 3446 | static 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 | ||
3800 | static struct snd_ac97_build_ops patch_it2646_ops = { | 3800 | static 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 | ||
3834 | static struct snd_ac97_build_ops patch_si3036_ops = { | 3834 | static 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 | ||
3901 | static struct snd_ac97_build_ops patch_ucb1400_ops = { | 3901 | static 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 | ||
115 | static unsigned int au8830_channels[3] = { | ||
116 | 1, 2, 4, | ||
117 | }; | ||
118 | |||
119 | static 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 */ |
119 | static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) | 126 | static 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; | |||
291 | module_param(seqtimer_scaling, int, 0444); | 293 | module_param(seqtimer_scaling, int, 0444); |
292 | MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128."); | 294 | MODULE_PARM_DESC(seqtimer_scaling, "Set 1024000Hz sequencer timer scale factor (lockup danger!). Default 128."); |
293 | 295 | ||
294 | struct snd_azf3328_codec_data { | ||
295 | unsigned long io_base; | ||
296 | struct snd_pcm_substream *substream; | ||
297 | bool running; | ||
298 | const char *name; | ||
299 | }; | ||
300 | |||
301 | enum snd_azf3328_codec_type { | 296 | enum 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 | ||
303 | struct 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 | |||
307 | struct snd_azf3328 { | 313 | struct 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); | |||
362 | static int | 368 | static int |
363 | snd_azf3328_io_reg_setb(unsigned reg, u8 mask, bool do_set) | 369 | snd_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 | ||
425 | static inline void | ||
426 | snd_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 | |||
416 | static inline u32 | 440 | static inline u32 |
417 | snd_azf3328_codec_inl(const struct snd_azf3328_codec_data *codec, unsigned reg) | 441 | snd_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 | ||
945 | static void | 969 | static void |
946 | snd_azf3328_codec_setfmt(struct snd_azf3328 *chip, | 970 | snd_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 | ||
1021 | static inline void | 1053 | static inline void |
1022 | snd_azf3328_codec_setfmt_lowpower(struct snd_azf3328 *chip, | 1054 | snd_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 | ||
1033 | static void | 1064 | static 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 | ||
1112 | static void | 1140 | static void |
1113 | snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip, | 1141 | snd_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 | ||
1150 | static int | 1196 | static int |
1151 | snd_azf3328_codec_prepare(struct snd_pcm_substream *substream) | 1197 | snd_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 | ||
1173 | static int | 1222 | static int |
1174 | snd_azf3328_codec_trigger(enum snd_azf3328_codec_type codec_type, | 1223 | snd_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 | ||
1333 | static int | ||
1334 | snd_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 | |||
1339 | static int | ||
1340 | snd_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 | |||
1345 | static int | ||
1346 | snd_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 | |||
1351 | static snd_pcm_uframes_t | 1381 | static snd_pcm_uframes_t |
1352 | snd_azf3328_codec_pointer(struct snd_pcm_substream *substream, | 1382 | snd_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 | ||
1376 | static snd_pcm_uframes_t | ||
1377 | snd_azf3328_codec_playback_pointer(struct snd_pcm_substream *substream) | ||
1378 | { | ||
1379 | return snd_azf3328_codec_pointer(substream, AZF_CODEC_PLAYBACK); | ||
1380 | } | ||
1381 | |||
1382 | static snd_pcm_uframes_t | ||
1383 | snd_azf3328_codec_capture_pointer(struct snd_pcm_substream *substream) | ||
1384 | { | ||
1385 | return snd_azf3328_codec_pointer(substream, AZF_CODEC_CAPTURE); | ||
1386 | } | ||
1387 | |||
1388 | static snd_pcm_uframes_t | ||
1389 | snd_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 | ||
1626 | static inline void | 1636 | static inline void |
1627 | snd_azf3328_codec_interrupt(struct snd_azf3328 *chip, u8 status) | 1637 | snd_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 | ||
1805 | static int | 1817 | static int |
1806 | snd_azf3328_playback_open(struct snd_pcm_substream *substream) | 1818 | snd_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 | ||
1811 | static int | 1823 | static int |
1812 | snd_azf3328_capture_open(struct snd_pcm_substream *substream) | 1824 | snd_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 | ||
1817 | static int | 1829 | static int |
1818 | snd_azf3328_i2s_out_open(struct snd_pcm_substream *substream) | 1830 | snd_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 | ||
1823 | static int | 1835 | static int |
1824 | snd_azf3328_pcm_close(struct snd_pcm_substream *substream, | 1836 | snd_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 | ||
1836 | static int | ||
1837 | snd_azf3328_playback_close(struct snd_pcm_substream *substream) | ||
1838 | { | ||
1839 | return snd_azf3328_pcm_close(substream, AZF_CODEC_PLAYBACK); | ||
1840 | } | ||
1841 | |||
1842 | static int | ||
1843 | snd_azf3328_capture_close(struct snd_pcm_substream *substream) | ||
1844 | { | ||
1845 | return snd_azf3328_pcm_close(substream, AZF_CODEC_CAPTURE); | ||
1846 | } | ||
1847 | |||
1848 | static int | ||
1849 | snd_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 | ||
1856 | static struct snd_pcm_ops snd_azf3328_playback_ops = { | 1850 | static 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 | ||
1867 | static struct snd_pcm_ops snd_azf3328_capture_ops = { | 1861 | static 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 | ||
1878 | static struct snd_pcm_ops snd_azf3328_i2s_out_ops = { | 1872 | static 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 | ||
1889 | static int __devinit | 1883 | static 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 = { | |||
637 | static int snd_bt87x_capture_source_info(struct snd_kcontrol *kcontrol, | 637 | static 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 | ||
651 | static int snd_bt87x_capture_source_get(struct snd_kcontrol *kcontrol, | 645 | static 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 | ||
2520 | static inline unsigned int get_line_in_mode(struct cmipci *cm) | 2518 | static 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, | |||
2564 | static int snd_cmipci_mic_in_mode_info(struct snd_kcontrol *kcontrol, | 2562 | static 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 | ||
2577 | static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol, | 2570 | static 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 | } |
1920 | EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); | 1920 | EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); |
1921 | 1921 | ||
1922 | static 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 | */ |
2126 | int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | 2136 | int 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 | */ |
3691 | int snd_hda_check_board_config(struct hda_codec *codec, | 3691 | int 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 | */ |
3755 | int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, | 3755 | int 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 | */ |
765 | static int create_output_mixers(struct hda_codec *codec, const char **names) | 765 | static 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) | |||
780 | static int build_output_controls(struct hda_codec *codec) | 781 | static 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 | */ |
2297 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { | 2300 | static 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, | |||
140 | struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, | 140 | struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, |
141 | const char *name); | 141 | const char *name); |
142 | int snd_hda_add_vmaster(struct hda_codec *codec, char *name, | 142 | int 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); |
144 | int snd_hda_codec_reset(struct hda_codec *codec); | 144 | int 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 | */ |
343 | int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, | 343 | int 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); |
346 | int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, | 346 | int 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); |
349 | int snd_hda_add_new_ctls(struct hda_codec *codec, | 349 | int 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 | ||
419 | static const char *get_pwr_state(u32 state) | 419 | static 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 | ||
133 | static const char *ad_slave_vols[] = { | 136 | static 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 | ||
146 | static const char *ad_slave_sws[] = { | 149 | static 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 | ||
162 | static 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 | |||
172 | static 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 | }; | ||
159 | static void ad198x_free_kctls(struct hda_codec *codec); | 181 | static 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 | ||
334 | static 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 | |||
346 | static 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 | |||
355 | static 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 | ||
1072 | static const char *ad1986a_models[AD1986A_MODELS] = { | 1137 | static 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 | ||
1816 | static const char *ad1981_models[AD1981_MODELS] = { | 1881 | static 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) | |||
2015 | enum { | 2080 | enum { |
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 | ||
2116 | static hda_nid_t ad1988_alt_dac_nid[1] = { | ||
2117 | 0x03 | ||
2118 | }; | ||
2119 | |||
2050 | static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { | 2120 | static 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 | |||
2239 | static 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 | ||
2547 | static 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 | |||
2448 | static struct hda_verb ad1988_capture_init_verbs[] = { | 2609 | static 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 | ||
3081 | static const char *ad1988_models[AD1988_MODEL_LAST] = { | 3243 | static 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 | ||
3402 | static const char *ad1884_slave_vols[] = { | 3578 | static 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 | ||
3640 | static const char *ad1984_models[AD1984_MODELS] = { | 3816 | static 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 | ||
4311 | static const char *ad1884a_models[AD1884A_MODELS] = { | 4487 | static 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 | ||
4699 | static const char *ad1882_models[AD1986A_MODELS] = { | 4875 | static 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 | ||
493 | static const char *dir_sfx[2] = { "Playback", "Capture" }; | 493 | static const char * const dir_sfx[2] = { "Playback", "Capture" }; |
494 | 494 | ||
495 | static int add_mute(struct hda_codec *codec, const char *name, int index, | 495 | static 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 | ||
1159 | static const char *cs420x_models[CS420X_MODELS] = { | 1159 | static 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 | ||
611 | static const char *cmi9880_models[CMI_MODELS] = { | 611 | static 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 | ||
540 | static const char *slave_vols[] = { | 540 | static 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 | ||
546 | static const char *slave_sws[] = { | 546 | static 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 | ||
871 | static struct snd_kcontrol_new cxt5045_mixers[] = { | 871 | static 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 | ||
912 | static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { | 912 | static 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 | ||
962 | static struct hda_verb cxt5045_benq_init_verbs[] = { | 962 | static 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 | ||
1137 | static const char *cxt5045_models[CXT5045_MODELS] = { | 1137 | static 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, | |||
1376 | static struct snd_kcontrol_new cxt5047_base_mixers[] = { | 1376 | static 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 | ||
1582 | static const char *cxt5047_models[CXT5047_MODELS] = { | 1582 | static 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[] = { | |||
1796 | static struct snd_kcontrol_new cxt5051_capture_mixers[] = { | 1796 | static 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[] = { | |||
1806 | static struct snd_kcontrol_new cxt5051_hp_mixers[] = { | 1806 | static 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[] = { | |||
1826 | static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { | 1826 | static 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 | ||
1998 | static const char *cxt5051_models[CXT5051_MODELS] = { | 1998 | static 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 | |||
2114 | static void cxt5066_update_speaker(struct hda_codec *codec) | 2119 | static 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[] = { | |||
2727 | static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { | 2729 | static 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 | ||
3085 | static const char *cxt5066_models[CXT5066_MODELS] = { | 3087 | static 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] = { | |||
3095 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | 3097 | static 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 | ||
39 | static bool static_hdmi_pcm; | ||
40 | module_param(static_hdmi_pcm, bool, 0644); | ||
41 | MODULE_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 | ||
915 | static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid) | 924 | static 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 | ||
1205 | static unsigned int channels_2_6_8[] = { | ||
1206 | 2, 6, 8 | ||
1207 | }; | ||
1208 | |||
1209 | static unsigned int channels_2_8[] = { | ||
1210 | 2, 8 | ||
1211 | }; | ||
1212 | |||
1213 | static 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 | |||
1219 | static 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 | |||
1169 | static int simple_playback_pcm_open(struct hda_pcm_stream *hinfo, | 1225 | static 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 | ||
306 | struct alc_fixup; | ||
307 | |||
307 | struct alc_spec { | 308 | struct 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 | ||
1687 | struct alc_model_fixup { | ||
1688 | const int id; | ||
1689 | const char *name; | ||
1690 | }; | ||
1691 | |||
1681 | struct alc_fixup { | 1692 | struct 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 | ||
1687 | static void alc_pick_fixup(struct hda_codec *codec, | 1706 | enum { |
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); | 1714 | enum { |
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 | |
1720 | static 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", | 1787 | static 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 | */ |
2823 | static const char *alc_slave_vols[] = { | 2921 | static 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 | ||
2837 | static const char *alc_slave_sws[] = { | 2935 | static 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 */ |
3310 | static void alc880_uniwill_mic_automute(struct hda_codec *codec) | 3408 | static 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) | |||
3329 | static void alc880_uniwill_init_hook(struct hda_codec *codec) | 3427 | static 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 | ||
3335 | static void alc880_uniwill_unsol_event(struct hda_codec *codec, | 3433 | static 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 | ||
4516 | static const char *alc880_models[ALC880_MODEL_LAST] = { | 4616 | static 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 | ||
5126 | static 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 */ |
5026 | static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | 5146 | static 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 | ||
7023 | static const struct alc_fixup alc260_fixups[] = { | 7145 | static 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 | */ |
7040 | static const char *alc260_models[ALC260_MODEL_LAST] = { | 7163 | static 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 | ||
8949 | static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { | 9073 | static 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 | |||
8983 | static 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 | /* | ||
9186 | static 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 | |||
9194 | static struct hda_verb alc883_mitac_verbs[] = { | 9295 | static 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 | ||
9437 | static 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 */ |
9448 | static void alc883_medion_md2_setup(struct hda_codec *codec) | 9539 | static 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 | ||
9460 | static 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 | |||
9469 | static void alc883_clevo_m720_setup(struct hda_codec *codec) | 9551 | static 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) | |||
9477 | static void alc883_clevo_m720_init_hook(struct hda_codec *codec) | 9559 | static 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 | ||
9483 | static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, | 9565 | static 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 | */ |
9704 | static const char *alc882_models[ALC882_MODEL_LAST] = { | 9786 | static 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 | ||
10667 | static const struct alc_fixup alc882_fixups[] = { | 10735 | static 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[] = { | |||
11222 | static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { | 11306 | static 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 | ||
12428 | static const struct alc_fixup alc262_fixups[] = { | 12507 | static 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 | ||
12445 | static struct snd_pci_quirk alc262_fixup_tbl[] = { | 12519 | static 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 | */ |
12532 | static const char *alc262_models[ALC262_MODEL_LAST] = { | 12606 | static 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 | */ |
13719 | static const char *alc268_models[ALC268_MODEL_LAST] = { | 13796 | static 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[] = { | |||
14154 | static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { | 14231 | static 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 | ||
14162 | static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { | 14239 | static 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 | ||
14169 | static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { | 14246 | static 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 | ||
14177 | static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { | 14254 | static 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 | ||
14876 | static 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 | |||
14799 | enum { | 14887 | enum { |
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 | ||
14804 | static const struct alc_fixup alc269_fixups[] = { | 14897 | static 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 | ||
14821 | static struct snd_pci_quirk alc269_fixup_tbl[] = { | 14951 | static 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 | */ |
14831 | static const char *alc269_models[ALC269_MODEL_LAST] = { | 14969 | static 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 | ||
15857 | static int alc861_create_out_sw(struct hda_codec *codec, const char *pfx, | 15997 | static 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 */ |
15865 | static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, | 16008 | static 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 | */ |
16083 | static const char *alc861_models[ALC861_MODEL_LAST] = { | 16218 | static 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 | ||
16231 | static const struct alc_fixup alc861_fixups[] = { | 16366 | static 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 = { | |||
16369 | static struct hda_input_mux alc861vd_dallas_capture_source = { | 16506 | static 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 | */ |
16516 | static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { | 16653 | static 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 | ||
16691 | static 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 | |||
16703 | static void alc861vd_lenovo_setup(struct hda_codec *codec) | 16828 | static 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) | |||
16710 | static void alc861vd_lenovo_init_hook(struct hda_codec *codec) | 16835 | static 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 | ||
16716 | static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, | 16841 | static 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 | */ |
16796 | static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { | 16921 | static 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) | |||
17013 | static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | 17138 | static 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 */ |
17205 | static const struct alc_fixup alc861vd_fixups[] = { | 17326 | static 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 | */ |
18575 | static const char *alc662_models[ALC662_MODEL_LAST] = { | 18698 | static 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 | ||
19062 | static inline int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, | 19185 | static 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 | ||
19069 | static inline int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, | 19192 | static 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 | ||
19445 | static 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 | |||
19326 | enum { | 19459 | enum { |
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 | ||
19331 | static const struct alc_fixup alc662_fixups[] = { | 19466 | static 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 | ||
19346 | static struct snd_pci_quirk alc662_fixup_tbl[] = { | 19494 | static 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 | ||
19503 | static const struct alc_model_fixup alc662_fixup_models[] = { | ||
19504 | {.id = ALC272_FIXUP_MARIO, .name = "mario"}, | ||
19505 | {} | ||
19506 | }; | ||
19354 | 19507 | ||
19355 | 19508 | ||
19356 | static int patch_alc662(struct hda_codec *codec) | 19509 | static 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 | */ |
19842 | static const char *alc680_models[ALC680_MODEL_LAST] = { | 19997 | static 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 |
393 | static hda_nid_t stac92hd87b_dmic_nids[STAC92HD87B_NUM_DMICS + 1] = { | 396 | static 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 | ||
524 | static const char *stac927x_spdif_labels[5] = { | 527 | static 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 | ||
1062 | static const char *slave_vols[] = { | 1065 | static 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 | ||
1073 | static const char *slave_sws[] = { | 1076 | static 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 | ||
1354 | static const char *stac9200_models[STAC_9200_MODELS] = { | 1357 | static 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 | ||
1500 | static const char *stac925x_models[STAC_925x_MODELS] = { | 1503 | static 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 | ||
1574 | static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { | 1577 | static 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 | ||
1660 | static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | 1663 | static 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 | ||
1722 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | 1725 | static 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 | ||
1915 | static const char *stac922x_models[STAC_922X_MODELS] = { | 1918 | static 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 | ||
2077 | static const char *stac927x_models[STAC_927X_MODELS] = { | 2080 | static 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 | ||
2180 | static const char *stac9205_models[STAC_9205_MODELS] = { | 2183 | static 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 */ |
3256 | static const char *stac92xx_mono_labels[4] = { | 3259 | static 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 | ||
3380 | static const char *stac92xx_spdif_labels[3] = { | 3383 | static 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 */ |
3409 | static const char *stac92xx_dmic_labels[5] = { | 3412 | static 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 | ||
5334 | static int stac92hd83xxx_set_system_btl_amp(struct hda_codec *codec) | 5336 | static 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 | ||
6265 | static const char *stac9872_models[STAC_9872_MODELS] = { | 6240 | static 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 | */ | ||
289 | static 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 | */ |
281 | static void vx442_ak4524_lock(struct snd_akm4xxx *ak, int chip) | 303 | static 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 | ||
512 | static 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 | |||
522 | static 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 | |||
490 | static struct snd_akm4xxx akm_delta44 __devinitdata = { | 535 | static 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 @@ | |||
1 | snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o | 1 | snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o |
2 | snd-hifier-objs := hifier.o | 2 | snd-oxygen-objs := oxygen.o xonar_dg.o |
3 | snd-oxygen-objs := oxygen.o | ||
4 | snd-virtuoso-objs := virtuoso.o xonar_lib.o \ | 3 | snd-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 | ||
7 | obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o | 6 | obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o |
8 | obj-$(CONFIG_SND_HIFIER) += snd-hifier.o | ||
9 | obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o | 7 | obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o |
10 | obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o | 8 | obj-$(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 | |||
36 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | ||
37 | MODULE_DESCRIPTION("TempoTec HiFier driver"); | ||
38 | MODULE_LICENSE("GPL v2"); | ||
39 | |||
40 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
41 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
42 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
43 | |||
44 | module_param_array(index, int, NULL, 0444); | ||
45 | MODULE_PARM_DESC(index, "card index"); | ||
46 | module_param_array(id, charp, NULL, 0444); | ||
47 | MODULE_PARM_DESC(id, "ID string"); | ||
48 | module_param_array(enable, bool, NULL, 0444); | ||
49 | MODULE_PARM_DESC(enable, "enable card"); | ||
50 | |||
51 | static 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 | }; | ||
57 | MODULE_DEVICE_TABLE(pci, hifier_ids); | ||
58 | |||
59 | struct hifier_data { | ||
60 | u8 ak4396_regs[5]; | ||
61 | }; | ||
62 | |||
63 | static 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 | |||
76 | static 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 | |||
84 | static 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 | |||
96 | static 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 | |||
108 | static void hifier_cleanup(struct oxygen *chip) | ||
109 | { | ||
110 | } | ||
111 | |||
112 | static void hifier_resume(struct oxygen *chip) | ||
113 | { | ||
114 | hifier_registers_init(chip); | ||
115 | } | ||
116 | |||
117 | static 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 | |||
142 | static 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 | |||
148 | static 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 | |||
159 | static void set_cs5340_params(struct oxygen *chip, | ||
160 | struct snd_pcm_hw_params *params) | ||
161 | { | ||
162 | } | ||
163 | |||
164 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); | ||
165 | |||
166 | static 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 | |||
191 | static 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 | |||
198 | static 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 | |||
217 | static 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 | |||
228 | static int __init alsa_card_hifier_init(void) | ||
229 | { | ||
230 | return pci_register_driver(&hifier_driver); | ||
231 | } | ||
232 | |||
233 | static void __exit alsa_card_hifier_exit(void) | ||
234 | { | ||
235 | pci_unregister_driver(&hifier_driver); | ||
236 | } | ||
237 | |||
238 | module_init(alsa_card_hifier_init) | ||
239 | module_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 | ||
52 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | 67 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); |
53 | MODULE_DESCRIPTION("C-Media CMI8788 driver"); | 68 | MODULE_DESCRIPTION("C-Media CMI8788 driver"); |
54 | MODULE_LICENSE("GPL v2"); | 69 | MODULE_LICENSE("GPL v2"); |
55 | MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8788}}"); | 70 | MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8786}" |
71 | ",{C-Media,CMI8787}" | ||
72 | ",{C-Media,CMI8788}}"); | ||
56 | 73 | ||
57 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | 74 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; |
58 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | 75 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; |
@@ -66,24 +83,46 @@ module_param_array(enable, bool, NULL, 0444); | |||
66 | MODULE_PARM_DESC(enable, "enable card"); | 83 | MODULE_PARM_DESC(enable, "enable card"); |
67 | 84 | ||
68 | enum { | 85 | enum { |
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 | ||
75 | static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { | 98 | static 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 | ||
100 | struct generic_data { | 144 | struct 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 | ||
208 | static void meridian_init(struct oxygen *chip) | 254 | static 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 | ||
221 | static void claro_init(struct oxygen *chip) | 271 | static 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 | ||
228 | static void claro_halo_init(struct oxygen *chip) | 280 | static 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 | ||
289 | static void fantasia_init(struct oxygen *chip) | ||
290 | { | ||
291 | ak4396_init(chip); | ||
292 | snd_component_add(chip->card, "CS5340"); | ||
293 | } | ||
294 | |||
295 | static void stereo_output_init(struct oxygen *chip) | ||
296 | { | ||
297 | ak4396_init(chip); | ||
298 | } | ||
299 | |||
235 | static void generic_cleanup(struct oxygen *chip) | 300 | static 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 | ||
336 | static void stereo_resume(struct oxygen *chip) | ||
337 | { | ||
338 | ak4396_registers_init(chip); | ||
339 | } | ||
340 | |||
271 | static void set_ak4396_params(struct oxygen *chip, | 341 | static 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 | ||
299 | static void update_ak4396_volume(struct oxygen *chip) | 369 | static 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 | ||
430 | static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params) | ||
431 | { | ||
432 | } | ||
433 | |||
359 | static int rolloff_info(struct snd_kcontrol *ctl, | 434 | static 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 | ||
375 | static int rolloff_get(struct snd_kcontrol *ctl, | 444 | static 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 | ||
433 | static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) | 496 | static 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 | ||
532 | static 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 | |||
540 | static 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 | |||
548 | static 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 | |||
559 | static 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 | |||
570 | static 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 | |||
591 | static 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 | |||
610 | static 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 | |||
618 | static 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 | |||
469 | static int generic_mixer_init(struct oxygen *chip) | 626 | static 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 | ||
644 | static 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 | |||
658 | static 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 | |||
672 | static 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 | |||
686 | static 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 | |||
700 | static 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 | |||
712 | static 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 | |||
487 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); | 719 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); |
488 | 720 | ||
489 | static const struct oxygen_model model_generic = { | 721 | static 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 = { | |||
520 | static int __devinit get_oxygen_model(struct oxygen *chip, | 755 | static 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 | ||
39 | enum { | 44 | enum { |
40 | CONTROL_SPDIF_PCM, | 45 | CONTROL_SPDIF_PCM, |
@@ -65,6 +70,7 @@ struct snd_pcm_hardware; | |||
65 | struct snd_pcm_hw_params; | 70 | struct snd_pcm_hw_params; |
66 | struct snd_kcontrol_new; | 71 | struct snd_kcontrol_new; |
67 | struct snd_rawmidi; | 72 | struct snd_rawmidi; |
73 | struct snd_info_buffer; | ||
68 | struct oxygen; | 74 | struct oxygen; |
69 | 75 | ||
70 | struct oxygen_model { | 76 | struct 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 | ||
169 | int oxygen_pcm_init(struct oxygen *chip); | 176 | int oxygen_pcm_init(struct oxygen *chip); |
170 | unsigned 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 | ||
237 | static void oxygen_proc_init(struct oxygen *chip) | 245 | static 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 | ||
100 | static 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 | |||
100 | static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) | 110 | static 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 | ||
121 | static int upmix_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) | 125 | static 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) | |||
188 | static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) | 192 | static 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 | ||
433 | static int spdif_loopback_get(struct snd_kcontrol *ctl, | 437 | static 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 | ||
444 | static int spdif_loopback_put(struct snd_kcontrol *ctl, | 448 | static 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 | ||
652 | static 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 | |||
660 | static 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 | |||
672 | static 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 | |||
647 | static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl, | 692 | static 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 | ||
274 | unsigned 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 | } | ||
283 | EXPORT_SYMBOL(oxygen_default_i2s_mclk); | ||
284 | |||
285 | static unsigned int oxygen_i2s_bits(struct snd_pcm_hw_params *hw_params) | 277 | static 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 | ||
336 | static 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 | |||
344 | static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, | 356 | static 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); | |||
24 | void xonar_init_cs53x1(struct oxygen *chip); | 24 | void xonar_init_cs53x1(struct oxygen *chip); |
25 | void xonar_set_cs53x1_params(struct oxygen *chip, | 25 | void 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) | ||
27 | int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl, | 29 | int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl, |
28 | struct snd_ctl_elem_value *value); | 30 | struct snd_ctl_elem_value *value); |
29 | int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl, | 31 | int 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 | ||
285 | static const struct snd_kcontrol_new front_panel_switch = { | 285 | static 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 | ||
310 | static int rolloff_get(struct snd_kcontrol *ctl, | 304 | static 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 | ||
377 | static 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 | |||
388 | static 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 | |||
383 | static const struct oxygen_model model_xonar_d1 = { | 401 | static 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 | |||
59 | struct 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 | |||
67 | static 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 | |||
82 | static 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 | |||
90 | static 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 | |||
117 | static 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 | |||
137 | static void dg_output_enable(struct oxygen *chip) | ||
138 | { | ||
139 | msleep(2500); | ||
140 | oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE); | ||
141 | } | ||
142 | |||
143 | static 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 | |||
162 | static void dg_cleanup(struct oxygen *chip) | ||
163 | { | ||
164 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE); | ||
165 | } | ||
166 | |||
167 | static void dg_suspend(struct oxygen *chip) | ||
168 | { | ||
169 | dg_cleanup(chip); | ||
170 | } | ||
171 | |||
172 | static void dg_resume(struct oxygen *chip) | ||
173 | { | ||
174 | cs4245_registers_init(chip); | ||
175 | dg_output_enable(chip); | ||
176 | } | ||
177 | |||
178 | static 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 | |||
194 | static 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 | |||
210 | static 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 | |||
220 | static 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 | |||
232 | static 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 | |||
267 | static 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 | |||
277 | static 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 | |||
294 | static 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 | |||
319 | static 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 | |||
329 | static 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 | |||
343 | static 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 | |||
373 | static DECLARE_TLV_DB_SCALE(cs4245_pga_db_scale, -1200, 50, 0); | ||
374 | |||
375 | static 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 | |||
385 | static 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 | |||
397 | static 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 | |||
436 | static 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 | |||
443 | static 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 | |||
453 | static 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 | } | ||
480 | static 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 | |||
515 | static 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 | |||
522 | static 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 | |||
536 | static 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 | |||
548 | struct 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 | |||
6 | extern 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 | ||
196 | struct xonar_hdav { | 234 | struct 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 | ||
256 | static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value) | 293 | static 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 | ||
373 | static void xonar_st_init_common(struct oxygen *chip) | 414 | static 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 | ||
418 | static void xonar_st_init(struct oxygen *chip) | 462 | static 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 | ||
510 | static 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 | |||
524 | static 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 | |||
534 | static void update_pcm1796_oversampling(struct oxygen *chip) | 559 | static 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 | ||
636 | static void set_st_params(struct oxygen *chip, | 649 | static 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 | ||
677 | static int rolloff_get(struct snd_kcontrol *ctl, | 684 | static 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 | ||
722 | static int os_128_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) | 729 | static 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 | |||
735 | static 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 | |||
745 | static 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 | |||
767 | static 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 | ||
775 | static int st_output_switch_info(struct snd_kcontrol *ctl, | 738 | static 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 | ||
791 | static int st_output_switch_get(struct snd_kcontrol *ctl, | 748 | static 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 | ||
852 | static int st_hp_volume_offset_get(struct snd_kcontrol *ctl, | 803 | static 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 | ||
882 | static 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 | |||
931 | static int add_pcm1796_controls(struct oxygen *chip) | 890 | static 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 | ||
957 | static int xonar_hdav_mixer_init(struct oxygen *chip) | 917 | static 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 | ||
962 | static int xonar_st_mixer_init(struct oxygen *chip) | 930 | static 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 | ||
947 | static 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 | |||
962 | static 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 | |||
979 | static 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 | |||
979 | static const struct oxygen_model model_xonar_d2 = { | 986 | static 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 | ||
71 | static void wm8776_write(struct oxygen *chip, | 101 | static 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 | |||
112 | static 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 | |||
119 | static 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 | ||
295 | static 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 | |||
248 | static void xonar_ds_cleanup(struct oxygen *chip) | 315 | static 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 | ||
321 | static 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 | |||
254 | static void xonar_ds_suspend(struct oxygen *chip) | 329 | static void xonar_ds_suspend(struct oxygen *chip) |
255 | { | 330 | { |
256 | xonar_ds_cleanup(chip); | 331 | xonar_ds_cleanup(chip); |
257 | } | 332 | } |
258 | 333 | ||
334 | static void xonar_hdav_slim_suspend(struct oxygen *chip) | ||
335 | { | ||
336 | xonar_hdav_slim_cleanup(chip); | ||
337 | } | ||
338 | |||
259 | static void xonar_ds_resume(struct oxygen *chip) | 339 | static 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 | ||
347 | static 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 | |||
267 | static void wm8776_adc_hardware_filter(unsigned int channel, | 356 | static 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 | ||
370 | static 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 | |||
281 | static void set_wm87x6_dac_params(struct oxygen *chip, | 377 | static 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 | ||
393 | static 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 | |||
297 | static void update_wm8776_volume(struct oxygen *chip) | 401 | static 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 | ||
508 | static int wm8776_field_volume_info(struct snd_kcontrol *ctl, | 606 | static 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 | ||
771 | static int wm8776_level_control_get(struct snd_kcontrol *ctl, | 864 | static 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 | ||
863 | static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) | 950 | static 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 | }; |
1075 | static 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 | }; | ||
988 | static const struct snd_kcontrol_new lc_controls[] = { | 1122 | static 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 | ||
1165 | static 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 | |||
1031 | static int xonar_ds_mixer_init(struct oxygen *chip) | 1185 | static 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 | |||
1210 | static 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 | |||
1228 | static 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 | |||
1243 | static 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 | ||
1065 | static const struct oxygen_model model_xonar_ds = { | 1256 | static 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 | |||
1289 | static 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 |
63 | MODULE_FIRMWARE("rpm_firmware.bin"); | ||
63 | MODULE_FIRMWARE("multiface_firmware.bin"); | 64 | MODULE_FIRMWARE("multiface_firmware.bin"); |
64 | MODULE_FIRMWARE("multiface_firmware_rev11.bin"); | 65 | MODULE_FIRMWARE("multiface_firmware_rev11.bin"); |
65 | MODULE_FIRMWARE("digiface_firmware.bin"); | 66 | MODULE_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), | |||
3231 | HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), | 3259 | HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), |
3232 | }; | 3260 | }; |
3233 | 3261 | ||
3262 | |||
3263 | static 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 | |||
3279 | static 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 | |||
3288 | static 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 | |||
3315 | static 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 | |||
3338 | static 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 | |||
3352 | static 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 | |||
3368 | static 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 | |||
3377 | static 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 | |||
3404 | static 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 */ | ||
3428 | static int hdsp_rpm_bypass(struct hdsp *hdsp) | ||
3429 | { | ||
3430 | return (hdsp->control_register & HDSP_RPM_Bypass) ? 1 : 0; | ||
3431 | } | ||
3432 | |||
3433 | |||
3434 | static 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 | |||
3443 | static 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 | |||
3454 | static 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 | |||
3471 | static 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 */ | ||
3486 | static int hdsp_rpm_disconnect(struct hdsp *hdsp) | ||
3487 | { | ||
3488 | return (hdsp->control_register & HDSP_RPM_Disconnect) ? 1 : 0; | ||
3489 | } | ||
3490 | |||
3491 | |||
3492 | static 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 | |||
3501 | static 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 | |||
3512 | static 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 | |||
3528 | static 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 | |||
3541 | static 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 | |||
3234 | static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); | 3574 | static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); |
3235 | static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; | 3575 | static 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 | ||
556 | static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg, | 556 | static 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 | ||
1390 | static int snd_ymfpci_drec_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *info) | 1390 | static 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 | ||
1403 | static int snd_ymfpci_drec_source_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *value) | 1397 | static 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; | |||
51 | static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY; | 51 | static int snd_ps3_start_delay = CONFIG_SND_PS3_DEFAULT_START_DELAY; |
52 | 52 | ||
53 | module_param_named(start_delay, snd_ps3_start_delay, uint, 0644); | 53 | module_param_named(start_delay, snd_ps3_start_delay, uint, 0644); |
54 | MODULE_PARM_DESC(start_delay, "time to insert silent data in milisec"); | 54 | MODULE_PARM_DESC(start_delay, "time to insert silent data in ms"); |
55 | 55 | ||
56 | static int index = SNDRV_DEFAULT_IDX1; | 56 | static int index = SNDRV_DEFAULT_IDX1; |
57 | static char *id = SNDRV_DEFAULT_STR1; | 57 | static 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 | */ |
84 | static int set_audio_clock_rate(unsigned long epll_rate, | 84 | static 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 | ||
857 | static struct usb_protocol_ops snd_usbmidi_122l_ops = { | 857 | static 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 | ||
1741 | static int roland_load_get(struct snd_kcontrol *kcontrol, | 1742 | static 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 | |||
1633 | static int mixer_ctl_selector_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1633 | static 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); |
449 | free: | 447 | free: |
450 | kfree(cfg); | 448 | kfree(cfg); |
449 | wake_up_all(&us122l->sk.sleep); | ||
451 | return err; | 450 | return err; |
452 | } | 451 | } |
453 | 452 | ||