diff options
author | Takashi Iwai <tiwai@suse.de> | 2012-07-18 07:53:06 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2012-07-18 07:53:06 -0400 |
commit | 61eab000f3536f080eab43fd5eed3fd817ded76e (patch) | |
tree | d1448b3b90c5650b522c8d13d8bdd7bd65a5cf52 /sound/pci | |
parent | 68e67f40b7343383517c3f951b4b8db7626406bc (diff) | |
parent | 4e01ec636e64707d202a1ca21a47bbc6d53085b7 (diff) |
Merge branch 'topic/hda' into for-next
This is a large chunk merge for 3.6 HD-audio things
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/es1968.c | 2 | ||||
-rw-r--r-- | sound/pci/fm801.c | 4 | ||||
-rw-r--r-- | sound/pci/hda/Kconfig | 7 | ||||
-rw-r--r-- | sound/pci/hda/hda_beep.c | 82 | ||||
-rw-r--r-- | sound/pci/hda/hda_beep.h | 5 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 66 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 3 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 26 | ||||
-rw-r--r-- | sound/pci/hda/hda_jack.c | 102 | ||||
-rw-r--r-- | sound/pci/hda/hda_jack.h | 1 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_proc.c | 17 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 298 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 284 |
14 files changed, 590 insertions, 311 deletions
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 67f47d891959..52b5c0bf90c1 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -2769,7 +2769,7 @@ static int __devinit snd_es1968_create(struct snd_card *card, | |||
2769 | chip->tea.ops = &snd_es1968_tea_ops; | 2769 | chip->tea.ops = &snd_es1968_tea_ops; |
2770 | strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); | 2770 | strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); |
2771 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); | 2771 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); |
2772 | if (!snd_tea575x_init(&chip->tea)) | 2772 | if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) |
2773 | printk(KERN_INFO "es1968: detected TEA575x radio\n"); | 2773 | printk(KERN_INFO "es1968: detected TEA575x radio\n"); |
2774 | #endif | 2774 | #endif |
2775 | 2775 | ||
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index f69662322750..b32e8024ea86 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -1254,7 +1254,7 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
1254 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); | 1254 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); |
1255 | if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && | 1255 | if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && |
1256 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { | 1256 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { |
1257 | if (snd_tea575x_init(&chip->tea)) { | 1257 | if (snd_tea575x_init(&chip->tea, THIS_MODULE)) { |
1258 | snd_printk(KERN_ERR "TEA575x radio not found\n"); | 1258 | snd_printk(KERN_ERR "TEA575x radio not found\n"); |
1259 | snd_fm801_free(chip); | 1259 | snd_fm801_free(chip); |
1260 | return -ENODEV; | 1260 | return -ENODEV; |
@@ -1263,7 +1263,7 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
1263 | /* autodetect tuner connection */ | 1263 | /* autodetect tuner connection */ |
1264 | for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { | 1264 | for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { |
1265 | chip->tea575x_tuner = tea575x_tuner; | 1265 | chip->tea575x_tuner = tea575x_tuner; |
1266 | if (!snd_tea575x_init(&chip->tea)) { | 1266 | if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) { |
1267 | snd_printk(KERN_INFO "detected TEA575x radio type %s\n", | 1267 | snd_printk(KERN_INFO "detected TEA575x radio type %s\n", |
1268 | get_tea575x_gpio(chip)->name); | 1268 | get_tea575x_gpio(chip)->name); |
1269 | break; | 1269 | break; |
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index d03079764189..194d625c1f83 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig | |||
@@ -53,15 +53,14 @@ config SND_HDA_INPUT_BEEP | |||
53 | driver. This interface is used to generate digital beeps. | 53 | driver. This interface is used to generate digital beeps. |
54 | 54 | ||
55 | config SND_HDA_INPUT_BEEP_MODE | 55 | config SND_HDA_INPUT_BEEP_MODE |
56 | int "Digital beep registration mode (0=off, 1=on, 2=mute sw on/off)" | 56 | int "Digital beep registration mode (0=off, 1=on)" |
57 | depends on SND_HDA_INPUT_BEEP=y | 57 | depends on SND_HDA_INPUT_BEEP=y |
58 | default "1" | 58 | default "1" |
59 | range 0 2 | 59 | range 0 1 |
60 | help | 60 | help |
61 | Set 0 to disable the digital beep interface for HD-audio by default. | 61 | Set 0 to disable the digital beep interface for HD-audio by default. |
62 | Set 1 to always enable the digital beep interface for HD-audio by | 62 | Set 1 to always enable the digital beep interface for HD-audio by |
63 | default. Set 2 to control the beep device registration to input | 63 | default. |
64 | layer using a "Beep Switch" in mixer applications. | ||
65 | 64 | ||
66 | config SND_HDA_INPUT_JACK | 65 | config SND_HDA_INPUT_JACK |
67 | bool "Support jack plugging notification via input layer" | 66 | bool "Support jack plugging notification via input layer" |
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 60738e52b8f9..0bc2315b181d 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -162,50 +162,20 @@ static int snd_hda_do_attach(struct hda_beep *beep) | |||
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
164 | 164 | ||
165 | static void snd_hda_do_register(struct work_struct *work) | ||
166 | { | ||
167 | struct hda_beep *beep = | ||
168 | container_of(work, struct hda_beep, register_work); | ||
169 | |||
170 | mutex_lock(&beep->mutex); | ||
171 | if (beep->enabled && !beep->dev) | ||
172 | snd_hda_do_attach(beep); | ||
173 | mutex_unlock(&beep->mutex); | ||
174 | } | ||
175 | |||
176 | static void snd_hda_do_unregister(struct work_struct *work) | ||
177 | { | ||
178 | struct hda_beep *beep = | ||
179 | container_of(work, struct hda_beep, unregister_work.work); | ||
180 | |||
181 | mutex_lock(&beep->mutex); | ||
182 | if (!beep->enabled && beep->dev) | ||
183 | snd_hda_do_detach(beep); | ||
184 | mutex_unlock(&beep->mutex); | ||
185 | } | ||
186 | |||
187 | int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) | 165 | int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) |
188 | { | 166 | { |
189 | struct hda_beep *beep = codec->beep; | 167 | struct hda_beep *beep = codec->beep; |
190 | enable = !!enable; | 168 | if (!beep) |
191 | if (beep == NULL) | ||
192 | return 0; | 169 | return 0; |
170 | enable = !!enable; | ||
193 | if (beep->enabled != enable) { | 171 | if (beep->enabled != enable) { |
194 | beep->enabled = enable; | 172 | beep->enabled = enable; |
195 | if (!enable) { | 173 | if (!enable) { |
174 | cancel_work_sync(&beep->beep_work); | ||
196 | /* turn off beep */ | 175 | /* turn off beep */ |
197 | snd_hda_codec_write(beep->codec, beep->nid, 0, | 176 | snd_hda_codec_write(beep->codec, beep->nid, 0, |
198 | AC_VERB_SET_BEEP_CONTROL, 0); | 177 | AC_VERB_SET_BEEP_CONTROL, 0); |
199 | } | 178 | } |
200 | if (beep->mode == HDA_BEEP_MODE_SWREG) { | ||
201 | if (enable) { | ||
202 | cancel_delayed_work(&beep->unregister_work); | ||
203 | schedule_work(&beep->register_work); | ||
204 | } else { | ||
205 | schedule_delayed_work(&beep->unregister_work, | ||
206 | HZ); | ||
207 | } | ||
208 | } | ||
209 | return 1; | 179 | return 1; |
210 | } | 180 | } |
211 | return 0; | 181 | return 0; |
@@ -215,6 +185,7 @@ EXPORT_SYMBOL_HDA(snd_hda_enable_beep_device); | |||
215 | int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) | 185 | int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) |
216 | { | 186 | { |
217 | struct hda_beep *beep; | 187 | struct hda_beep *beep; |
188 | int err; | ||
218 | 189 | ||
219 | if (!snd_hda_get_bool_hint(codec, "beep")) | 190 | if (!snd_hda_get_bool_hint(codec, "beep")) |
220 | return 0; /* disabled explicitly by hints */ | 191 | return 0; /* disabled explicitly by hints */ |
@@ -232,21 +203,16 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) | |||
232 | 203 | ||
233 | beep->nid = nid; | 204 | beep->nid = nid; |
234 | beep->codec = codec; | 205 | beep->codec = codec; |
235 | beep->mode = codec->beep_mode; | ||
236 | codec->beep = beep; | 206 | codec->beep = beep; |
237 | 207 | ||
238 | INIT_WORK(&beep->register_work, &snd_hda_do_register); | ||
239 | INIT_DELAYED_WORK(&beep->unregister_work, &snd_hda_do_unregister); | ||
240 | INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); | 208 | INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); |
241 | mutex_init(&beep->mutex); | 209 | mutex_init(&beep->mutex); |
242 | 210 | ||
243 | if (beep->mode == HDA_BEEP_MODE_ON) { | 211 | err = snd_hda_do_attach(beep); |
244 | int err = snd_hda_do_attach(beep); | 212 | if (err < 0) { |
245 | if (err < 0) { | 213 | kfree(beep); |
246 | kfree(beep); | 214 | codec->beep = NULL; |
247 | codec->beep = NULL; | 215 | return err; |
248 | return err; | ||
249 | } | ||
250 | } | 216 | } |
251 | 217 | ||
252 | return 0; | 218 | return 0; |
@@ -257,8 +223,6 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) | |||
257 | { | 223 | { |
258 | struct hda_beep *beep = codec->beep; | 224 | struct hda_beep *beep = codec->beep; |
259 | if (beep) { | 225 | if (beep) { |
260 | cancel_work_sync(&beep->register_work); | ||
261 | cancel_delayed_work(&beep->unregister_work); | ||
262 | if (beep->dev) | 226 | if (beep->dev) |
263 | snd_hda_do_detach(beep); | 227 | snd_hda_do_detach(beep); |
264 | codec->beep = NULL; | 228 | codec->beep = NULL; |
@@ -266,3 +230,31 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) | |||
266 | } | 230 | } |
267 | } | 231 | } |
268 | EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); | 232 | EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); |
233 | |||
234 | /* get/put callbacks for beep mute mixer switches */ | ||
235 | int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, | ||
236 | struct snd_ctl_elem_value *ucontrol) | ||
237 | { | ||
238 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
239 | struct hda_beep *beep = codec->beep; | ||
240 | if (beep) { | ||
241 | ucontrol->value.integer.value[0] = | ||
242 | ucontrol->value.integer.value[1] = | ||
243 | beep->enabled; | ||
244 | return 0; | ||
245 | } | ||
246 | return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | ||
247 | } | ||
248 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get_beep); | ||
249 | |||
250 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, | ||
251 | struct snd_ctl_elem_value *ucontrol) | ||
252 | { | ||
253 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
254 | struct hda_beep *beep = codec->beep; | ||
255 | if (beep) | ||
256 | snd_hda_enable_beep_device(codec, | ||
257 | *ucontrol->value.integer.value); | ||
258 | return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
259 | } | ||
260 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep); | ||
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h index 55f0647458c7..4dc6933bc655 100644 --- a/sound/pci/hda/hda_beep.h +++ b/sound/pci/hda/hda_beep.h | |||
@@ -26,21 +26,16 @@ | |||
26 | 26 | ||
27 | #define HDA_BEEP_MODE_OFF 0 | 27 | #define HDA_BEEP_MODE_OFF 0 |
28 | #define HDA_BEEP_MODE_ON 1 | 28 | #define HDA_BEEP_MODE_ON 1 |
29 | #define HDA_BEEP_MODE_SWREG 2 | ||
30 | 29 | ||
31 | /* beep information */ | 30 | /* beep information */ |
32 | struct hda_beep { | 31 | struct hda_beep { |
33 | struct input_dev *dev; | 32 | struct input_dev *dev; |
34 | struct hda_codec *codec; | 33 | struct hda_codec *codec; |
35 | unsigned int mode; | ||
36 | char phys[32]; | 34 | char phys[32]; |
37 | int tone; | 35 | int tone; |
38 | hda_nid_t nid; | 36 | hda_nid_t nid; |
39 | unsigned int enabled:1; | 37 | unsigned int enabled:1; |
40 | unsigned int request_enable:1; | ||
41 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ | 38 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ |
42 | struct work_struct register_work; /* registration work */ | ||
43 | struct delayed_work unregister_work; /* unregistration work */ | ||
44 | struct work_struct beep_work; /* scheduled task for beep event */ | 39 | struct work_struct beep_work; /* scheduled task for beep event */ |
45 | struct mutex mutex; | 40 | struct mutex mutex; |
46 | }; | 41 | }; |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 51cb2a2e4fce..20580bf69697 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -2676,25 +2676,6 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, | |||
2676 | } | 2676 | } |
2677 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put); | 2677 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put); |
2678 | 2678 | ||
2679 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
2680 | /** | ||
2681 | * snd_hda_mixer_amp_switch_put_beep - Put callback for a beep AMP switch | ||
2682 | * | ||
2683 | * This function calls snd_hda_enable_beep_device(), which behaves differently | ||
2684 | * depending on beep_mode option. | ||
2685 | */ | ||
2686 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, | ||
2687 | struct snd_ctl_elem_value *ucontrol) | ||
2688 | { | ||
2689 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2690 | long *valp = ucontrol->value.integer.value; | ||
2691 | |||
2692 | snd_hda_enable_beep_device(codec, *valp); | ||
2693 | return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
2694 | } | ||
2695 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep); | ||
2696 | #endif /* CONFIG_SND_HDA_INPUT_BEEP */ | ||
2697 | |||
2698 | /* | 2679 | /* |
2699 | * bound volume controls | 2680 | * bound volume controls |
2700 | * | 2681 | * |
@@ -3509,22 +3490,52 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, | |||
3509 | EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all); | 3490 | EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all); |
3510 | 3491 | ||
3511 | /* | 3492 | /* |
3493 | * supported power states check | ||
3494 | */ | ||
3495 | static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, hda_nid_t fg, | ||
3496 | unsigned int power_state) | ||
3497 | { | ||
3498 | int sup = snd_hda_param_read(codec, fg, AC_PAR_POWER_STATE); | ||
3499 | |||
3500 | if (sup < 0) | ||
3501 | return false; | ||
3502 | if (sup & power_state) | ||
3503 | return true; | ||
3504 | else | ||
3505 | return false; | ||
3506 | } | ||
3507 | |||
3508 | /* | ||
3512 | * set power state of the codec | 3509 | * set power state of the codec |
3513 | */ | 3510 | */ |
3514 | static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | 3511 | static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, |
3515 | unsigned int power_state) | 3512 | unsigned int power_state) |
3516 | { | 3513 | { |
3514 | int count; | ||
3515 | unsigned int state; | ||
3516 | |||
3517 | if (codec->patch_ops.set_power_state) { | 3517 | if (codec->patch_ops.set_power_state) { |
3518 | codec->patch_ops.set_power_state(codec, fg, power_state); | 3518 | codec->patch_ops.set_power_state(codec, fg, power_state); |
3519 | return; | 3519 | return; |
3520 | } | 3520 | } |
3521 | 3521 | ||
3522 | /* this delay seems necessary to avoid click noise at power-down */ | 3522 | /* this delay seems necessary to avoid click noise at power-down */ |
3523 | if (power_state == AC_PWRST_D3) | 3523 | if (power_state == AC_PWRST_D3) { |
3524 | msleep(100); | 3524 | /* transition time less than 10ms for power down */ |
3525 | snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, | 3525 | bool epss = snd_hda_codec_get_supported_ps(codec, fg, AC_PWRST_EPSS); |
3526 | power_state); | 3526 | msleep(epss ? 10 : 100); |
3527 | snd_hda_codec_set_power_to_all(codec, fg, power_state, true); | 3527 | } |
3528 | |||
3529 | /* repeat power states setting at most 10 times*/ | ||
3530 | for (count = 0; count < 10; count++) { | ||
3531 | snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, | ||
3532 | power_state); | ||
3533 | snd_hda_codec_set_power_to_all(codec, fg, power_state, true); | ||
3534 | state = snd_hda_codec_read(codec, fg, 0, | ||
3535 | AC_VERB_GET_POWER_STATE, 0); | ||
3536 | if (!(state & AC_PWRST_ERROR)) | ||
3537 | break; | ||
3538 | } | ||
3528 | } | 3539 | } |
3529 | 3540 | ||
3530 | #ifdef CONFIG_SND_HDA_HWDEP | 3541 | #ifdef CONFIG_SND_HDA_HWDEP |
@@ -4418,6 +4429,13 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down) | |||
4418 | cancel_delayed_work_sync(&codec->power_work); | 4429 | cancel_delayed_work_sync(&codec->power_work); |
4419 | 4430 | ||
4420 | spin_lock(&codec->power_lock); | 4431 | spin_lock(&codec->power_lock); |
4432 | /* If the power down delayed work was cancelled above before starting, | ||
4433 | * then there is no need to go through power up here. | ||
4434 | */ | ||
4435 | if (codec->power_on) { | ||
4436 | spin_unlock(&codec->power_lock); | ||
4437 | return; | ||
4438 | } | ||
4421 | trace_hda_power_up(codec); | 4439 | trace_hda_power_up(codec); |
4422 | snd_hda_update_power_acct(codec); | 4440 | snd_hda_update_power_acct(codec); |
4423 | codec->power_on = 1; | 4441 | codec->power_on = 1; |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 2fdaadbb4326..a4ac1de7aa19 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -323,6 +323,9 @@ enum { | |||
323 | #define AC_PWRST_D1 0x01 | 323 | #define AC_PWRST_D1 0x01 |
324 | #define AC_PWRST_D2 0x02 | 324 | #define AC_PWRST_D2 0x02 |
325 | #define AC_PWRST_D3 0x03 | 325 | #define AC_PWRST_D3 0x03 |
326 | #define AC_PWRST_ERROR (1<<8) | ||
327 | #define AC_PWRST_CLK_STOP_OK (1<<9) | ||
328 | #define AC_PWRST_SETTING_RESET (1<<10) | ||
326 | 329 | ||
327 | /* Processing capabilies */ | 330 | /* Processing capabilies */ |
328 | #define AC_PCAP_BENIGN (1<<0) | 331 | #define AC_PCAP_BENIGN (1<<0) |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 7757536b9d5f..b4f3c7295a53 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -72,7 +72,7 @@ static int enable_msi = -1; | |||
72 | static char *patch[SNDRV_CARDS]; | 72 | static char *patch[SNDRV_CARDS]; |
73 | #endif | 73 | #endif |
74 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 74 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
75 | static int beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = | 75 | static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = |
76 | CONFIG_SND_HDA_INPUT_BEEP_MODE}; | 76 | CONFIG_SND_HDA_INPUT_BEEP_MODE}; |
77 | #endif | 77 | #endif |
78 | 78 | ||
@@ -103,9 +103,9 @@ module_param_array(patch, charp, NULL, 0444); | |||
103 | MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface."); | 103 | MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface."); |
104 | #endif | 104 | #endif |
105 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 105 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
106 | module_param_array(beep_mode, int, NULL, 0444); | 106 | module_param_array(beep_mode, bool, NULL, 0444); |
107 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " | 107 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " |
108 | "(0=off, 1=on, 2=mute switch on/off) (default=1)."); | 108 | "(0=off, 1=on) (default=1)."); |
109 | #endif | 109 | #endif |
110 | 110 | ||
111 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 111 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -151,6 +151,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | |||
151 | "{Intel, CPT}," | 151 | "{Intel, CPT}," |
152 | "{Intel, PPT}," | 152 | "{Intel, PPT}," |
153 | "{Intel, LPT}," | 153 | "{Intel, LPT}," |
154 | "{Intel, HPT}," | ||
154 | "{Intel, PBG}," | 155 | "{Intel, PBG}," |
155 | "{Intel, SCH}," | 156 | "{Intel, SCH}," |
156 | "{ATI, SB450}," | 157 | "{ATI, SB450}," |
@@ -535,6 +536,7 @@ enum { | |||
535 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ | 536 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ |
536 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ | 537 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ |
537 | #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ | 538 | #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ |
539 | #define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */ | ||
538 | 540 | ||
539 | /* quirks for ATI SB / AMD Hudson */ | 541 | /* quirks for ATI SB / AMD Hudson */ |
540 | #define AZX_DCAPS_PRESET_ATI_SB \ | 542 | #define AZX_DCAPS_PRESET_ATI_SB \ |
@@ -2731,6 +2733,10 @@ static int __devinit check_position_fix(struct azx *chip, int fix) | |||
2731 | snd_printd(SFX "Using LPIB position fix\n"); | 2733 | snd_printd(SFX "Using LPIB position fix\n"); |
2732 | return POS_FIX_LPIB; | 2734 | return POS_FIX_LPIB; |
2733 | } | 2735 | } |
2736 | if (chip->driver_caps & AZX_DCAPS_POSFIX_COMBO) { | ||
2737 | snd_printd(SFX "Using COMBO position fix\n"); | ||
2738 | return POS_FIX_COMBO; | ||
2739 | } | ||
2734 | return POS_FIX_AUTO; | 2740 | return POS_FIX_AUTO; |
2735 | } | 2741 | } |
2736 | 2742 | ||
@@ -3243,7 +3249,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
3243 | /* CPT */ | 3249 | /* CPT */ |
3244 | { PCI_DEVICE(0x8086, 0x1c20), | 3250 | { PCI_DEVICE(0x8086, 0x1c20), |
3245 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3251 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
3246 | AZX_DCAPS_BUFSIZE }, | 3252 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
3247 | /* PBG */ | 3253 | /* PBG */ |
3248 | { PCI_DEVICE(0x8086, 0x1d20), | 3254 | { PCI_DEVICE(0x8086, 0x1d20), |
3249 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3255 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
@@ -3251,11 +3257,15 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
3251 | /* Panther Point */ | 3257 | /* Panther Point */ |
3252 | { PCI_DEVICE(0x8086, 0x1e20), | 3258 | { PCI_DEVICE(0x8086, 0x1e20), |
3253 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3259 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
3254 | AZX_DCAPS_BUFSIZE}, | 3260 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
3255 | /* Lynx Point */ | 3261 | /* Lynx Point */ |
3256 | { PCI_DEVICE(0x8086, 0x8c20), | 3262 | { PCI_DEVICE(0x8086, 0x8c20), |
3257 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3263 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
3258 | AZX_DCAPS_BUFSIZE}, | 3264 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
3265 | /* Haswell */ | ||
3266 | { PCI_DEVICE(0x8086, 0x0c0c), | ||
3267 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | ||
3268 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, | ||
3259 | /* SCH */ | 3269 | /* SCH */ |
3260 | { PCI_DEVICE(0x8086, 0x811b), | 3270 | { PCI_DEVICE(0x8086, 0x811b), |
3261 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | 3271 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | |
@@ -3341,6 +3351,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
3341 | /* VIA VT8251/VT8237A */ | 3351 | /* VIA VT8251/VT8237A */ |
3342 | { PCI_DEVICE(0x1106, 0x3288), | 3352 | { PCI_DEVICE(0x1106, 0x3288), |
3343 | .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, | 3353 | .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, |
3354 | /* VIA GFX VT7122/VX900 */ | ||
3355 | { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC }, | ||
3356 | /* VIA GFX VT6122/VX11 */ | ||
3357 | { PCI_DEVICE(0x1106, 0x9140), .driver_data = AZX_DRIVER_GENERIC }, | ||
3344 | /* SIS966 */ | 3358 | /* SIS966 */ |
3345 | { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, | 3359 | { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, |
3346 | /* ULI M5461 */ | 3360 | /* ULI M5461 */ |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index 2dd1c113a4c1..aaccc0236bda 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c | |||
@@ -127,10 +127,15 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec) | |||
127 | static void jack_detect_update(struct hda_codec *codec, | 127 | static void jack_detect_update(struct hda_codec *codec, |
128 | struct hda_jack_tbl *jack) | 128 | struct hda_jack_tbl *jack) |
129 | { | 129 | { |
130 | if (jack->jack_dirty || !jack->jack_detect) { | 130 | if (!jack->jack_dirty) |
131 | return; | ||
132 | |||
133 | if (jack->phantom_jack) | ||
134 | jack->pin_sense = AC_PINSENSE_PRESENCE; | ||
135 | else | ||
131 | jack->pin_sense = read_pin_sense(codec, jack->nid); | 136 | jack->pin_sense = read_pin_sense(codec, jack->nid); |
132 | jack->jack_dirty = 0; | 137 | |
133 | } | 138 | jack->jack_dirty = 0; |
134 | } | 139 | } |
135 | 140 | ||
136 | /** | 141 | /** |
@@ -264,8 +269,8 @@ static void hda_free_jack_priv(struct snd_jack *jack) | |||
264 | * This assigns a jack-detection kctl to the given pin. The kcontrol | 269 | * This assigns a jack-detection kctl to the given pin. The kcontrol |
265 | * will have the given name and index. | 270 | * will have the given name and index. |
266 | */ | 271 | */ |
267 | int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | 272 | static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, |
268 | const char *name, int idx) | 273 | const char *name, int idx, bool phantom_jack) |
269 | { | 274 | { |
270 | struct hda_jack_tbl *jack; | 275 | struct hda_jack_tbl *jack; |
271 | struct snd_kcontrol *kctl; | 276 | struct snd_kcontrol *kctl; |
@@ -283,47 +288,81 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | |||
283 | if (err < 0) | 288 | if (err < 0) |
284 | return err; | 289 | return err; |
285 | jack->kctl = kctl; | 290 | jack->kctl = kctl; |
291 | jack->phantom_jack = !!phantom_jack; | ||
292 | |||
286 | state = snd_hda_jack_detect(codec, nid); | 293 | state = snd_hda_jack_detect(codec, nid); |
287 | snd_kctl_jack_report(codec->bus->card, kctl, state); | 294 | snd_kctl_jack_report(codec->bus->card, kctl, state); |
288 | #ifdef CONFIG_SND_HDA_INPUT_JACK | 295 | #ifdef CONFIG_SND_HDA_INPUT_JACK |
289 | jack->type = get_input_jack_type(codec, nid); | 296 | if (!phantom_jack) { |
290 | err = snd_jack_new(codec->bus->card, name, jack->type, &jack->jack); | 297 | jack->type = get_input_jack_type(codec, nid); |
291 | if (err < 0) | 298 | err = snd_jack_new(codec->bus->card, name, jack->type, |
292 | return err; | 299 | &jack->jack); |
293 | jack->jack->private_data = jack; | 300 | if (err < 0) |
294 | jack->jack->private_free = hda_free_jack_priv; | 301 | return err; |
295 | snd_jack_report(jack->jack, state ? jack->type : 0); | 302 | jack->jack->private_data = jack; |
303 | jack->jack->private_free = hda_free_jack_priv; | ||
304 | snd_jack_report(jack->jack, state ? jack->type : 0); | ||
305 | } | ||
296 | #endif | 306 | #endif |
297 | return 0; | 307 | return 0; |
298 | } | 308 | } |
309 | |||
310 | int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | ||
311 | const char *name, int idx) | ||
312 | { | ||
313 | return __snd_hda_jack_add_kctl(codec, nid, name, idx, false); | ||
314 | } | ||
299 | EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); | 315 | EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); |
300 | 316 | ||
317 | /* get the unique index number for the given kctl name */ | ||
318 | static int get_unique_index(struct hda_codec *codec, const char *name, int idx) | ||
319 | { | ||
320 | struct hda_jack_tbl *jack; | ||
321 | int i, len = strlen(name); | ||
322 | again: | ||
323 | jack = codec->jacktbl.list; | ||
324 | for (i = 0; i < codec->jacktbl.used; i++, jack++) { | ||
325 | /* jack->kctl.id contains "XXX Jack" name string with index */ | ||
326 | if (jack->kctl && | ||
327 | !strncmp(name, jack->kctl->id.name, len) && | ||
328 | !strcmp(" Jack", jack->kctl->id.name + len) && | ||
329 | jack->kctl->id.index == idx) { | ||
330 | idx++; | ||
331 | goto again; | ||
332 | } | ||
333 | } | ||
334 | return idx; | ||
335 | } | ||
336 | |||
301 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, | 337 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, |
302 | const struct auto_pin_cfg *cfg, | 338 | const struct auto_pin_cfg *cfg) |
303 | char *lastname, int *lastidx) | ||
304 | { | 339 | { |
305 | unsigned int def_conf, conn; | 340 | unsigned int def_conf, conn; |
306 | char name[44]; | 341 | char name[44]; |
307 | int idx, err; | 342 | int idx, err; |
343 | bool phantom_jack; | ||
308 | 344 | ||
309 | if (!nid) | 345 | if (!nid) |
310 | return 0; | 346 | return 0; |
311 | if (!is_jack_detectable(codec, nid)) | ||
312 | return 0; | ||
313 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | 347 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
314 | conn = get_defcfg_connect(def_conf); | 348 | conn = get_defcfg_connect(def_conf); |
315 | if (conn != AC_JACK_PORT_COMPLEX) | 349 | if (conn == AC_JACK_PORT_NONE) |
316 | return 0; | 350 | return 0; |
351 | phantom_jack = (conn != AC_JACK_PORT_COMPLEX) || | ||
352 | !is_jack_detectable(codec, nid); | ||
317 | 353 | ||
318 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); | 354 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); |
319 | if (!strcmp(name, lastname) && idx == *lastidx) | 355 | if (phantom_jack) |
320 | idx++; | 356 | /* Example final name: "Internal Mic Phantom Jack" */ |
321 | strncpy(lastname, name, 44); | 357 | strncat(name, " Phantom", sizeof(name) - strlen(name) - 1); |
322 | *lastidx = idx; | 358 | idx = get_unique_index(codec, name, idx); |
323 | err = snd_hda_jack_add_kctl(codec, nid, name, idx); | 359 | err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack); |
324 | if (err < 0) | 360 | if (err < 0) |
325 | return err; | 361 | return err; |
326 | return snd_hda_jack_detect_enable(codec, nid, 0); | 362 | |
363 | if (!phantom_jack) | ||
364 | return snd_hda_jack_detect_enable(codec, nid, 0); | ||
365 | return 0; | ||
327 | } | 366 | } |
328 | 367 | ||
329 | /** | 368 | /** |
@@ -333,42 +372,41 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, | |||
333 | const struct auto_pin_cfg *cfg) | 372 | const struct auto_pin_cfg *cfg) |
334 | { | 373 | { |
335 | const hda_nid_t *p; | 374 | const hda_nid_t *p; |
336 | int i, err, lastidx = 0; | 375 | int i, err; |
337 | char lastname[44] = ""; | ||
338 | 376 | ||
339 | for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { | 377 | for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { |
340 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); | 378 | err = add_jack_kctl(codec, *p, cfg); |
341 | if (err < 0) | 379 | if (err < 0) |
342 | return err; | 380 | return err; |
343 | } | 381 | } |
344 | for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { | 382 | for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { |
345 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 383 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
346 | break; | 384 | break; |
347 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); | 385 | err = add_jack_kctl(codec, *p, cfg); |
348 | if (err < 0) | 386 | if (err < 0) |
349 | return err; | 387 | return err; |
350 | } | 388 | } |
351 | for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { | 389 | for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { |
352 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 390 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
353 | break; | 391 | break; |
354 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); | 392 | err = add_jack_kctl(codec, *p, cfg); |
355 | if (err < 0) | 393 | if (err < 0) |
356 | return err; | 394 | return err; |
357 | } | 395 | } |
358 | for (i = 0; i < cfg->num_inputs; i++) { | 396 | for (i = 0; i < cfg->num_inputs; i++) { |
359 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx); | 397 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg); |
360 | if (err < 0) | 398 | if (err < 0) |
361 | return err; | 399 | return err; |
362 | } | 400 | } |
363 | for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { | 401 | for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { |
364 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); | 402 | err = add_jack_kctl(codec, *p, cfg); |
365 | if (err < 0) | 403 | if (err < 0) |
366 | return err; | 404 | return err; |
367 | } | 405 | } |
368 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx); | 406 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg); |
369 | if (err < 0) | 407 | if (err < 0) |
370 | return err; | 408 | return err; |
371 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx); | 409 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg); |
372 | if (err < 0) | 410 | if (err < 0) |
373 | return err; | 411 | return err; |
374 | return 0; | 412 | return 0; |
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h index 8ae52465ec5d..a9803da633c0 100644 --- a/sound/pci/hda/hda_jack.h +++ b/sound/pci/hda/hda_jack.h | |||
@@ -23,6 +23,7 @@ struct hda_jack_tbl { | |||
23 | unsigned int pin_sense; /* cached pin-sense value */ | 23 | unsigned int pin_sense; /* cached pin-sense value */ |
24 | unsigned int jack_detect:1; /* capable of jack-detection? */ | 24 | unsigned int jack_detect:1; /* capable of jack-detection? */ |
25 | unsigned int jack_dirty:1; /* needs to update? */ | 25 | unsigned int jack_dirty:1; /* needs to update? */ |
26 | unsigned int phantom_jack:1; /* a fixed, always present port? */ | ||
26 | struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */ | 27 | struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */ |
27 | #ifdef CONFIG_SND_HDA_INPUT_JACK | 28 | #ifdef CONFIG_SND_HDA_INPUT_JACK |
28 | int type; | 29 | int type; |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 9a096a8e0fc5..1b4c12941baa 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -89,7 +89,7 @@ | |||
89 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 89 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
90 | .subdevice = HDA_SUBDEV_AMP_FLAG, \ | 90 | .subdevice = HDA_SUBDEV_AMP_FLAG, \ |
91 | .info = snd_hda_mixer_amp_switch_info, \ | 91 | .info = snd_hda_mixer_amp_switch_info, \ |
92 | .get = snd_hda_mixer_amp_switch_get, \ | 92 | .get = snd_hda_mixer_amp_switch_get_beep, \ |
93 | .put = snd_hda_mixer_amp_switch_put_beep, \ | 93 | .put = snd_hda_mixer_amp_switch_put_beep, \ |
94 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } | 94 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } |
95 | #else | 95 | #else |
@@ -121,6 +121,8 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, | |||
121 | int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, | 121 | int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, |
122 | struct snd_ctl_elem_value *ucontrol); | 122 | struct snd_ctl_elem_value *ucontrol); |
123 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 123 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
124 | int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, | ||
125 | struct snd_ctl_elem_value *ucontrol); | ||
124 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, | 126 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, |
125 | struct snd_ctl_elem_value *ucontrol); | 127 | struct snd_ctl_elem_value *ucontrol); |
126 | #endif | 128 | #endif |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index e59e2f059b6e..7e46258fc700 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -426,10 +426,10 @@ static void print_digital_conv(struct snd_info_buffer *buffer, | |||
426 | 426 | ||
427 | static const char *get_pwr_state(u32 state) | 427 | static const char *get_pwr_state(u32 state) |
428 | { | 428 | { |
429 | static const char * const buf[4] = { | 429 | static const char * const buf[] = { |
430 | "D0", "D1", "D2", "D3" | 430 | "D0", "D1", "D2", "D3", "D3cold" |
431 | }; | 431 | }; |
432 | if (state < 4) | 432 | if (state < ARRAY_SIZE(buf)) |
433 | return buf[state]; | 433 | return buf[state]; |
434 | return "UNKNOWN"; | 434 | return "UNKNOWN"; |
435 | } | 435 | } |
@@ -451,14 +451,21 @@ static void print_power_state(struct snd_info_buffer *buffer, | |||
451 | int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE); | 451 | int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE); |
452 | int pwr = snd_hda_codec_read(codec, nid, 0, | 452 | int pwr = snd_hda_codec_read(codec, nid, 0, |
453 | AC_VERB_GET_POWER_STATE, 0); | 453 | AC_VERB_GET_POWER_STATE, 0); |
454 | if (sup) | 454 | if (sup != -1) |
455 | snd_iprintf(buffer, " Power states: %s\n", | 455 | snd_iprintf(buffer, " Power states: %s\n", |
456 | bits_names(sup, names, ARRAY_SIZE(names))); | 456 | bits_names(sup, names, ARRAY_SIZE(names))); |
457 | 457 | ||
458 | snd_iprintf(buffer, " Power: setting=%s, actual=%s\n", | 458 | snd_iprintf(buffer, " Power: setting=%s, actual=%s", |
459 | get_pwr_state(pwr & AC_PWRST_SETTING), | 459 | get_pwr_state(pwr & AC_PWRST_SETTING), |
460 | get_pwr_state((pwr & AC_PWRST_ACTUAL) >> | 460 | get_pwr_state((pwr & AC_PWRST_ACTUAL) >> |
461 | AC_PWRST_ACTUAL_SHIFT)); | 461 | AC_PWRST_ACTUAL_SHIFT)); |
462 | if (pwr & AC_PWRST_ERROR) | ||
463 | snd_iprintf(buffer, ", Error"); | ||
464 | if (pwr & AC_PWRST_CLK_STOP_OK) | ||
465 | snd_iprintf(buffer, ", Clock-stop-OK"); | ||
466 | if (pwr & AC_PWRST_SETTING_RESET) | ||
467 | snd_iprintf(buffer, ", Setting-reset"); | ||
468 | snd_iprintf(buffer, "\n"); | ||
462 | } | 469 | } |
463 | 470 | ||
464 | static void print_unsol_cap(struct snd_info_buffer *buffer, | 471 | static void print_unsol_cap(struct snd_info_buffer *buffer, |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index ad319d4dc32f..0b4a1ea147c6 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -85,7 +85,7 @@ struct hdmi_spec { | |||
85 | * Non-generic ATI/NVIDIA specific | 85 | * Non-generic ATI/NVIDIA specific |
86 | */ | 86 | */ |
87 | struct hda_multi_out multiout; | 87 | struct hda_multi_out multiout; |
88 | const struct hda_pcm_stream *pcm_playback; | 88 | struct hda_pcm_stream pcm_playback; |
89 | }; | 89 | }; |
90 | 90 | ||
91 | 91 | ||
@@ -787,7 +787,7 @@ static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) | |||
787 | int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); | 787 | int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); |
788 | 788 | ||
789 | printk(KERN_INFO | 789 | printk(KERN_INFO |
790 | "HDMI CP event: CODEC=%d PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", | 790 | "HDMI CP event: CODEC=%d TAG=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", |
791 | codec->addr, | 791 | codec->addr, |
792 | tag, | 792 | tag, |
793 | subtag, | 793 | subtag, |
@@ -1277,23 +1277,34 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) | |||
1277 | return 0; | 1277 | return 0; |
1278 | } | 1278 | } |
1279 | 1279 | ||
1280 | static int generic_hdmi_init(struct hda_codec *codec) | 1280 | static int generic_hdmi_init_per_pins(struct hda_codec *codec) |
1281 | { | 1281 | { |
1282 | struct hdmi_spec *spec = codec->spec; | 1282 | struct hdmi_spec *spec = codec->spec; |
1283 | int pin_idx; | 1283 | int pin_idx; |
1284 | 1284 | ||
1285 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 1285 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
1286 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1286 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; |
1287 | hda_nid_t pin_nid = per_pin->pin_nid; | ||
1288 | struct hdmi_eld *eld = &per_pin->sink_eld; | 1287 | struct hdmi_eld *eld = &per_pin->sink_eld; |
1289 | 1288 | ||
1290 | hdmi_init_pin(codec, pin_nid); | ||
1291 | snd_hda_jack_detect_enable(codec, pin_nid, pin_nid); | ||
1292 | |||
1293 | per_pin->codec = codec; | 1289 | per_pin->codec = codec; |
1294 | INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); | 1290 | INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); |
1295 | snd_hda_eld_proc_new(codec, eld, pin_idx); | 1291 | snd_hda_eld_proc_new(codec, eld, pin_idx); |
1296 | } | 1292 | } |
1293 | return 0; | ||
1294 | } | ||
1295 | |||
1296 | static int generic_hdmi_init(struct hda_codec *codec) | ||
1297 | { | ||
1298 | struct hdmi_spec *spec = codec->spec; | ||
1299 | int pin_idx; | ||
1300 | |||
1301 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | ||
1302 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | ||
1303 | hda_nid_t pin_nid = per_pin->pin_nid; | ||
1304 | |||
1305 | hdmi_init_pin(codec, pin_nid); | ||
1306 | snd_hda_jack_detect_enable(codec, pin_nid, pin_nid); | ||
1307 | } | ||
1297 | snd_hda_jack_report_sync(codec); | 1308 | snd_hda_jack_report_sync(codec); |
1298 | return 0; | 1309 | return 0; |
1299 | } | 1310 | } |
@@ -1338,6 +1349,7 @@ static int patch_generic_hdmi(struct hda_codec *codec) | |||
1338 | return -EINVAL; | 1349 | return -EINVAL; |
1339 | } | 1350 | } |
1340 | codec->patch_ops = generic_hdmi_patch_ops; | 1351 | codec->patch_ops = generic_hdmi_patch_ops; |
1352 | generic_hdmi_init_per_pins(codec); | ||
1341 | 1353 | ||
1342 | init_channel_allocations(); | 1354 | init_channel_allocations(); |
1343 | 1355 | ||
@@ -1352,45 +1364,65 @@ static int simple_playback_build_pcms(struct hda_codec *codec) | |||
1352 | { | 1364 | { |
1353 | struct hdmi_spec *spec = codec->spec; | 1365 | struct hdmi_spec *spec = codec->spec; |
1354 | struct hda_pcm *info = spec->pcm_rec; | 1366 | struct hda_pcm *info = spec->pcm_rec; |
1355 | int i; | 1367 | unsigned int chans; |
1368 | struct hda_pcm_stream *pstr; | ||
1356 | 1369 | ||
1357 | codec->num_pcms = spec->num_cvts; | 1370 | codec->num_pcms = 1; |
1358 | codec->pcm_info = info; | 1371 | codec->pcm_info = info; |
1359 | 1372 | ||
1360 | for (i = 0; i < codec->num_pcms; i++, info++) { | 1373 | chans = get_wcaps(codec, spec->cvts[0].cvt_nid); |
1361 | unsigned int chans; | 1374 | chans = get_wcaps_channels(chans); |
1362 | struct hda_pcm_stream *pstr; | ||
1363 | |||
1364 | chans = get_wcaps(codec, spec->cvts[i].cvt_nid); | ||
1365 | chans = get_wcaps_channels(chans); | ||
1366 | 1375 | ||
1367 | info->name = get_hdmi_pcm_name(i); | 1376 | info->name = get_hdmi_pcm_name(0); |
1368 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 1377 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
1369 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; | 1378 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; |
1370 | snd_BUG_ON(!spec->pcm_playback); | 1379 | *pstr = spec->pcm_playback; |
1371 | *pstr = *spec->pcm_playback; | 1380 | pstr->nid = spec->cvts[0].cvt_nid; |
1372 | pstr->nid = spec->cvts[i].cvt_nid; | 1381 | if (pstr->channels_max <= 2 && chans && chans <= 16) |
1373 | if (pstr->channels_max <= 2 && chans && chans <= 16) | 1382 | pstr->channels_max = chans; |
1374 | pstr->channels_max = chans; | ||
1375 | } | ||
1376 | 1383 | ||
1377 | return 0; | 1384 | return 0; |
1378 | } | 1385 | } |
1379 | 1386 | ||
1387 | /* unsolicited event for jack sensing */ | ||
1388 | static void simple_hdmi_unsol_event(struct hda_codec *codec, | ||
1389 | unsigned int res) | ||
1390 | { | ||
1391 | snd_hda_jack_set_dirty_all(codec); | ||
1392 | snd_hda_jack_report_sync(codec); | ||
1393 | } | ||
1394 | |||
1395 | /* generic_hdmi_build_jack can be used for simple_hdmi, too, | ||
1396 | * as long as spec->pins[] is set correctly | ||
1397 | */ | ||
1398 | #define simple_hdmi_build_jack generic_hdmi_build_jack | ||
1399 | |||
1380 | static int simple_playback_build_controls(struct hda_codec *codec) | 1400 | static int simple_playback_build_controls(struct hda_codec *codec) |
1381 | { | 1401 | { |
1382 | struct hdmi_spec *spec = codec->spec; | 1402 | struct hdmi_spec *spec = codec->spec; |
1383 | int err; | 1403 | int err; |
1384 | int i; | ||
1385 | 1404 | ||
1386 | for (i = 0; i < codec->num_pcms; i++) { | 1405 | err = snd_hda_create_spdif_out_ctls(codec, |
1387 | err = snd_hda_create_spdif_out_ctls(codec, | 1406 | spec->cvts[0].cvt_nid, |
1388 | spec->cvts[i].cvt_nid, | 1407 | spec->cvts[0].cvt_nid); |
1389 | spec->cvts[i].cvt_nid); | 1408 | if (err < 0) |
1390 | if (err < 0) | 1409 | return err; |
1391 | return err; | 1410 | return simple_hdmi_build_jack(codec, 0); |
1392 | } | 1411 | } |
1393 | 1412 | ||
1413 | static int simple_playback_init(struct hda_codec *codec) | ||
1414 | { | ||
1415 | struct hdmi_spec *spec = codec->spec; | ||
1416 | hda_nid_t pin = spec->pins[0].pin_nid; | ||
1417 | |||
1418 | snd_hda_codec_write(codec, pin, 0, | ||
1419 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
1420 | /* some codecs require to unmute the pin */ | ||
1421 | if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) | ||
1422 | snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1423 | AMP_OUT_UNMUTE); | ||
1424 | snd_hda_jack_detect_enable(codec, pin, pin); | ||
1425 | snd_hda_jack_report_sync(codec); | ||
1394 | return 0; | 1426 | return 0; |
1395 | } | 1427 | } |
1396 | 1428 | ||
@@ -1418,7 +1450,15 @@ static const hda_nid_t nvhdmi_con_nids_7x[4] = { | |||
1418 | 0x6, 0x8, 0xa, 0xc, | 1450 | 0x6, 0x8, 0xa, 0xc, |
1419 | }; | 1451 | }; |
1420 | 1452 | ||
1421 | static const struct hda_verb nvhdmi_basic_init_7x[] = { | 1453 | static const struct hda_verb nvhdmi_basic_init_7x_2ch[] = { |
1454 | /* set audio protect on */ | ||
1455 | { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, | ||
1456 | /* enable digital output on pin widget */ | ||
1457 | { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, | ||
1458 | {} /* terminator */ | ||
1459 | }; | ||
1460 | |||
1461 | static const struct hda_verb nvhdmi_basic_init_7x_8ch[] = { | ||
1422 | /* set audio protect on */ | 1462 | /* set audio protect on */ |
1423 | { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, | 1463 | { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, |
1424 | /* enable digital output on pin widget */ | 1464 | /* enable digital output on pin widget */ |
@@ -1446,9 +1486,15 @@ static const struct hda_verb nvhdmi_basic_init_7x[] = { | |||
1446 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) | 1486 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) |
1447 | #endif | 1487 | #endif |
1448 | 1488 | ||
1449 | static int nvhdmi_7x_init(struct hda_codec *codec) | 1489 | static int nvhdmi_7x_init_2ch(struct hda_codec *codec) |
1450 | { | 1490 | { |
1451 | snd_hda_sequence_write(codec, nvhdmi_basic_init_7x); | 1491 | snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_2ch); |
1492 | return 0; | ||
1493 | } | ||
1494 | |||
1495 | static int nvhdmi_7x_init_8ch(struct hda_codec *codec) | ||
1496 | { | ||
1497 | snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_8ch); | ||
1452 | return 0; | 1498 | return 0; |
1453 | } | 1499 | } |
1454 | 1500 | ||
@@ -1524,6 +1570,50 @@ static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1524 | stream_tag, format, substream); | 1570 | stream_tag, format, substream); |
1525 | } | 1571 | } |
1526 | 1572 | ||
1573 | static const struct hda_pcm_stream simple_pcm_playback = { | ||
1574 | .substreams = 1, | ||
1575 | .channels_min = 2, | ||
1576 | .channels_max = 2, | ||
1577 | .ops = { | ||
1578 | .open = simple_playback_pcm_open, | ||
1579 | .close = simple_playback_pcm_close, | ||
1580 | .prepare = simple_playback_pcm_prepare | ||
1581 | }, | ||
1582 | }; | ||
1583 | |||
1584 | static const struct hda_codec_ops simple_hdmi_patch_ops = { | ||
1585 | .build_controls = simple_playback_build_controls, | ||
1586 | .build_pcms = simple_playback_build_pcms, | ||
1587 | .init = simple_playback_init, | ||
1588 | .free = simple_playback_free, | ||
1589 | .unsol_event = simple_hdmi_unsol_event, | ||
1590 | }; | ||
1591 | |||
1592 | static int patch_simple_hdmi(struct hda_codec *codec, | ||
1593 | hda_nid_t cvt_nid, hda_nid_t pin_nid) | ||
1594 | { | ||
1595 | struct hdmi_spec *spec; | ||
1596 | |||
1597 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
1598 | if (!spec) | ||
1599 | return -ENOMEM; | ||
1600 | |||
1601 | codec->spec = spec; | ||
1602 | |||
1603 | spec->multiout.num_dacs = 0; /* no analog */ | ||
1604 | spec->multiout.max_channels = 2; | ||
1605 | spec->multiout.dig_out_nid = cvt_nid; | ||
1606 | spec->num_cvts = 1; | ||
1607 | spec->num_pins = 1; | ||
1608 | spec->cvts[0].cvt_nid = cvt_nid; | ||
1609 | spec->pins[0].pin_nid = pin_nid; | ||
1610 | spec->pcm_playback = simple_pcm_playback; | ||
1611 | |||
1612 | codec->patch_ops = simple_hdmi_patch_ops; | ||
1613 | |||
1614 | return 0; | ||
1615 | } | ||
1616 | |||
1527 | static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec, | 1617 | static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec, |
1528 | int channels) | 1618 | int channels) |
1529 | { | 1619 | { |
@@ -1696,54 +1786,20 @@ static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = { | |||
1696 | }, | 1786 | }, |
1697 | }; | 1787 | }; |
1698 | 1788 | ||
1699 | static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = { | ||
1700 | .substreams = 1, | ||
1701 | .channels_min = 2, | ||
1702 | .channels_max = 2, | ||
1703 | .nid = nvhdmi_master_con_nid_7x, | ||
1704 | .rates = SUPPORTED_RATES, | ||
1705 | .maxbps = SUPPORTED_MAXBPS, | ||
1706 | .formats = SUPPORTED_FORMATS, | ||
1707 | .ops = { | ||
1708 | .open = simple_playback_pcm_open, | ||
1709 | .close = simple_playback_pcm_close, | ||
1710 | .prepare = simple_playback_pcm_prepare | ||
1711 | }, | ||
1712 | }; | ||
1713 | |||
1714 | static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = { | ||
1715 | .build_controls = simple_playback_build_controls, | ||
1716 | .build_pcms = simple_playback_build_pcms, | ||
1717 | .init = nvhdmi_7x_init, | ||
1718 | .free = simple_playback_free, | ||
1719 | }; | ||
1720 | |||
1721 | static const struct hda_codec_ops nvhdmi_patch_ops_2ch = { | ||
1722 | .build_controls = simple_playback_build_controls, | ||
1723 | .build_pcms = simple_playback_build_pcms, | ||
1724 | .init = nvhdmi_7x_init, | ||
1725 | .free = simple_playback_free, | ||
1726 | }; | ||
1727 | |||
1728 | static int patch_nvhdmi_2ch(struct hda_codec *codec) | 1789 | static int patch_nvhdmi_2ch(struct hda_codec *codec) |
1729 | { | 1790 | { |
1730 | struct hdmi_spec *spec; | 1791 | struct hdmi_spec *spec; |
1792 | int err = patch_simple_hdmi(codec, nvhdmi_master_con_nid_7x, | ||
1793 | nvhdmi_master_pin_nid_7x); | ||
1794 | if (err < 0) | ||
1795 | return err; | ||
1731 | 1796 | ||
1732 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 1797 | codec->patch_ops.init = nvhdmi_7x_init_2ch; |
1733 | if (spec == NULL) | 1798 | /* override the PCM rates, etc, as the codec doesn't give full list */ |
1734 | return -ENOMEM; | 1799 | spec = codec->spec; |
1735 | 1800 | spec->pcm_playback.rates = SUPPORTED_RATES; | |
1736 | codec->spec = spec; | 1801 | spec->pcm_playback.maxbps = SUPPORTED_MAXBPS; |
1737 | 1802 | spec->pcm_playback.formats = SUPPORTED_FORMATS; | |
1738 | spec->multiout.num_dacs = 0; /* no analog */ | ||
1739 | spec->multiout.max_channels = 2; | ||
1740 | spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; | ||
1741 | spec->num_cvts = 1; | ||
1742 | spec->cvts[0].cvt_nid = nvhdmi_master_con_nid_7x; | ||
1743 | spec->pcm_playback = &nvhdmi_pcm_playback_2ch; | ||
1744 | |||
1745 | codec->patch_ops = nvhdmi_patch_ops_2ch; | ||
1746 | |||
1747 | return 0; | 1803 | return 0; |
1748 | } | 1804 | } |
1749 | 1805 | ||
@@ -1751,13 +1807,12 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) | |||
1751 | { | 1807 | { |
1752 | struct hdmi_spec *spec; | 1808 | struct hdmi_spec *spec; |
1753 | int err = patch_nvhdmi_2ch(codec); | 1809 | int err = patch_nvhdmi_2ch(codec); |
1754 | |||
1755 | if (err < 0) | 1810 | if (err < 0) |
1756 | return err; | 1811 | return err; |
1757 | spec = codec->spec; | 1812 | spec = codec->spec; |
1758 | spec->multiout.max_channels = 8; | 1813 | spec->multiout.max_channels = 8; |
1759 | spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x; | 1814 | spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x; |
1760 | codec->patch_ops = nvhdmi_patch_ops_8ch_7x; | 1815 | codec->patch_ops.init = nvhdmi_7x_init_8ch; |
1761 | 1816 | ||
1762 | /* Initialize the audio infoframe channel mask and checksum to something | 1817 | /* Initialize the audio infoframe channel mask and checksum to something |
1763 | * valid */ | 1818 | * valid */ |
@@ -1801,69 +1856,26 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1801 | return 0; | 1856 | return 0; |
1802 | } | 1857 | } |
1803 | 1858 | ||
1804 | static const struct hda_pcm_stream atihdmi_pcm_digital_playback = { | 1859 | static int patch_atihdmi(struct hda_codec *codec) |
1805 | .substreams = 1, | ||
1806 | .channels_min = 2, | ||
1807 | .channels_max = 2, | ||
1808 | .nid = ATIHDMI_CVT_NID, | ||
1809 | .ops = { | ||
1810 | .open = simple_playback_pcm_open, | ||
1811 | .close = simple_playback_pcm_close, | ||
1812 | .prepare = atihdmi_playback_pcm_prepare | ||
1813 | }, | ||
1814 | }; | ||
1815 | |||
1816 | static const struct hda_verb atihdmi_basic_init[] = { | ||
1817 | /* enable digital output on pin widget */ | ||
1818 | { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
1819 | {} /* terminator */ | ||
1820 | }; | ||
1821 | |||
1822 | static int atihdmi_init(struct hda_codec *codec) | ||
1823 | { | 1860 | { |
1824 | struct hdmi_spec *spec = codec->spec; | 1861 | struct hdmi_spec *spec; |
1825 | 1862 | int err = patch_simple_hdmi(codec, ATIHDMI_CVT_NID, ATIHDMI_PIN_NID); | |
1826 | snd_hda_sequence_write(codec, atihdmi_basic_init); | 1863 | if (err < 0) |
1827 | /* SI codec requires to unmute the pin */ | 1864 | return err; |
1828 | if (get_wcaps(codec, spec->pins[0].pin_nid) & AC_WCAP_OUT_AMP) | 1865 | spec = codec->spec; |
1829 | snd_hda_codec_write(codec, spec->pins[0].pin_nid, 0, | 1866 | spec->pcm_playback.ops.prepare = atihdmi_playback_pcm_prepare; |
1830 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
1831 | AMP_OUT_UNMUTE); | ||
1832 | return 0; | 1867 | return 0; |
1833 | } | 1868 | } |
1834 | 1869 | ||
1835 | static const struct hda_codec_ops atihdmi_patch_ops = { | 1870 | /* VIA HDMI Implementation */ |
1836 | .build_controls = simple_playback_build_controls, | 1871 | #define VIAHDMI_CVT_NID 0x02 /* audio converter1 */ |
1837 | .build_pcms = simple_playback_build_pcms, | 1872 | #define VIAHDMI_PIN_NID 0x03 /* HDMI output pin1 */ |
1838 | .init = atihdmi_init, | ||
1839 | .free = simple_playback_free, | ||
1840 | }; | ||
1841 | |||
1842 | 1873 | ||
1843 | static int patch_atihdmi(struct hda_codec *codec) | 1874 | static int patch_via_hdmi(struct hda_codec *codec) |
1844 | { | 1875 | { |
1845 | struct hdmi_spec *spec; | 1876 | return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID); |
1846 | |||
1847 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
1848 | if (spec == NULL) | ||
1849 | return -ENOMEM; | ||
1850 | |||
1851 | codec->spec = spec; | ||
1852 | |||
1853 | spec->multiout.num_dacs = 0; /* no analog */ | ||
1854 | spec->multiout.max_channels = 2; | ||
1855 | spec->multiout.dig_out_nid = ATIHDMI_CVT_NID; | ||
1856 | spec->num_cvts = 1; | ||
1857 | spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID; | ||
1858 | spec->pins[0].pin_nid = ATIHDMI_PIN_NID; | ||
1859 | spec->pcm_playback = &atihdmi_pcm_digital_playback; | ||
1860 | |||
1861 | codec->patch_ops = atihdmi_patch_ops; | ||
1862 | |||
1863 | return 0; | ||
1864 | } | 1877 | } |
1865 | 1878 | ||
1866 | |||
1867 | /* | 1879 | /* |
1868 | * patch entries | 1880 | * patch entries |
1869 | */ | 1881 | */ |
@@ -1902,8 +1914,13 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { | |||
1902 | { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, | 1914 | { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, |
1903 | { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi }, | 1915 | { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi }, |
1904 | { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, | 1916 | { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, |
1917 | { .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_generic_hdmi }, | ||
1905 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, | 1918 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, |
1906 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, | 1919 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, |
1920 | { .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, | ||
1921 | { .id = 0x11069f81, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, | ||
1922 | { .id = 0x11069f84, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi }, | ||
1923 | { .id = 0x11069f85, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi }, | ||
1907 | { .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, | 1924 | { .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, |
1908 | { .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi }, | 1925 | { .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi }, |
1909 | { .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi }, | 1926 | { .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi }, |
@@ -1911,6 +1928,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { | |||
1911 | { .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, | 1928 | { .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, |
1912 | { .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, | 1929 | { .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, |
1913 | { .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, | 1930 | { .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, |
1931 | { .id = 0x80862807, .name = "Haswell HDMI", .patch = patch_generic_hdmi }, | ||
1914 | { .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi }, | 1932 | { .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi }, |
1915 | { .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, | 1933 | { .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, |
1916 | {} /* terminator */ | 1934 | {} /* terminator */ |
@@ -1948,8 +1966,13 @@ MODULE_ALIAS("snd-hda-codec-id:10de0041"); | |||
1948 | MODULE_ALIAS("snd-hda-codec-id:10de0042"); | 1966 | MODULE_ALIAS("snd-hda-codec-id:10de0042"); |
1949 | MODULE_ALIAS("snd-hda-codec-id:10de0043"); | 1967 | MODULE_ALIAS("snd-hda-codec-id:10de0043"); |
1950 | MODULE_ALIAS("snd-hda-codec-id:10de0044"); | 1968 | MODULE_ALIAS("snd-hda-codec-id:10de0044"); |
1969 | MODULE_ALIAS("snd-hda-codec-id:10de0051"); | ||
1951 | MODULE_ALIAS("snd-hda-codec-id:10de0067"); | 1970 | MODULE_ALIAS("snd-hda-codec-id:10de0067"); |
1952 | MODULE_ALIAS("snd-hda-codec-id:10de8001"); | 1971 | MODULE_ALIAS("snd-hda-codec-id:10de8001"); |
1972 | MODULE_ALIAS("snd-hda-codec-id:11069f80"); | ||
1973 | MODULE_ALIAS("snd-hda-codec-id:11069f81"); | ||
1974 | MODULE_ALIAS("snd-hda-codec-id:11069f84"); | ||
1975 | MODULE_ALIAS("snd-hda-codec-id:11069f85"); | ||
1953 | MODULE_ALIAS("snd-hda-codec-id:17e80047"); | 1976 | MODULE_ALIAS("snd-hda-codec-id:17e80047"); |
1954 | MODULE_ALIAS("snd-hda-codec-id:80860054"); | 1977 | MODULE_ALIAS("snd-hda-codec-id:80860054"); |
1955 | MODULE_ALIAS("snd-hda-codec-id:80862801"); | 1978 | MODULE_ALIAS("snd-hda-codec-id:80862801"); |
@@ -1958,6 +1981,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862803"); | |||
1958 | MODULE_ALIAS("snd-hda-codec-id:80862804"); | 1981 | MODULE_ALIAS("snd-hda-codec-id:80862804"); |
1959 | MODULE_ALIAS("snd-hda-codec-id:80862805"); | 1982 | MODULE_ALIAS("snd-hda-codec-id:80862805"); |
1960 | MODULE_ALIAS("snd-hda-codec-id:80862806"); | 1983 | MODULE_ALIAS("snd-hda-codec-id:80862806"); |
1984 | MODULE_ALIAS("snd-hda-codec-id:80862807"); | ||
1961 | MODULE_ALIAS("snd-hda-codec-id:80862880"); | 1985 | MODULE_ALIAS("snd-hda-codec-id:80862880"); |
1962 | MODULE_ALIAS("snd-hda-codec-id:808629fb"); | 1986 | MODULE_ALIAS("snd-hda-codec-id:808629fb"); |
1963 | 1987 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index aa4c25e0f327..ec14224021aa 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -170,10 +170,10 @@ struct alc_spec { | |||
170 | hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; | 170 | hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; |
171 | unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; | 171 | unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; |
172 | int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */ | 172 | int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */ |
173 | hda_nid_t inv_dmic_pin; | ||
173 | 174 | ||
174 | /* hooks */ | 175 | /* hooks */ |
175 | void (*init_hook)(struct hda_codec *codec); | 176 | void (*init_hook)(struct hda_codec *codec); |
176 | void (*unsol_event)(struct hda_codec *codec, unsigned int res); | ||
177 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 177 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
178 | void (*power_hook)(struct hda_codec *codec); | 178 | void (*power_hook)(struct hda_codec *codec); |
179 | #endif | 179 | #endif |
@@ -201,6 +201,8 @@ struct alc_spec { | |||
201 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ | 201 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ |
202 | unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ | 202 | unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ |
203 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ | 203 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ |
204 | unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */ | ||
205 | unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */ | ||
204 | 206 | ||
205 | /* auto-mute control */ | 207 | /* auto-mute control */ |
206 | int automute_mode; | 208 | int automute_mode; |
@@ -298,6 +300,39 @@ static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) | |||
298 | } | 300 | } |
299 | 301 | ||
300 | static void call_update_outputs(struct hda_codec *codec); | 302 | static void call_update_outputs(struct hda_codec *codec); |
303 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force); | ||
304 | |||
305 | /* for shared I/O, change the pin-control accordingly */ | ||
306 | static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic) | ||
307 | { | ||
308 | struct alc_spec *spec = codec->spec; | ||
309 | unsigned int val; | ||
310 | hda_nid_t pin = spec->autocfg.inputs[1].pin; | ||
311 | /* NOTE: this assumes that there are only two inputs, the | ||
312 | * first is the real internal mic and the second is HP/mic jack. | ||
313 | */ | ||
314 | |||
315 | val = snd_hda_get_default_vref(codec, pin); | ||
316 | |||
317 | /* This pin does not have vref caps - let's enable vref on pin 0x18 | ||
318 | instead, as suggested by Realtek */ | ||
319 | if (val == AC_PINCTL_VREF_HIZ) { | ||
320 | const hda_nid_t vref_pin = 0x18; | ||
321 | /* Sanity check pin 0x18 */ | ||
322 | if (get_wcaps_type(get_wcaps(codec, vref_pin)) == AC_WID_PIN && | ||
323 | get_defcfg_connect(snd_hda_codec_get_pincfg(codec, vref_pin)) == AC_JACK_PORT_NONE) { | ||
324 | unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin); | ||
325 | if (vref_val != AC_PINCTL_VREF_HIZ) | ||
326 | snd_hda_set_pin_ctl(codec, vref_pin, PIN_IN | (set_as_mic ? vref_val : 0)); | ||
327 | } | ||
328 | } | ||
329 | |||
330 | val = set_as_mic ? val | PIN_IN : PIN_HP; | ||
331 | snd_hda_set_pin_ctl(codec, pin, val); | ||
332 | |||
333 | spec->automute_speaker = !set_as_mic; | ||
334 | call_update_outputs(codec); | ||
335 | } | ||
301 | 336 | ||
302 | /* select the given imux item; either unmute exclusively or select the route */ | 337 | /* select the given imux item; either unmute exclusively or select the route */ |
303 | static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | 338 | static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, |
@@ -325,21 +360,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
325 | return 0; | 360 | return 0; |
326 | spec->cur_mux[adc_idx] = idx; | 361 | spec->cur_mux[adc_idx] = idx; |
327 | 362 | ||
328 | /* for shared I/O, change the pin-control accordingly */ | 363 | if (spec->shared_mic_hp) |
329 | if (spec->shared_mic_hp) { | 364 | update_shared_mic_hp(codec, spec->cur_mux[adc_idx]); |
330 | unsigned int val; | ||
331 | hda_nid_t pin = spec->autocfg.inputs[1].pin; | ||
332 | /* NOTE: this assumes that there are only two inputs, the | ||
333 | * first is the real internal mic and the second is HP jack. | ||
334 | */ | ||
335 | if (spec->cur_mux[adc_idx]) | ||
336 | val = snd_hda_get_default_vref(codec, pin) | PIN_IN; | ||
337 | else | ||
338 | val = PIN_HP; | ||
339 | snd_hda_set_pin_ctl(codec, pin, val); | ||
340 | spec->automute_speaker = !spec->cur_mux[adc_idx]; | ||
341 | call_update_outputs(codec); | ||
342 | } | ||
343 | 365 | ||
344 | if (spec->dyn_adc_switch) { | 366 | if (spec->dyn_adc_switch) { |
345 | alc_dyn_adc_pcm_resetup(codec, idx); | 367 | alc_dyn_adc_pcm_resetup(codec, idx); |
@@ -368,6 +390,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
368 | AC_VERB_SET_CONNECT_SEL, | 390 | AC_VERB_SET_CONNECT_SEL, |
369 | imux->items[idx].index); | 391 | imux->items[idx].index); |
370 | } | 392 | } |
393 | alc_inv_dmic_sync(codec, true); | ||
371 | return 1; | 394 | return 1; |
372 | } | 395 | } |
373 | 396 | ||
@@ -664,7 +687,7 @@ static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid) | |||
664 | } | 687 | } |
665 | 688 | ||
666 | /* unsolicited event for HP jack sensing */ | 689 | /* unsolicited event for HP jack sensing */ |
667 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | 690 | static void alc_unsol_event(struct hda_codec *codec, unsigned int res) |
668 | { | 691 | { |
669 | int action; | 692 | int action; |
670 | 693 | ||
@@ -1000,11 +1023,9 @@ static void alc_init_automute(struct hda_codec *codec) | |||
1000 | spec->automute_lo = spec->automute_lo_possible; | 1023 | spec->automute_lo = spec->automute_lo_possible; |
1001 | spec->automute_speaker = spec->automute_speaker_possible; | 1024 | spec->automute_speaker = spec->automute_speaker_possible; |
1002 | 1025 | ||
1003 | if (spec->automute_speaker_possible || spec->automute_lo_possible) { | 1026 | if (spec->automute_speaker_possible || spec->automute_lo_possible) |
1004 | /* create a control for automute mode */ | 1027 | /* create a control for automute mode */ |
1005 | alc_add_automute_mode_enum(codec); | 1028 | alc_add_automute_mode_enum(codec); |
1006 | spec->unsol_event = alc_sku_unsol_event; | ||
1007 | } | ||
1008 | } | 1029 | } |
1009 | 1030 | ||
1010 | /* return the position of NID in the list, or -1 if not found */ | 1031 | /* return the position of NID in the list, or -1 if not found */ |
@@ -1167,7 +1188,6 @@ static void alc_init_auto_mic(struct hda_codec *codec) | |||
1167 | 1188 | ||
1168 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", | 1189 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", |
1169 | ext, fixed, dock); | 1190 | ext, fixed, dock); |
1170 | spec->unsol_event = alc_sku_unsol_event; | ||
1171 | } | 1191 | } |
1172 | 1192 | ||
1173 | /* check the availabilities of auto-mute and auto-mic switches */ | 1193 | /* check the availabilities of auto-mute and auto-mic switches */ |
@@ -1556,14 +1576,14 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, | |||
1556 | 1576 | ||
1557 | static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, | 1577 | static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, |
1558 | struct snd_ctl_elem_value *ucontrol, | 1578 | struct snd_ctl_elem_value *ucontrol, |
1559 | getput_call_t func, bool check_adc_switch) | 1579 | getput_call_t func, bool is_put) |
1560 | { | 1580 | { |
1561 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1581 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1562 | struct alc_spec *spec = codec->spec; | 1582 | struct alc_spec *spec = codec->spec; |
1563 | int i, err = 0; | 1583 | int i, err = 0; |
1564 | 1584 | ||
1565 | mutex_lock(&codec->control_mutex); | 1585 | mutex_lock(&codec->control_mutex); |
1566 | if (check_adc_switch && spec->dyn_adc_switch) { | 1586 | if (is_put && spec->dyn_adc_switch) { |
1567 | for (i = 0; i < spec->num_adc_nids; i++) { | 1587 | for (i = 0; i < spec->num_adc_nids; i++) { |
1568 | kcontrol->private_value = | 1588 | kcontrol->private_value = |
1569 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], | 1589 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], |
@@ -1584,6 +1604,8 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, | |||
1584 | 3, 0, HDA_INPUT); | 1604 | 3, 0, HDA_INPUT); |
1585 | err = func(kcontrol, ucontrol); | 1605 | err = func(kcontrol, ucontrol); |
1586 | } | 1606 | } |
1607 | if (err >= 0 && is_put) | ||
1608 | alc_inv_dmic_sync(codec, false); | ||
1587 | error: | 1609 | error: |
1588 | mutex_unlock(&codec->control_mutex); | 1610 | mutex_unlock(&codec->control_mutex); |
1589 | return err; | 1611 | return err; |
@@ -1676,6 +1698,116 @@ DEFINE_CAPMIX_NOSRC(2); | |||
1676 | DEFINE_CAPMIX_NOSRC(3); | 1698 | DEFINE_CAPMIX_NOSRC(3); |
1677 | 1699 | ||
1678 | /* | 1700 | /* |
1701 | * Inverted digital-mic handling | ||
1702 | * | ||
1703 | * First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch" | ||
1704 | * gives the additional mute only to the right channel of the digital mic | ||
1705 | * capture stream. This is a workaround for avoiding the almost silence | ||
1706 | * by summing the stereo stream from some (known to be ForteMedia) | ||
1707 | * digital mic unit. | ||
1708 | * | ||
1709 | * The logic is to call alc_inv_dmic_sync() after each action (possibly) | ||
1710 | * modifying ADC amp. When the mute flag is set, it mutes the R-channel | ||
1711 | * without caching so that the cache can still keep the original value. | ||
1712 | * The cached value is then restored when the flag is set off or any other | ||
1713 | * than d-mic is used as the current input source. | ||
1714 | */ | ||
1715 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) | ||
1716 | { | ||
1717 | struct alc_spec *spec = codec->spec; | ||
1718 | int i; | ||
1719 | |||
1720 | if (!spec->inv_dmic_fixup) | ||
1721 | return; | ||
1722 | if (!spec->inv_dmic_muted && !force) | ||
1723 | return; | ||
1724 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
1725 | int src = spec->dyn_adc_switch ? 0 : i; | ||
1726 | bool dmic_fixup = false; | ||
1727 | hda_nid_t nid; | ||
1728 | int parm, dir, v; | ||
1729 | |||
1730 | if (spec->inv_dmic_muted && | ||
1731 | spec->imux_pins[spec->cur_mux[src]] == spec->inv_dmic_pin) | ||
1732 | dmic_fixup = true; | ||
1733 | if (!dmic_fixup && !force) | ||
1734 | continue; | ||
1735 | if (spec->vol_in_capsrc) { | ||
1736 | nid = spec->capsrc_nids[i]; | ||
1737 | parm = AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT; | ||
1738 | dir = HDA_OUTPUT; | ||
1739 | } else { | ||
1740 | nid = spec->adc_nids[i]; | ||
1741 | parm = AC_AMP_SET_RIGHT | AC_AMP_SET_INPUT; | ||
1742 | dir = HDA_INPUT; | ||
1743 | } | ||
1744 | /* we care only right channel */ | ||
1745 | v = snd_hda_codec_amp_read(codec, nid, 1, dir, 0); | ||
1746 | if (v & 0x80) /* if already muted, we don't need to touch */ | ||
1747 | continue; | ||
1748 | if (dmic_fixup) /* add mute for d-mic */ | ||
1749 | v |= 0x80; | ||
1750 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1751 | parm | v); | ||
1752 | } | ||
1753 | } | ||
1754 | |||
1755 | static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol, | ||
1756 | struct snd_ctl_elem_value *ucontrol) | ||
1757 | { | ||
1758 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1759 | struct alc_spec *spec = codec->spec; | ||
1760 | |||
1761 | ucontrol->value.integer.value[0] = !spec->inv_dmic_muted; | ||
1762 | return 0; | ||
1763 | } | ||
1764 | |||
1765 | static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol, | ||
1766 | struct snd_ctl_elem_value *ucontrol) | ||
1767 | { | ||
1768 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1769 | struct alc_spec *spec = codec->spec; | ||
1770 | unsigned int val = !ucontrol->value.integer.value[0]; | ||
1771 | |||
1772 | if (val == spec->inv_dmic_muted) | ||
1773 | return 0; | ||
1774 | spec->inv_dmic_muted = val; | ||
1775 | alc_inv_dmic_sync(codec, true); | ||
1776 | return 0; | ||
1777 | } | ||
1778 | |||
1779 | static const struct snd_kcontrol_new alc_inv_dmic_sw = { | ||
1780 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1781 | .info = snd_ctl_boolean_mono_info, | ||
1782 | .get = alc_inv_dmic_sw_get, | ||
1783 | .put = alc_inv_dmic_sw_put, | ||
1784 | }; | ||
1785 | |||
1786 | static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid) | ||
1787 | { | ||
1788 | struct alc_spec *spec = codec->spec; | ||
1789 | struct snd_kcontrol_new *knew = alc_kcontrol_new(spec); | ||
1790 | if (!knew) | ||
1791 | return -ENOMEM; | ||
1792 | *knew = alc_inv_dmic_sw; | ||
1793 | knew->name = kstrdup("Inverted Internal Mic Capture Switch", GFP_KERNEL); | ||
1794 | if (!knew->name) | ||
1795 | return -ENOMEM; | ||
1796 | spec->inv_dmic_fixup = 1; | ||
1797 | spec->inv_dmic_muted = 0; | ||
1798 | spec->inv_dmic_pin = nid; | ||
1799 | return 0; | ||
1800 | } | ||
1801 | |||
1802 | /* typically the digital mic is put at node 0x12 */ | ||
1803 | static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec, | ||
1804 | const struct alc_fixup *fix, int action) | ||
1805 | { | ||
1806 | if (action == ALC_FIXUP_ACT_PROBE) | ||
1807 | alc_add_inv_dmic_mixer(codec, 0x12); | ||
1808 | } | ||
1809 | |||
1810 | /* | ||
1679 | * virtual master controls | 1811 | * virtual master controls |
1680 | */ | 1812 | */ |
1681 | 1813 | ||
@@ -1865,13 +1997,31 @@ static int __alc_build_controls(struct hda_codec *codec) | |||
1865 | return 0; | 1997 | return 0; |
1866 | } | 1998 | } |
1867 | 1999 | ||
1868 | static int alc_build_controls(struct hda_codec *codec) | 2000 | static int alc_build_jacks(struct hda_codec *codec) |
1869 | { | 2001 | { |
1870 | struct alc_spec *spec = codec->spec; | 2002 | struct alc_spec *spec = codec->spec; |
2003 | |||
2004 | if (spec->shared_mic_hp) { | ||
2005 | int err; | ||
2006 | int nid = spec->autocfg.inputs[1].pin; | ||
2007 | err = snd_hda_jack_add_kctl(codec, nid, "Headphone Mic", 0); | ||
2008 | if (err < 0) | ||
2009 | return err; | ||
2010 | err = snd_hda_jack_detect_enable(codec, nid, 0); | ||
2011 | if (err < 0) | ||
2012 | return err; | ||
2013 | } | ||
2014 | |||
2015 | return snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
2016 | } | ||
2017 | |||
2018 | static int alc_build_controls(struct hda_codec *codec) | ||
2019 | { | ||
1871 | int err = __alc_build_controls(codec); | 2020 | int err = __alc_build_controls(codec); |
1872 | if (err < 0) | 2021 | if (err < 0) |
1873 | return err; | 2022 | return err; |
1874 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | 2023 | |
2024 | err = alc_build_jacks(codec); | ||
1875 | if (err < 0) | 2025 | if (err < 0) |
1876 | return err; | 2026 | return err; |
1877 | alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD); | 2027 | alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD); |
@@ -1908,14 +2058,6 @@ static int alc_init(struct hda_codec *codec) | |||
1908 | return 0; | 2058 | return 0; |
1909 | } | 2059 | } |
1910 | 2060 | ||
1911 | static void alc_unsol_event(struct hda_codec *codec, unsigned int res) | ||
1912 | { | ||
1913 | struct alc_spec *spec = codec->spec; | ||
1914 | |||
1915 | if (spec->unsol_event) | ||
1916 | spec->unsol_event(codec, res); | ||
1917 | } | ||
1918 | |||
1919 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2061 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
1920 | static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) | 2062 | static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) |
1921 | { | 2063 | { |
@@ -2317,6 +2459,7 @@ static int alc_resume(struct hda_codec *codec) | |||
2317 | codec->patch_ops.init(codec); | 2459 | codec->patch_ops.init(codec); |
2318 | snd_hda_codec_resume_amp(codec); | 2460 | snd_hda_codec_resume_amp(codec); |
2319 | snd_hda_codec_resume_cache(codec); | 2461 | snd_hda_codec_resume_cache(codec); |
2462 | alc_inv_dmic_sync(codec, true); | ||
2320 | hda_call_check_power_status(codec, 0x01); | 2463 | hda_call_check_power_status(codec, 0x01); |
2321 | return 0; | 2464 | return 0; |
2322 | } | 2465 | } |
@@ -4116,14 +4259,12 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
4116 | */ | 4259 | */ |
4117 | static void alc_auto_init_std(struct hda_codec *codec) | 4260 | static void alc_auto_init_std(struct hda_codec *codec) |
4118 | { | 4261 | { |
4119 | struct alc_spec *spec = codec->spec; | ||
4120 | alc_auto_init_multi_out(codec); | 4262 | alc_auto_init_multi_out(codec); |
4121 | alc_auto_init_extra_out(codec); | 4263 | alc_auto_init_extra_out(codec); |
4122 | alc_auto_init_analog_input(codec); | 4264 | alc_auto_init_analog_input(codec); |
4123 | alc_auto_init_input_src(codec); | 4265 | alc_auto_init_input_src(codec); |
4124 | alc_auto_init_digital(codec); | 4266 | alc_auto_init_digital(codec); |
4125 | if (spec->unsol_event) | 4267 | alc_inithook(codec); |
4126 | alc_inithook(codec); | ||
4127 | } | 4268 | } |
4128 | 4269 | ||
4129 | /* | 4270 | /* |
@@ -4724,7 +4865,6 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, | |||
4724 | spec->automute_speaker = 1; | 4865 | spec->automute_speaker = 1; |
4725 | spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ | 4866 | spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ |
4726 | snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT); | 4867 | snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT); |
4727 | spec->unsol_event = alc_sku_unsol_event; | ||
4728 | snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs); | 4868 | snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs); |
4729 | } | 4869 | } |
4730 | } | 4870 | } |
@@ -4909,6 +5049,7 @@ enum { | |||
4909 | ALC889_FIXUP_DAC_ROUTE, | 5049 | ALC889_FIXUP_DAC_ROUTE, |
4910 | ALC889_FIXUP_MBP_VREF, | 5050 | ALC889_FIXUP_MBP_VREF, |
4911 | ALC889_FIXUP_IMAC91_VREF, | 5051 | ALC889_FIXUP_IMAC91_VREF, |
5052 | ALC882_FIXUP_INV_DMIC, | ||
4912 | }; | 5053 | }; |
4913 | 5054 | ||
4914 | static void alc889_fixup_coef(struct hda_codec *codec, | 5055 | static void alc889_fixup_coef(struct hda_codec *codec, |
@@ -5212,6 +5353,10 @@ static const struct alc_fixup alc882_fixups[] = { | |||
5212 | .chained = true, | 5353 | .chained = true, |
5213 | .chain_id = ALC882_FIXUP_GPIO1, | 5354 | .chain_id = ALC882_FIXUP_GPIO1, |
5214 | }, | 5355 | }, |
5356 | [ALC882_FIXUP_INV_DMIC] = { | ||
5357 | .type = ALC_FIXUP_FUNC, | ||
5358 | .v.func = alc_fixup_inv_dmic_0x12, | ||
5359 | }, | ||
5215 | }; | 5360 | }; |
5216 | 5361 | ||
5217 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { | 5362 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { |
@@ -5286,6 +5431,7 @@ static const struct alc_model_fixup alc882_fixup_models[] = { | |||
5286 | {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, | 5431 | {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, |
5287 | {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, | 5432 | {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, |
5288 | {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, | 5433 | {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, |
5434 | {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"}, | ||
5289 | {} | 5435 | {} |
5290 | }; | 5436 | }; |
5291 | 5437 | ||
@@ -5373,6 +5519,7 @@ enum { | |||
5373 | ALC262_FIXUP_LENOVO_3000, | 5519 | ALC262_FIXUP_LENOVO_3000, |
5374 | ALC262_FIXUP_BENQ, | 5520 | ALC262_FIXUP_BENQ, |
5375 | ALC262_FIXUP_BENQ_T31, | 5521 | ALC262_FIXUP_BENQ_T31, |
5522 | ALC262_FIXUP_INV_DMIC, | ||
5376 | }; | 5523 | }; |
5377 | 5524 | ||
5378 | static const struct alc_fixup alc262_fixups[] = { | 5525 | static const struct alc_fixup alc262_fixups[] = { |
@@ -5424,6 +5571,10 @@ static const struct alc_fixup alc262_fixups[] = { | |||
5424 | {} | 5571 | {} |
5425 | } | 5572 | } |
5426 | }, | 5573 | }, |
5574 | [ALC262_FIXUP_INV_DMIC] = { | ||
5575 | .type = ALC_FIXUP_FUNC, | ||
5576 | .v.func = alc_fixup_inv_dmic_0x12, | ||
5577 | }, | ||
5427 | }; | 5578 | }; |
5428 | 5579 | ||
5429 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { | 5580 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { |
@@ -5438,6 +5589,10 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { | |||
5438 | {} | 5589 | {} |
5439 | }; | 5590 | }; |
5440 | 5591 | ||
5592 | static const struct alc_model_fixup alc262_fixup_models[] = { | ||
5593 | {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, | ||
5594 | {} | ||
5595 | }; | ||
5441 | 5596 | ||
5442 | /* | 5597 | /* |
5443 | */ | 5598 | */ |
@@ -5466,7 +5621,8 @@ static int patch_alc262(struct hda_codec *codec) | |||
5466 | #endif | 5621 | #endif |
5467 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | 5622 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); |
5468 | 5623 | ||
5469 | alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); | 5624 | alc_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, |
5625 | alc262_fixups); | ||
5470 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | 5626 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
5471 | 5627 | ||
5472 | alc_auto_parse_customize_define(codec); | 5628 | alc_auto_parse_customize_define(codec); |
@@ -5522,6 +5678,22 @@ static const struct hda_verb alc268_beep_init_verbs[] = { | |||
5522 | { } | 5678 | { } |
5523 | }; | 5679 | }; |
5524 | 5680 | ||
5681 | enum { | ||
5682 | ALC268_FIXUP_INV_DMIC, | ||
5683 | }; | ||
5684 | |||
5685 | static const struct alc_fixup alc268_fixups[] = { | ||
5686 | [ALC268_FIXUP_INV_DMIC] = { | ||
5687 | .type = ALC_FIXUP_FUNC, | ||
5688 | .v.func = alc_fixup_inv_dmic_0x12, | ||
5689 | }, | ||
5690 | }; | ||
5691 | |||
5692 | static const struct alc_model_fixup alc268_fixup_models[] = { | ||
5693 | {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, | ||
5694 | {} | ||
5695 | }; | ||
5696 | |||
5525 | /* | 5697 | /* |
5526 | * BIOS auto configuration | 5698 | * BIOS auto configuration |
5527 | */ | 5699 | */ |
@@ -5553,6 +5725,9 @@ static int patch_alc268(struct hda_codec *codec) | |||
5553 | 5725 | ||
5554 | spec = codec->spec; | 5726 | spec = codec->spec; |
5555 | 5727 | ||
5728 | alc_pick_fixup(codec, alc268_fixup_models, NULL, alc268_fixups); | ||
5729 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | ||
5730 | |||
5556 | /* automatic parse from the BIOS config */ | 5731 | /* automatic parse from the BIOS config */ |
5557 | err = alc268_parse_auto_config(codec); | 5732 | err = alc268_parse_auto_config(codec); |
5558 | if (err < 0) | 5733 | if (err < 0) |
@@ -5582,6 +5757,8 @@ static int patch_alc268(struct hda_codec *codec) | |||
5582 | codec->patch_ops = alc_patch_ops; | 5757 | codec->patch_ops = alc_patch_ops; |
5583 | spec->shutup = alc_eapd_shutup; | 5758 | spec->shutup = alc_eapd_shutup; |
5584 | 5759 | ||
5760 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | ||
5761 | |||
5585 | return 0; | 5762 | return 0; |
5586 | 5763 | ||
5587 | error: | 5764 | error: |
@@ -5810,6 +5987,7 @@ static void alc269_fixup_mic2_mute(struct hda_codec *codec, | |||
5810 | } | 5987 | } |
5811 | } | 5988 | } |
5812 | 5989 | ||
5990 | |||
5813 | enum { | 5991 | enum { |
5814 | ALC269_FIXUP_SONY_VAIO, | 5992 | ALC269_FIXUP_SONY_VAIO, |
5815 | ALC275_FIXUP_SONY_VAIO_GPIO2, | 5993 | ALC275_FIXUP_SONY_VAIO_GPIO2, |
@@ -5828,6 +6006,7 @@ enum { | |||
5828 | ALC269VB_FIXUP_AMIC, | 6006 | ALC269VB_FIXUP_AMIC, |
5829 | ALC269VB_FIXUP_DMIC, | 6007 | ALC269VB_FIXUP_DMIC, |
5830 | ALC269_FIXUP_MIC2_MUTE_LED, | 6008 | ALC269_FIXUP_MIC2_MUTE_LED, |
6009 | ALC269_FIXUP_INV_DMIC, | ||
5831 | }; | 6010 | }; |
5832 | 6011 | ||
5833 | static const struct alc_fixup alc269_fixups[] = { | 6012 | static const struct alc_fixup alc269_fixups[] = { |
@@ -5952,12 +6131,19 @@ static const struct alc_fixup alc269_fixups[] = { | |||
5952 | .type = ALC_FIXUP_FUNC, | 6131 | .type = ALC_FIXUP_FUNC, |
5953 | .v.func = alc269_fixup_mic2_mute, | 6132 | .v.func = alc269_fixup_mic2_mute, |
5954 | }, | 6133 | }, |
6134 | [ALC269_FIXUP_INV_DMIC] = { | ||
6135 | .type = ALC_FIXUP_FUNC, | ||
6136 | .v.func = alc_fixup_inv_dmic_0x12, | ||
6137 | }, | ||
5955 | }; | 6138 | }; |
5956 | 6139 | ||
5957 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 6140 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
6141 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), | ||
6142 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), | ||
5958 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), | 6143 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), |
5959 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), | 6144 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), |
5960 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | 6145 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
6146 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), | ||
5961 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), | 6147 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), |
5962 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), | 6148 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), |
5963 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), | 6149 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), |
@@ -6033,6 +6219,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
6033 | static const struct alc_model_fixup alc269_fixup_models[] = { | 6219 | static const struct alc_model_fixup alc269_fixup_models[] = { |
6034 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, | 6220 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, |
6035 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, | 6221 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, |
6222 | {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, | ||
6223 | {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, | ||
6224 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, | ||
6036 | {} | 6225 | {} |
6037 | }; | 6226 | }; |
6038 | 6227 | ||
@@ -6329,12 +6518,6 @@ static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { | |||
6329 | {} | 6518 | {} |
6330 | }; | 6519 | }; |
6331 | 6520 | ||
6332 | static const struct hda_verb alc660vd_eapd_verbs[] = { | ||
6333 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
6334 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
6335 | { } | ||
6336 | }; | ||
6337 | |||
6338 | /* | 6521 | /* |
6339 | */ | 6522 | */ |
6340 | static int patch_alc861vd(struct hda_codec *codec) | 6523 | static int patch_alc861vd(struct hda_codec *codec) |
@@ -6356,11 +6539,6 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
6356 | if (err < 0) | 6539 | if (err < 0) |
6357 | goto error; | 6540 | goto error; |
6358 | 6541 | ||
6359 | if (codec->vendor_id == 0x10ec0660) { | ||
6360 | /* always turn on EAPD */ | ||
6361 | snd_hda_gen_add_verbs(&spec->gen, alc660vd_eapd_verbs); | ||
6362 | } | ||
6363 | |||
6364 | if (!spec->no_analog) { | 6542 | if (!spec->no_analog) { |
6365 | err = snd_hda_attach_beep_device(codec, 0x23); | 6543 | err = snd_hda_attach_beep_device(codec, 0x23); |
6366 | if (err < 0) | 6544 | if (err < 0) |
@@ -6443,6 +6621,7 @@ enum { | |||
6443 | ALC662_FIXUP_ASUS_MODE8, | 6621 | ALC662_FIXUP_ASUS_MODE8, |
6444 | ALC662_FIXUP_NO_JACK_DETECT, | 6622 | ALC662_FIXUP_NO_JACK_DETECT, |
6445 | ALC662_FIXUP_ZOTAC_Z68, | 6623 | ALC662_FIXUP_ZOTAC_Z68, |
6624 | ALC662_FIXUP_INV_DMIC, | ||
6446 | }; | 6625 | }; |
6447 | 6626 | ||
6448 | static const struct alc_fixup alc662_fixups[] = { | 6627 | static const struct alc_fixup alc662_fixups[] = { |
@@ -6599,12 +6778,17 @@ static const struct alc_fixup alc662_fixups[] = { | |||
6599 | { } | 6778 | { } |
6600 | } | 6779 | } |
6601 | }, | 6780 | }, |
6781 | [ALC662_FIXUP_INV_DMIC] = { | ||
6782 | .type = ALC_FIXUP_FUNC, | ||
6783 | .v.func = alc_fixup_inv_dmic_0x12, | ||
6784 | }, | ||
6602 | }; | 6785 | }; |
6603 | 6786 | ||
6604 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { | 6787 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
6605 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), | 6788 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), |
6606 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), | 6789 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), |
6607 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), | 6790 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), |
6791 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), | ||
6608 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 6792 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
6609 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), | 6793 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
6610 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), | 6794 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), |
@@ -6685,6 +6869,7 @@ static const struct alc_model_fixup alc662_fixup_models[] = { | |||
6685 | {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, | 6869 | {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, |
6686 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, | 6870 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, |
6687 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, | 6871 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, |
6872 | {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, | ||
6688 | {} | 6873 | {} |
6689 | }; | 6874 | }; |
6690 | 6875 | ||
@@ -6831,6 +7016,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
6831 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, | 7016 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, |
6832 | { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, | 7017 | { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, |
6833 | { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, | 7018 | { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, |
7019 | { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, | ||
6834 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | 7020 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
6835 | .patch = patch_alc861 }, | 7021 | .patch = patch_alc861 }, |
6836 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, | 7022 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, |